From 888c7beb8ddf04b14053de4d24c881b4a98ff49e Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Mon, 4 Sep 2023 15:35:55 -0400 Subject: [PATCH 01/19] Initial setup --- .eslintrc.cjs | 13 + .eslintrc.json | 18 - docs/demo/demo.js | 2 - package-lock.json | 1680 +++++----------------------------------- package.json | 11 +- src/formatters/html.js | 5 +- tsconfig.json | 20 + 7 files changed, 252 insertions(+), 1497 deletions(-) create mode 100644 .eslintrc.cjs delete mode 100644 .eslintrc.json create mode 100644 tsconfig.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 00000000..c72acffc --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,13 @@ +module.exports = { + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended-type-checked', + ], + plugins: ['@typescript-eslint'], + parser: '@typescript-eslint/parser', + parserOptions: { + project: true, + tsconfigRootDir: __dirname, + }, + root: true, +}; diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 747ac243..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "parser": "@babel/eslint-parser", - "extends": ["standard", "prettier"], - "rules": { - "camelcase": [2, { "properties": "always" }], - "new-cap": [2, { "newIsCap": true, "capIsNew": true }], - "arrow-body-style": [2, "as-needed"], - "prefer-arrow-callback": 0, - "prefer-template": 0, - - "no-var": 2, - "no-undef": 2, - "no-param-reassign": 2 - }, - "env": { - "node": true - } -} diff --git a/docs/demo/demo.js b/docs/demo/demo.js index 99e327ad..8409d116 100644 --- a/docs/demo/demo.js +++ b/docs/demo/demo.js @@ -227,7 +227,6 @@ } }, getJson: function (url, callback) { - /* global XMLHttpRequest */ let request = new XMLHttpRequest(); request.open('GET', url, true); request.onreadystatechange = function () { @@ -236,7 +235,6 @@ try { data = JSON.parse(this.responseText, jsondiffpatch.dateReviver); } catch (parseError) { - // eslint-disable-next-line n/no-callback-literal return callback('parse error: ' + parseError); } if (this.status >= 200 && this.status < 400) { diff --git a/package-lock.json b/package-lock.json index 5950ac10..21820ca2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,20 +17,20 @@ }, "devDependencies": { "@babel/core": "^7.22.10", - "@babel/eslint-parser": "^7.22.10", "@babel/preset-env": "^7.22.10", "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-commonjs": "^25.0.4", "@rollup/plugin-node-resolve": "^15.2.0", "@rollup/plugin-replace": "^5.0.2", + "@typescript-eslint/eslint-plugin": "^6.6.0", + "@typescript-eslint/parser": "^6.6.0", "eslint": "^8.47.0", "eslint-config-prettier": "^9.0.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-jest": "^27.2.3", "jest": "^29.6.2", "prettier": "^3.0.2", "rollup": "^3.28.0", - "rollup-plugin-visualizer": "^5.9.2" + "rollup-plugin-visualizer": "^5.9.2", + "typescript": "~5.2.2" }, "engines": { "node": ">=8.17.0" @@ -181,24 +181,6 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/eslint-parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.10.tgz", - "integrity": "sha512-0J8DNPRXQRLeR9rPaUMM3fA+RbixjnVLe/MRMYCkp3hzgsSuxCHQ8NN8xQG1wIHKJ4a1DTROTvFJdW+B5/eOsg==", - "dev": true, - "dependencies": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0", - "eslint": "^7.5.0 || ^8.0.0" - } - }, "node_modules/@babel/generator": { "version": "7.22.10", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", @@ -2572,15 +2554,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", - "dev": true, - "dependencies": { - "eslint-scope": "5.1.1" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2845,13 +2818,6 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "peer": true - }, "node_modules/@types/node": { "version": "20.5.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", @@ -2865,9 +2831,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", "dev": true }, "node_modules/@types/stack-utils": { @@ -2891,30 +2857,153 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.6.0.tgz", + "integrity": "sha512-CW9YDGTQnNYMIo5lMeuiIG08p4E0cXrXTbcZ2saT/ETE7dWUrNxlijsQeU04qAAKkILiLzdQz+cGFxCJjaZUmA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/type-utils": "6.6.0", + "@typescript-eslint/utils": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.6.0.tgz", + "integrity": "sha512-setq5aJgUwtzGrhW177/i+DMLqBaJbdwGj2CPIVFFLE0NCliy5ujIdLHd2D1ysmlmsjdL2GWW+hR85neEfc12w==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz", + "integrity": "sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz", + "integrity": "sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.6.0", + "@typescript-eslint/utils": "6.6.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.6.0.tgz", + "integrity": "sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -2922,21 +3011,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz", + "integrity": "sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/visitor-keys": "6.6.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -2982,29 +3071,28 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.6.0.tgz", + "integrity": "sha512-mPHFoNa2bPIWWglWYdR0QfY9GN0CfvvXX1Sv6DlSTive3jlMTUy+an67//Gysc+0Me9pjitrq0LJp0nGtLgftw==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.6.0", + "@typescript-eslint/types": "6.6.0", + "@typescript-eslint/typescript-estree": "6.6.0", + "semver": "^7.5.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0" } }, "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { @@ -3041,16 +3129,16 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz", + "integrity": "sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "6.6.0", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -3163,40 +3251,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -3206,98 +3260,6 @@ "node": ">=8" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz", - "integrity": "sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", - "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", - "dev": true, - "peer": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/babel-jest": { "version": "29.6.2", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.2.tgz", @@ -3531,66 +3493,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", - "dev": true, - "peer": true, - "dependencies": { - "semver": "^7.0.0" - } - }, - "node_modules/builtins/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "peer": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/builtins/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/builtins/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "peer": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3817,23 +3719,6 @@ "node": ">=8" } }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "peer": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -3914,116 +3799,19 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dev": true, - "peer": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" - }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "peer": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "peer": true, - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "peer": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { "node": ">=10" @@ -4098,282 +3886,6 @@ "eslint": ">=7.0.0" } }, - "node_modules/eslint-config-standard": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", - "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "eslint": "^8.0.1", - "eslint-plugin-import": "^2.25.2", - "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", - "eslint-plugin-promise": "^6.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "peer": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "peer": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-es-x": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.2.0.tgz", - "integrity": "sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==", - "dev": true, - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "eslint": ">=8" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", - "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", - "dev": true, - "peer": true, - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.findlastindex": "^1.2.2", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.8.0", - "has": "^1.0.3", - "is-core-module": "^2.13.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.6", - "object.groupby": "^1.0.0", - "object.values": "^1.1.6", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-jest": { - "version": "27.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.3.tgz", - "integrity": "sha512-sRLlSCpICzWuje66Gl9zvdF6mwD5X86I4u55hJyFBsxYOsBCmT5+kSUjf+fkFWVMMgpzNEupjW8WzUqi83hJAQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "^5.10.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0", - "eslint": "^7.0.0 || ^8.0.0", - "jest": "*" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-n": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.0.1.tgz", - "integrity": "sha512-CDmHegJN0OF3L5cz5tATH84RPQm9kG+Yx39wIqIwPR2C0uhBGMWfbbOtetR83PQjjidA5aXMu+LEFw1jaSwvTA==", - "dev": true, - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.1.0", - "ignore": "^5.2.4", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", - "semver": "^7.5.3" - }, - "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-n/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "peer": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-n/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "peer": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-n/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "peer": true - }, - "node_modules/eslint-plugin-promise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", - "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", - "dev": true, - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -4538,15 +4050,6 @@ "node": ">=4.0" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", @@ -4734,16 +4237,6 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "peer": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4770,35 +4263,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4817,22 +4281,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dev": true, - "peer": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -4854,23 +4302,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -4932,22 +4363,6 @@ "node": ">=4" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "peer": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -4968,19 +4383,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "peer": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -5005,16 +4407,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5023,61 +4415,6 @@ "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "peer": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "peer": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -5162,72 +4499,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, - "peer": true, - "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "peer": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-builtin-module": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", @@ -5243,19 +4520,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-core-module": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", @@ -5268,22 +4532,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "peer": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", @@ -5339,168 +4587,48 @@ } }, "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "peer": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "peer": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.12.0" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "peer": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", "dev": true, - "peer": true, "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/estree": "*" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2" + "engines": { + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-wsl": { @@ -5515,13 +4643,6 @@ "node": ">=8" } }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "peer": true - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -6697,16 +5818,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -6752,94 +5863,6 @@ "node": ">=8" } }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true, - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.0.tgz", - "integrity": "sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.21.2", - "get-intrinsic": "^1.2.1" - } - }, - "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -7247,24 +6270,6 @@ "@babel/runtime": "^7.8.4" } }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/regexpu-core": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", @@ -7487,40 +6492,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -7551,21 +6522,6 @@ "node": ">=8" } }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -7660,54 +6616,6 @@ "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -7840,61 +6748,16 @@ "node": ">=8.0" } }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "peer": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { + "node_modules/ts-api-utils": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "peer": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.2.tgz", + "integrity": "sha512-Cbu4nIqnEdd+THNEsBdkolnOXhg0I8XteoHaEKgvsxpsbWda4IsUut2c187HxywQCvveojow0Dgw/amxtSKVkQ==", "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, "engines": { - "node": ">= 6" + "node": ">=16.13.0" }, "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "typescript": ">=4.2.0" } }, "node_modules/type-check": { @@ -7930,81 +6793,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "peer": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8013,22 +6806,6 @@ "node": ">=14.17" } }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "peer": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -8146,43 +6923,6 @@ "node": ">= 8" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "peer": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "dev": true, - "peer": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index 15e727a2..793e4a72 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ }, "scripts": { "build": "rollup -c", - "lint": "eslint .", + "type-check": "tsc", + "lint": "eslint src", "test": "jest --coverage", "format": "prettier . --write", "format-check": "prettier . --check", @@ -41,20 +42,20 @@ }, "devDependencies": { "@babel/core": "^7.22.10", - "@babel/eslint-parser": "^7.22.10", "@babel/preset-env": "^7.22.10", "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-commonjs": "^25.0.4", "@rollup/plugin-node-resolve": "^15.2.0", "@rollup/plugin-replace": "^5.0.2", + "@typescript-eslint/eslint-plugin": "^6.6.0", + "@typescript-eslint/parser": "^6.6.0", "eslint": "^8.47.0", "eslint-config-prettier": "^9.0.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-jest": "^27.2.3", "jest": "^29.6.2", "prettier": "^3.0.2", "rollup": "^3.28.0", - "rollup-plugin-visualizer": "^5.9.2" + "rollup-plugin-visualizer": "^5.9.2", + "typescript": "~5.2.2" }, "license": "MIT", "engines": { diff --git a/src/formatters/html.js b/src/formatters/html.js index fb837fce..ad462028 100644 --- a/src/formatters/html.js +++ b/src/formatters/html.js @@ -24,7 +24,6 @@ class HtmlFormatter extends BaseFormatter { pieceIndex < piecesLength; pieceIndex++ ) { - /* global decodeURI */ const piece = pieces[pieceIndex]; context.out( `${htmlEscape( @@ -221,7 +220,9 @@ const adjustArrows = function jsondiffpatchHtmlFormatterAdjustArrows(nodeArg) { : `M30,${-distance} Q-10,${Math.round(-distance / 2)} 26,4`; path.setAttribute('d', curve); svg.style.display = ''; - } catch (err) {} + } catch (err) { + // continue regardless of error + } }, ); }; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..38e163be --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es2016", + // "lib": [], + "module": "node16", + "types": [], + // "resolveJsonModule": true, + // "declaration": true, + // "declarationMap": true, + // "emitDeclarationOnly": true, + // "outFile": "./", + // "outDir": "./", + "noEmit": true, + "isolatedModules": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": false + } +} From fb8cb4841a6ceea584c03813955e29e0c6692d49 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Mon, 4 Sep 2023 16:05:45 -0400 Subject: [PATCH 02/19] Convert piping classes to TS --- src/contexts/{context.js => context.ts} | 33 ++-- src/index.d.ts | 203 ------------------------ src/{pipe.js => pipe.ts} | 64 ++++---- src/{processor.js => processor.ts} | 35 ++-- src/types.ts | 1 + 5 files changed, 72 insertions(+), 264 deletions(-) rename src/contexts/{context.js => context.ts} (59%) delete mode 100644 src/index.d.ts rename src/{pipe.js => pipe.ts} (63%) rename src/{processor.js => processor.ts} (60%) create mode 100644 src/types.ts diff --git a/src/contexts/context.js b/src/contexts/context.ts similarity index 59% rename from src/contexts/context.js rename to src/contexts/context.ts index f31abd2d..774bd957 100644 --- a/src/contexts/context.js +++ b/src/contexts/context.ts @@ -1,7 +1,20 @@ -import Pipe from '../pipe'; +import type { Options } from '../types'; -export default class Context { - setResult(result) { +export default abstract class Context { + abstract pipe: string; + + result?: TResult; + hasResult?: boolean; + exiting?: boolean; + parent?: this; + childName?: string | number; + root?: this; + options?: Options; + children?: this[]; + nextAfterChildren?: this | null; + next?: this | null; + + setResult(result: TResult) { this.result = result; this.hasResult = true; return this; @@ -12,19 +25,7 @@ export default class Context { return this; } - switchTo(next, pipe) { - if (typeof next === 'string' || next instanceof Pipe) { - this.nextPipe = next; - } else { - this.next = next; - if (pipe) { - this.nextPipe = pipe; - } - } - return this; - } - - push(child, name) { + push(child: this, name?: string | number) { child.parent = this; if (typeof name !== 'undefined') { child.childName = name; diff --git a/src/index.d.ts b/src/index.d.ts deleted file mode 100644 index 715ce30d..00000000 --- a/src/index.d.ts +++ /dev/null @@ -1,203 +0,0 @@ -export interface Formatter { - format(delta: Delta, original: any): string; -} - -export interface HtmlFormatter extends Formatter { - /** - * Set whether to show or hide unchanged parts of a diff. - * @param show Whether to show unchanged parts - * @param node The root element the diff is contained within. (Default: body) - * @param delay Transition time in ms. (Default: no transition) - */ - showUnchanged(show: boolean, node?: Element | null, delay?: number): void; - - /** - * An alias for showUnchanged(false, ...) - * @param node The root element the diff is contained within (Default: body) - * @param delay Transition time in ms. (Default: no transition) - */ - hideUnchanged(node?: Element | null, delay?: number): void; -} - -export interface Delta { - [key: string]: any; - [key: number]: any; -} - -export class Context { - nested: boolean; - exiting?: boolean; - options: Config; - parent?: PatchContext; - childName?: string; - children?: PatchContext[]; - root?: PatchContext; - next?: PatchContext; - nextAfterChildren?: PatchContext; - hasResult: boolean; - setResult(result: any): Context; - exit(): Context; -} - -export class PatchContext extends Context { - pipe: 'patch'; - left: any; - delta: Delta; -} - -export class DiffContext extends Context { - pipe: 'diff'; - left: any; - right: any; -} - -export class ReverseContext extends Context { - pipe: 'reverse'; - delta: Delta; -} - -type FilterContext = PatchContext | DiffContext | ReverseContext; - -/** - * A plugin which can modify the diff(), patch() or reverse() operations - */ -export interface Filter { - /** - * A function which is called at each stage of the operation and can update the context to modify the result - * @param context The current state of the operation - */ - (context: TContext): void; - - /** - * A unique name which can be used to insert other filters before/after, or remove/replace this filter - */ - filterName: string; -} - -/** - * A collection of Filters run on each diff(), patch() or reverse() operation - */ -export class Pipe { - /** - * Append one or more filters to the existing list - */ - append(...filters: Filter[]): void; - - /** - * Prepend one or more filters to the existing list - */ - prepend(...filters: Filter[]): void; - - /** - * Add one ore more filters after the specified filter - * @param filterName The name of the filter to insert before - * @param filters Filters to be inserted - */ - after(filterName: string, ...filters: Filter[]): void; - - /** - * Add one ore more filters before the specified filter - * @param filterName The name of the filter to insert before - * @param filters Filters to be inserted - */ - before(filterName: string, ...filters: Filter[]): void; - - /** - * Replace the specified filter with one ore more filters - * @param filterName The name of the filter to replace - * @param filters Filters to be inserted - */ - replace(filterName: string, ...filters: Filter[]): void; - - /** - * Remove the filter with the specified name - * @param filterName The name of the filter to remove - */ - remove(filterName: string): void; - - /** - * Remove all filters from this pipe - */ - clear(): void; - - /** - * Return array of ordered filter names for this pipe - */ - list(): void; -} - -export class Processor { - constructor(options?: Config); - - pipes: { - patch: Pipe; - diff: Pipe; - reverse: Pipe; - }; -} - -export interface Config { - // used to match objects when diffing arrays, by default only === operator is used - objectHash?: (item: any, index: number) => string; - - arrays?: { - // default true, detect items moved inside the array (otherwise they will be registered as remove+add) - detectMove: boolean; - // default false, the value of items moved is not included in deltas - includeValueOnMove: boolean; - }; - - textDiff?: { - // default 60, minimum string length (left and right sides) to use text diff algorythm: google-diff-match-patch - minLength: number; - }; - - /** - * this optional function can be specified to ignore object properties (eg. volatile data) - * @param name property name, present in either context.left or context.right objects - * @param context the diff context (has context.left and context.right objects) - */ - /** - * - */ - propertyFilter?: (name: string, context: DiffContext) => boolean; - - /** - * default false. if true, values in the obtained delta will be cloned (using jsondiffpatch.clone by default), - * to ensure delta keeps no references to left or right objects. this becomes useful if you're diffing and patching - * the same objects multiple times without serializing deltas. - * - * instead of true, a function can be specified here to provide a custom clone(value) - */ - cloneDiffValues?: boolean | ((value: any) => any); -} - -export class DiffPatcher { - constructor(options?: Config); - - processor: Processor; - - clone: (value: any) => any; - diff: (left: any, right: any) => Delta | undefined; - patch: (left: any, delta: Delta) => any; - reverse: (delta: Delta) => Delta | undefined; - unpatch: (right: any, delta: Delta) => any; -} - -export const create: (options?: any) => DiffPatcher; - -export const formatters: { - annotated: Formatter; - console: Formatter; - html: HtmlFormatter; - jsonpatch: Formatter; -}; - -export const console: Formatter; - -export const dateReviver: (key: string, value: any) => any; - -export const diff: (left: any, right: any) => Delta | undefined; -export const patch: (left: any, delta: Delta) => any; -export const reverse: (delta: Delta) => Delta | undefined; -export const unpatch: (right: any, delta: Delta) => any; diff --git a/src/pipe.js b/src/pipe.ts similarity index 63% rename from src/pipe.js rename to src/pipe.ts index 460634c4..c77f6193 100644 --- a/src/pipe.js +++ b/src/pipe.ts @@ -1,10 +1,24 @@ -class Pipe { - constructor(name) { +import type Context from './contexts/context'; +import type Processor from './processor'; + +export interface Filter> { + (context: TContext): void; + filterName: string; +} + +class Pipe> { + name: string; + filters: Filter[]; + processor?: Processor; + debug?: boolean; + resultCheck?: ((context: TContext) => void) | null; + + constructor(name: string) { this.name = name; this.filters = []; } - process(input) { + process(input: TContext) { if (!this.processor) { throw new Error('add this pipe to a processor before using it'); } @@ -27,21 +41,21 @@ class Pipe { } } - log(msg) { + log(msg: string) { console.log(`[jsondiffpatch] ${this.name} pipe, ${msg}`); } - append(...args) { + append(...args: Filter[]) { this.filters.push(...args); return this; } - prepend(...args) { + prepend(...args: Filter[]) { this.filters.unshift(...args); return this; } - indexOf(filterName) { + indexOf(filterName: string) { if (!filterName) { throw new Error('a filter name is required'); } @@ -58,40 +72,25 @@ class Pipe { return this.filters.map((f) => f.filterName); } - after(filterName) { + after(filterName: string, ...params: Filter[]) { const index = this.indexOf(filterName); - const params = Array.prototype.slice.call(arguments, 1); - if (!params.length) { - throw new Error('a filter is required'); - } - params.unshift(index + 1, 0); - Array.prototype.splice.apply(this.filters, params); + this.filters.splice(index + 1, 0, ...params); return this; } - before(filterName) { + before(filterName: string, ...params: Filter[]) { const index = this.indexOf(filterName); - const params = Array.prototype.slice.call(arguments, 1); - if (!params.length) { - throw new Error('a filter is required'); - } - params.unshift(index, 0); - Array.prototype.splice.apply(this.filters, params); + this.filters.splice(index, 0, ...params); return this; } - replace(filterName) { + replace(filterName: string, ...params: Filter[]) { const index = this.indexOf(filterName); - const params = Array.prototype.slice.call(arguments, 1); - if (!params.length) { - throw new Error('a filter is required'); - } - params.unshift(index, 1); - Array.prototype.splice.apply(this.filters, params); + this.filters.splice(index, 1, ...params); return this; } - remove(filterName) { + remove(filterName: string) { const index = this.indexOf(filterName); this.filters.splice(index, 1); return this; @@ -102,7 +101,7 @@ class Pipe { return this; } - shouldHaveResult(should) { + shouldHaveResult(should?: boolean) { if (should === false) { this.resultCheck = null; return; @@ -110,11 +109,12 @@ class Pipe { if (this.resultCheck) { return; } - const pipe = this; this.resultCheck = (context) => { if (!context.hasResult) { console.log(context); - const error = new Error(`${pipe.name} failed`); + const error: Error & { noResult?: boolean } = new Error( + `${this.name} failed`, + ); error.noResult = true; throw error; } diff --git a/src/processor.js b/src/processor.ts similarity index 60% rename from src/processor.js rename to src/processor.ts index ccc0ae6b..21e76ebc 100644 --- a/src/processor.js +++ b/src/processor.ts @@ -1,42 +1,52 @@ +import type { Options } from './types'; +import type Pipe from './pipe'; +import type Context from './contexts/context'; + class Processor { - constructor(options) { + selfOptions: Options; + pipes: { [pipeName: string]: Pipe> }; + + constructor(options: Options) { this.selfOptions = options || {}; this.pipes = {}; } - options(options) { + options(options?: Options) { if (options) { this.selfOptions = options; } return this.selfOptions; } - pipe(name, pipeArg) { + pipe(name: string | Pipe>, pipeArg?: Pipe>) { let pipe = pipeArg; if (typeof name === 'string') { if (typeof pipe === 'undefined') { - return this.pipes[name]; + return this.pipes[name]!; } else { this.pipes[name] = pipe; } } - if (name && name.name) { - pipe = name; + if (name && (name as Pipe).name) { + pipe = name as Pipe>; if (pipe.processor === this) { return pipe; } this.pipes[pipe.name] = pipe; } - pipe.processor = this; - return pipe; + pipe!.processor = this; + return pipe!; } - process(input, pipe) { + process>( + input: TContext, + pipe?: Pipe, + ) { let context = input; context.options = this.options(); - let nextPipe = pipe || input.pipe || 'default'; + let nextPipe: Pipe | string | null = + pipe || input.pipe || 'default'; let lastPipe; - let lastContext; while (nextPipe) { if (typeof context.nextAfterChildren !== 'undefined') { // children processed and coming back to parent @@ -48,13 +58,12 @@ class Processor { nextPipe = this.pipe(nextPipe); } nextPipe.process(context); - lastContext = context; lastPipe = nextPipe; nextPipe = null; if (context) { if (context.next) { context = context.next; - nextPipe = lastContext.nextPipe || context.pipe || lastPipe; + nextPipe = context.pipe || lastPipe; } } } diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 00000000..88025b92 --- /dev/null +++ b/src/types.ts @@ -0,0 +1 @@ +export interface Options {} From 141f3476238e859367caf53f8fe8cc2a817f9a99 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Mon, 4 Sep 2023 16:14:56 -0400 Subject: [PATCH 03/19] Contexts to TS --- src/{clone.js => clone.ts} | 17 ++++------ src/contexts/{diff.js => diff.ts} | 19 +++++++---- src/contexts/patch.js | 12 ------- src/contexts/patch.ts | 17 ++++++++++ src/contexts/reverse.js | 11 ------ src/contexts/reverse.ts | 15 +++++++++ src/{date-reviver.js => date-reviver.ts} | 2 +- src/types.ts | 43 +++++++++++++++++++++++- 8 files changed, 94 insertions(+), 42 deletions(-) rename src/{clone.js => clone.ts} (60%) rename src/contexts/{diff.js => diff.ts} (50%) delete mode 100644 src/contexts/patch.js create mode 100644 src/contexts/patch.ts delete mode 100644 src/contexts/reverse.js create mode 100644 src/contexts/reverse.ts rename src/{date-reviver.js => date-reviver.ts} (89%) diff --git a/src/clone.js b/src/clone.ts similarity index 60% rename from src/clone.js rename to src/clone.ts index 3d4d5310..5e3b5ec7 100644 --- a/src/clone.js +++ b/src/clone.ts @@ -1,21 +1,16 @@ -const isArray = - typeof Array.isArray === 'function' - ? Array.isArray - : (a) => a instanceof Array; - -function cloneRegExp(re) { - const regexMatch = /^\/(.*)\/([gimyu]*)$/.exec(re.toString()); +function cloneRegExp(re: RegExp) { + const regexMatch = /^\/(.*)\/([gimyu]*)$/.exec(re.toString())!; return new RegExp(regexMatch[1], regexMatch[2]); } -export default function clone(arg) { +export default function clone(arg: unknown): unknown { if (typeof arg !== 'object') { return arg; } if (arg === null) { return null; } - if (isArray(arg)) { + if (Array.isArray(arg)) { return arg.map(clone); } if (arg instanceof Date) { @@ -27,7 +22,9 @@ export default function clone(arg) { const cloned = {}; for (const name in arg) { if (Object.prototype.hasOwnProperty.call(arg, name)) { - cloned[name] = clone(arg[name]); + (cloned as Record)[name] = clone( + (arg as Record)[name], + ); } } return cloned; diff --git a/src/contexts/diff.js b/src/contexts/diff.ts similarity index 50% rename from src/contexts/diff.js rename to src/contexts/diff.ts index 5cd82435..c2ac7da7 100644 --- a/src/contexts/diff.js +++ b/src/contexts/diff.ts @@ -1,19 +1,24 @@ import Context from './context'; import defaultClone from '../clone'; +import type { Delta } from '../types'; -class DiffContext extends Context { - constructor(left, right) { +class DiffContext extends Context { + left: unknown; + right: unknown; + pipe: 'diff'; + + constructor(left: unknown, right: unknown) { super(); this.left = left; this.right = right; this.pipe = 'diff'; } - setResult(result) { - if (this.options.cloneDiffValues && typeof result === 'object') { + setResult(result: Delta) { + if (this.options!.cloneDiffValues && typeof result === 'object') { const clone = - typeof this.options.cloneDiffValues === 'function' - ? this.options.cloneDiffValues + typeof this.options!.cloneDiffValues === 'function' + ? this.options!.cloneDiffValues : defaultClone; if (typeof result[0] === 'object') { result[0] = clone(result[0]); @@ -22,7 +27,7 @@ class DiffContext extends Context { result[1] = clone(result[1]); } } - return Context.prototype.setResult.apply(this, arguments); + return super.setResult(result); } } diff --git a/src/contexts/patch.js b/src/contexts/patch.js deleted file mode 100644 index f6d55722..00000000 --- a/src/contexts/patch.js +++ /dev/null @@ -1,12 +0,0 @@ -import Context from './context'; - -class PatchContext extends Context { - constructor(left, delta) { - super(); - this.left = left; - this.delta = delta; - this.pipe = 'patch'; - } -} - -export default PatchContext; diff --git a/src/contexts/patch.ts b/src/contexts/patch.ts new file mode 100644 index 00000000..c2ee5458 --- /dev/null +++ b/src/contexts/patch.ts @@ -0,0 +1,17 @@ +import Context from './context'; +import type { Delta } from '../types'; + +class PatchContext extends Context { + left: unknown; + delta: Delta; + pipe: 'patch'; + + constructor(left: unknown, delta: Delta) { + super(); + this.left = left; + this.delta = delta; + this.pipe = 'patch'; + } +} + +export default PatchContext; diff --git a/src/contexts/reverse.js b/src/contexts/reverse.js deleted file mode 100644 index d49d6cb9..00000000 --- a/src/contexts/reverse.js +++ /dev/null @@ -1,11 +0,0 @@ -import Context from './context'; - -class ReverseContext extends Context { - constructor(delta) { - super(); - this.delta = delta; - this.pipe = 'reverse'; - } -} - -export default ReverseContext; diff --git a/src/contexts/reverse.ts b/src/contexts/reverse.ts new file mode 100644 index 00000000..53124ca6 --- /dev/null +++ b/src/contexts/reverse.ts @@ -0,0 +1,15 @@ +import Context from './context'; +import type { Delta } from '../types'; + +class ReverseContext extends Context { + delta: Delta; + pipe: 'reverse'; + + constructor(delta: Delta) { + super(); + this.delta = delta; + this.pipe = 'reverse'; + } +} + +export default ReverseContext; diff --git a/src/date-reviver.js b/src/date-reviver.ts similarity index 89% rename from src/date-reviver.js rename to src/date-reviver.ts index c4d74ed2..4830ed37 100644 --- a/src/date-reviver.js +++ b/src/date-reviver.ts @@ -1,5 +1,5 @@ // use as 2nd parameter for JSON.parse to revive Date instances -export default function dateReviver(key, value) { +export default function dateReviver(key: string, value: unknown) { let parts; if (typeof value === 'string') { // eslint-disable-next-line max-len diff --git a/src/types.ts b/src/types.ts index 88025b92..6f00dc73 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1 +1,42 @@ -export interface Options {} +import type DiffContext from './contexts/diff'; + +export interface Options { + objectHash?: (item: object, index?: number) => string; + matchByPosition?: boolean; + arrays?: { + detectMove?: boolean; + includeValueOnMove?: boolean; + }; + textDiff?: { + minLength?: number; + }; + propertyFilter?: (name: string, context: DiffContext) => boolean; + cloneDiffValues?: boolean | ((value: unknown) => unknown); +} + +export type AddedDelta = [unknown]; +export type ModifiedDelta = [unknown, unknown]; +export type DeletedDelta = [unknown, 0, 0]; + +export interface ObjectDelta { + [property: string]: Delta; +} + +export interface ArrayDelta { + _t: 'a'; + [index: `${number}` | `_${number}`]: Delta; +} + +export type MovedDelta = [unknown, number, 3]; + +export type TextDiffDelta = [string, 0, 2]; + +export type Delta = + | AddedDelta + | ModifiedDelta + | DeletedDelta + | ObjectDelta + | ArrayDelta + | MovedDelta + | TextDiffDelta + | undefined; From 4f241c8fdb97f24374ffa40a99b4e1fb1ac7c4f0 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Mon, 4 Sep 2023 16:19:55 -0400 Subject: [PATCH 04/19] Convert main files --- src/{diffpatcher.js => diffpatcher.ts} | 25 ++++++++++++++----------- src/{main.js => main.ts} | 25 +++++++++++++------------ src/processor.ts | 4 ++-- 3 files changed, 29 insertions(+), 25 deletions(-) rename src/{diffpatcher.js => diffpatcher.ts} (78%) rename src/{main.js => main.ts} (51%) diff --git a/src/diffpatcher.js b/src/diffpatcher.ts similarity index 78% rename from src/diffpatcher.js rename to src/diffpatcher.ts index 660232d7..8ad01e35 100644 --- a/src/diffpatcher.js +++ b/src/diffpatcher.ts @@ -10,12 +10,15 @@ import * as nested from './filters/nested'; import * as arrays from './filters/arrays'; import * as dates from './filters/dates'; import * as texts from './filters/texts'; +import type { Delta, Options } from './types'; class DiffPatcher { - constructor(options) { + processor: Processor; + + constructor(options?: Options) { this.processor = new Processor(options); this.processor.pipe( - new Pipe('diff') + new Pipe('diff') .append( nested.collectChildrenDiffFilter, trivial.diffFilter, @@ -27,7 +30,7 @@ class DiffPatcher { .shouldHaveResult(), ); this.processor.pipe( - new Pipe('patch') + new Pipe('patch') .append( nested.collectChildrenPatchFilter, arrays.collectChildrenPatchFilter, @@ -39,7 +42,7 @@ class DiffPatcher { .shouldHaveResult(), ); this.processor.pipe( - new Pipe('reverse') + new Pipe('reverse') .append( nested.collectChildrenReverseFilter, arrays.collectChildrenReverseFilter, @@ -52,27 +55,27 @@ class DiffPatcher { ); } - options(...args) { - return this.processor.options(...args); + options(options: Options) { + return this.processor.options(options); } - diff(left, right) { + diff(left: unknown, right: unknown) { return this.processor.process(new DiffContext(left, right)); } - patch(left, delta) { + patch(left: unknown, delta: Delta) { return this.processor.process(new PatchContext(left, delta)); } - reverse(delta) { + reverse(delta: Delta) { return this.processor.process(new ReverseContext(delta)); } - unpatch(right, delta) { + unpatch(right: unknown, delta: Delta) { return this.patch(right, this.reverse(delta)); } - clone(value) { + clone(value: unknown) { return clone(value); } } diff --git a/src/main.js b/src/main.ts similarity index 51% rename from src/main.js rename to src/main.ts index 6ae18423..8760749c 100644 --- a/src/main.js +++ b/src/main.ts @@ -1,5 +1,6 @@ import DiffPatcher from './diffpatcher'; import dateReviver from './date-reviver'; +import type { Delta, Options } from './types'; export { DiffPatcher, dateReviver }; @@ -7,43 +8,43 @@ export * as formatters from './formatters/index'; export * as console from './formatters/console'; -export function create(options) { +export function create(options?: Options) { return new DiffPatcher(options); } -let defaultInstance; +let defaultInstance: DiffPatcher; -export function diff() { +export function diff(left: unknown, right: unknown) { if (!defaultInstance) { defaultInstance = new DiffPatcher(); } - return defaultInstance.diff.apply(defaultInstance, arguments); + return defaultInstance.diff(left, right); } -export function patch() { +export function patch(left: unknown, delta: Delta) { if (!defaultInstance) { defaultInstance = new DiffPatcher(); } - return defaultInstance.patch.apply(defaultInstance, arguments); + return defaultInstance.patch(left, delta); } -export function unpatch() { +export function unpatch(right: unknown, delta: Delta) { if (!defaultInstance) { defaultInstance = new DiffPatcher(); } - return defaultInstance.unpatch.apply(defaultInstance, arguments); + return defaultInstance.unpatch(right, delta); } -export function reverse() { +export function reverse(delta: Delta) { if (!defaultInstance) { defaultInstance = new DiffPatcher(); } - return defaultInstance.reverse.apply(defaultInstance, arguments); + return defaultInstance.reverse(delta); } -export function clone() { +export function clone(value: unknown) { if (!defaultInstance) { defaultInstance = new DiffPatcher(); } - return defaultInstance.clone.apply(defaultInstance, arguments); + return defaultInstance.clone(value); } diff --git a/src/processor.ts b/src/processor.ts index 21e76ebc..32e7dc50 100644 --- a/src/processor.ts +++ b/src/processor.ts @@ -6,7 +6,7 @@ class Processor { selfOptions: Options; pipes: { [pipeName: string]: Pipe> }; - constructor(options: Options) { + constructor(options?: Options) { this.selfOptions = options || {}; this.pipes = {}; } @@ -41,7 +41,7 @@ class Processor { process>( input: TContext, pipe?: Pipe, - ) { + ): TContext['result'] | undefined { let context = input; context.options = this.options(); let nextPipe: Pipe | string | null = From 52da34eacb03bc73fbcdb02716b6226e2b4c7a64 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Mon, 4 Sep 2023 20:53:51 -0400 Subject: [PATCH 05/19] Type diff filters --- src/contexts/diff.ts | 5 ++ src/date-reviver.ts | 1 - src/diff-match-patch.d.ts | 128 +++++++++++++++++++++++++++ src/diffpatcher.ts | 6 +- src/filters/{arrays.js => arrays.ts} | 83 +++++++++-------- src/filters/{dates.js => dates.ts} | 7 +- src/filters/{lcs.js => lcs.ts} | 72 +++++++++++++-- src/filters/{nested.js => nested.ts} | 33 ++++--- src/filters/{texts.js => texts.ts} | 52 +++++++---- src/filters/trivial.js | 114 ------------------------ src/filters/trivial.ts | 111 +++++++++++++++++++++++ src/processor.ts | 11 ++- src/types.ts | 2 +- 13 files changed, 422 insertions(+), 203 deletions(-) create mode 100644 src/diff-match-patch.d.ts rename src/filters/{arrays.js => arrays.ts} (87%) rename src/filters/{dates.js => dates.ts} (74%) rename src/filters/{lcs.js => lcs.ts} (53%) rename src/filters/{nested.js => nested.ts} (77%) rename src/filters/{texts.js => texts.ts} (71%) delete mode 100644 src/filters/trivial.js create mode 100644 src/filters/trivial.ts diff --git a/src/contexts/diff.ts b/src/contexts/diff.ts index c2ac7da7..6a1db695 100644 --- a/src/contexts/diff.ts +++ b/src/contexts/diff.ts @@ -7,6 +7,11 @@ class DiffContext extends Context { right: unknown; pipe: 'diff'; + leftType?: string; + rightType?: string; + leftIsArray?: boolean; + rightIsArray?: boolean; + constructor(left: unknown, right: unknown) { super(); this.left = left; diff --git a/src/date-reviver.ts b/src/date-reviver.ts index 4830ed37..a166bf0b 100644 --- a/src/date-reviver.ts +++ b/src/date-reviver.ts @@ -2,7 +2,6 @@ export default function dateReviver(key: string, value: unknown) { let parts; if (typeof value === 'string') { - // eslint-disable-next-line max-len parts = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d*))?(Z|([+-])(\d{2}):(\d{2}))$/.exec( value, diff --git a/src/diff-match-patch.d.ts b/src/diff-match-patch.d.ts new file mode 100644 index 00000000..c635fc76 --- /dev/null +++ b/src/diff-match-patch.d.ts @@ -0,0 +1,128 @@ +declare module 'diff-match-patch' { + namespace diff_match_patch { + type Diff = [number, string]; + + interface patch_obj { + diffs: Diff[]; + start1: number | null; + start2: number | null; + length1: number; + length2: number; + } + } + + class diff_match_patch { + Diff_Timeout: number; + Diff_EditCost: number; + Match_Threshold: number; + Match_Distance: number; + Patch_DeleteThreshold: number; + Patch_Margin: number; + Match_MaxBits: number; + + diff_main( + text1: string, + text2: string, + opt_checklines?: boolean, + opt_deadline?: number, + ): diff_match_patch.Diff[]; + + diff_bisect_( + text1: string, + text2: string, + deadline: number, + ): diff_match_patch.Diff[]; + + diff_linesToChars_( + text1: string, + text2: string, + ): { chars1: string; chars2: string; lineArray: string[] }; + + diff_charsToLines_( + diffs: diff_match_patch.Diff[], + lineArray: string[], + ): void; + + diff_commonPrefix(text1: string, text2: string): number; + + diff_commonSuffix(text1: string, text2: string): number; + + diff_commonOverlap_(text1: string, text2: string): number; + + diff_halfMatch_(text1: string, text2: string): string[]; + + diff_cleanupSemantic(diffs: diff_match_patch.Diff[]): void; + + diff_cleanupSemanticLossless(diffs: diff_match_patch.Diff[]): void; + + diff_cleanupEfficiency(diffs: diff_match_patch.Diff[]): void; + + diff_cleanupMerge(diffs: diff_match_patch.Diff[]): void; + + diff_xIndex(diffs: diff_match_patch.Diff[], loc: number): number; + + diff_prettyHtml(diffs: diff_match_patch.Diff[]): string; + + diff_text1(diffs: diff_match_patch.Diff[]): string; + + diff_text2(diffs: diff_match_patch.Diff[]): string; + + diff_levenshtein(diffs: diff_match_patch.Diff[]): number; + + diff_toDelta(diffs: diff_match_patch.Diff[]): string; + + diff_fromDelta(text1: string, delta: string): diff_match_patch.Diff[]; + + match_main(text: string, pattern: string, loc: number): number; + + match_bitap_(text: string, pattern: string, loc: number): number; + + match_alphabet_(pattern: string): { [char: string]: number }; + + patch_addContext_( + patch: typeof diff_match_patch.patch_obj, + text: string, + ): void; + + patch_make( + a: string, + opt_b: string | diff_match_patch.Diff[], + ): Array; + patch_make( + a: diff_match_patch.Diff[], + ): Array; + patch_make( + a: string, + opt_b: string, + opt_c: diff_match_patch.Diff[], + ): Array; + + patch_deepCopy( + patches: Array, + ): Array; + + patch_apply( + patches: Array, + text: string, + ): [string, boolean[]]; + + patch_addPadding(patches: Array): string; + + patch_splitMax(patches: Array): void; + + patch_fromText(text: string): Array; + + patch_toText(patches: Array): string; + + static patch_obj: { + new (): diff_match_patch.patch_obj; + }; + + static diff_match_patch: typeof diff_match_patch; + static DIFF_DELETE: -1; + static DIFF_INSERT: 1; + static DIFF_EQUAL: 0; + } + + export = diff_match_patch; +} diff --git a/src/diffpatcher.ts b/src/diffpatcher.ts index 8ad01e35..273b8262 100644 --- a/src/diffpatcher.ts +++ b/src/diffpatcher.ts @@ -27,7 +27,7 @@ class DiffPatcher { nested.objectsDiffFilter, arrays.diffFilter, ) - .shouldHaveResult(), + .shouldHaveResult()!, ); this.processor.pipe( new Pipe('patch') @@ -39,7 +39,7 @@ class DiffPatcher { nested.patchFilter, arrays.patchFilter, ) - .shouldHaveResult(), + .shouldHaveResult()!, ); this.processor.pipe( new Pipe('reverse') @@ -51,7 +51,7 @@ class DiffPatcher { nested.reverseFilter, arrays.reverseFilter, ) - .shouldHaveResult(), + .shouldHaveResult()!, ); } diff --git a/src/filters/arrays.js b/src/filters/arrays.ts similarity index 87% rename from src/filters/arrays.js rename to src/filters/arrays.ts index 3b26f365..bf41e7c9 100644 --- a/src/filters/arrays.js +++ b/src/filters/arrays.ts @@ -3,28 +3,17 @@ import PatchContext from '../contexts/patch'; import ReverseContext from '../contexts/reverse'; import lcs from './lcs'; +import type { Filter } from '../pipe'; +import type { AddedDelta, DeletedDelta, MovedDelta } from '../types'; const ARRAY_MOVE = 3; -const isArray = - typeof Array.isArray === 'function' - ? Array.isArray - : (a) => a instanceof Array; - -const arrayIndexOf = - typeof Array.prototype.indexOf === 'function' - ? (array, item) => array.indexOf(item) - : (array, item) => { - const length = array.length; - for (let i = 0; i < length; i++) { - if (array[i] === item) { - return i; - } - } - return -1; - }; - -function arraysHaveMatchByRef(array1, array2, len1, len2) { +function arraysHaveMatchByRef( + array1: readonly unknown[], + array2: readonly unknown[], + len1: number, + len2: number, +) { for (let index1 = 0; index1 < len1; index1++) { const val1 = array1[index1]; for (let index2 = 0; index2 < len2; index2++) { @@ -36,7 +25,20 @@ function arraysHaveMatchByRef(array1, array2, len1, len2) { } } -function matchItems(array1, array2, index1, index2, context) { +export interface MatchContext { + objectHash: ((item: object, index?: number) => string) | undefined; + matchByPosition: boolean | undefined; + hashCache1?: string[]; + hashCache2?: string[]; +} + +function matchItems( + array1: readonly unknown[], + array2: readonly unknown[], + index1: number, + index2: number, + context: MatchContext, +) { const value1 = array1[index1]; const value2 = array2[index2]; if (value1 === value2) { @@ -53,7 +55,7 @@ function matchItems(array1, array2, index1, index2, context) { context.hashCache1 = context.hashCache1 || []; let hash1 = context.hashCache1[index1]; if (typeof hash1 === 'undefined') { - context.hashCache1[index1] = hash1 = objectHash(value1, index1); + context.hashCache1[index1] = hash1 = objectHash(value1 as object, index1); } if (typeof hash1 === 'undefined') { return false; @@ -61,7 +63,7 @@ function matchItems(array1, array2, index1, index2, context) { context.hashCache2 = context.hashCache2 || []; let hash2 = context.hashCache2[index2]; if (typeof hash2 === 'undefined') { - context.hashCache2[index2] = hash2 = objectHash(value2, index2); + context.hashCache2[index2] = hash2 = objectHash(value2 as object, index2); } if (typeof hash2 === 'undefined') { return false; @@ -69,12 +71,14 @@ function matchItems(array1, array2, index1, index2, context) { return hash1 === hash2; } -export const diffFilter = function arraysDiffFilter(context) { +export const diffFilter: Filter = function arraysDiffFilter( + context, +) { if (!context.leftIsArray) { return; } - const matchContext = { + const matchContext: MatchContext = { objectHash: context.options && context.options.objectHash, matchByPosition: context.options && context.options.matchByPosition, }; @@ -83,8 +87,8 @@ export const diffFilter = function arraysDiffFilter(context) { let index; let index1; let index2; - const array1 = context.left; - const array2 = context.right; + const array1 = context.left as readonly unknown[]; + const array2 = context.right as readonly unknown[]; const len1 = array1.length; const len2 = array2.length; @@ -111,7 +115,7 @@ export const diffFilter = function arraysDiffFilter(context) { matchItems(array1, array2, commonHead, commonHead, matchContext) ) { index = commonHead; - child = new DiffContext(context.left[index], context.right[index]); + child = new DiffContext(array1[index], array2[index]); context.push(child, index); commonHead++; } @@ -129,11 +133,17 @@ export const diffFilter = function arraysDiffFilter(context) { ) { index1 = len1 - 1 - commonTail; index2 = len2 - 1 - commonTail; - child = new DiffContext(context.left[index1], context.right[index2]); + child = new DiffContext(array1[index1], array2[index2]); context.push(child, index2); commonTail++; } - let result; + let result: + | { + _t: 'a'; + [index: number]: AddedDelta; + [index: `_${number}`]: MovedDelta | DeletedDelta; + } + | undefined; if (commonHead + commonTail === len1) { if (len1 === len2) { // arrays are identical @@ -174,7 +184,7 @@ export const diffFilter = function arraysDiffFilter(context) { _t: 'a', }; for (index = commonHead; index < len1 - commonTail; index++) { - if (arrayIndexOf(seq.indices1, index - commonHead) < 0) { + if (seq.indices1.indexOf(index - commonHead) < 0) { // removed result[`_${index}`] = [array1[index], 0, 0]; removedItems.push(index); @@ -200,7 +210,7 @@ export const diffFilter = function arraysDiffFilter(context) { const removedItemsLength = removedItems.length; for (index = commonHead; index < len2 - commonTail; index++) { - const indexOnArray2 = arrayIndexOf(seq.indices2, index - commonHead); + const indexOnArray2 = seq.indices2.indexOf(index - commonHead); if (indexOnArray2 < 0) { // added, try to match with a removed item and register as position move let isMove = false; @@ -228,10 +238,7 @@ export const diffFilter = function arraysDiffFilter(context) { } index2 = index; - child = new DiffContext( - context.left[index1], - context.right[index2], - ); + child = new DiffContext(array1[index1], array2[index2]); context.push(child, index2); removedItems.splice(removeItemIndex1, 1); isMove = true; @@ -247,7 +254,7 @@ export const diffFilter = function arraysDiffFilter(context) { // match, do inner diff index1 = seq.indices1[indexOnArray2] + commonHead; index2 = seq.indices2[indexOnArray2] + commonHead; - child = new DiffContext(context.left[index1], context.right[index2]); + child = new DiffContext(array1[index1], array2[index2]); context.push(child, index2); } } @@ -409,14 +416,14 @@ reverseFilter.filterName = 'arrays'; const reverseArrayDeltaIndex = (delta, index, itemDelta) => { if (typeof index === 'string' && index[0] === '_') { return parseInt(index.substring(1), 10); - } else if (isArray(itemDelta) && itemDelta[2] === 0) { + } else if (Array.isArray(itemDelta) && itemDelta[2] === 0) { return `_${index}`; } let reverseIndex = +index; for (const deltaIndex in delta) { const deltaItem = delta[deltaIndex]; - if (isArray(deltaItem)) { + if (Array.isArray(deltaItem)) { if (deltaItem[2] === ARRAY_MOVE) { const moveFromIndex = parseInt(deltaIndex.substring(1), 10); const moveToIndex = deltaItem[1]; diff --git a/src/filters/dates.js b/src/filters/dates.ts similarity index 74% rename from src/filters/dates.js rename to src/filters/dates.ts index fc1f8aba..3702d702 100644 --- a/src/filters/dates.js +++ b/src/filters/dates.ts @@ -1,4 +1,9 @@ -export const diffFilter = function datesDiffFilter(context) { +import type { Filter } from '../pipe'; +import type DiffContext from '../contexts/diff'; + +export const diffFilter: Filter = function datesDiffFilter( + context, +) { if (context.left instanceof Date) { if (context.right instanceof Date) { if (context.left.getTime() !== context.right.getTime()) { diff --git a/src/filters/lcs.js b/src/filters/lcs.ts similarity index 53% rename from src/filters/lcs.js rename to src/filters/lcs.ts index 4435a6df..0751b7f5 100644 --- a/src/filters/lcs.js +++ b/src/filters/lcs.ts @@ -6,19 +6,45 @@ reference: http://en.wikipedia.org/wiki/Longest_common_subsequence_problem */ -const defaultMatch = function (array1, array2, index1, index2) { +import type { MatchContext } from './arrays'; + +const defaultMatch = function ( + array1: readonly unknown[], + array2: readonly unknown[], + index1: number, + index2: number, +) { return array1[index1] === array2[index2]; }; -const lengthMatrix = function (array1, array2, match, context) { +const lengthMatrix = function ( + array1: readonly unknown[], + array2: readonly unknown[], + match: ( + array1: readonly unknown[], + array2: readonly unknown[], + index1: number, + index2: number, + context: MatchContext, + ) => boolean | undefined, + context: MatchContext, +) { const len1 = array1.length; const len2 = array2.length; let x, y; // initialize empty matrix of len1+1 x len2+1 - const matrix = new Array(len1 + 1); + const matrix: number[][] & { + match?: ( + array1: readonly unknown[], + array2: readonly unknown[], + index1: number, + index2: number, + context: MatchContext, + ) => boolean | undefined; + } = new Array(len1 + 1); for (x = 0; x < len1 + 1; x++) { - matrix[x] = new Array(len2 + 1); + matrix[x] = new Array(len2 + 1); for (y = 0; y < len2 + 1; y++) { matrix[x][y] = 0; } @@ -37,17 +63,36 @@ const lengthMatrix = function (array1, array2, match, context) { return matrix; }; -const backtrack = function (matrix, array1, array2, context) { +interface Subsequence { + sequence: unknown[]; + indices1: number[]; + indices2: number[]; +} + +const backtrack = function ( + matrix: number[][] & { + match?: ( + array1: readonly unknown[], + array2: readonly unknown[], + index1: number, + index2: number, + context: MatchContext, + ) => boolean | undefined; + }, + array1: readonly unknown[], + array2: readonly unknown[], + context: MatchContext, +) { let index1 = array1.length; let index2 = array2.length; - const subsequence = { + const subsequence: Subsequence = { sequence: [], indices1: [], indices2: [], }; while (index1 !== 0 && index2 !== 0) { - const sameLetter = matrix.match( + const sameLetter = matrix.match!( array1, array2, index1 - 1, @@ -73,7 +118,18 @@ const backtrack = function (matrix, array1, array2, context) { return subsequence; }; -const get = function (array1, array2, match, context) { +const get = function ( + array1: readonly unknown[], + array2: readonly unknown[], + match: ( + array1: readonly unknown[], + array2: readonly unknown[], + index1: number, + index2: number, + context: MatchContext, + ) => boolean | undefined, + context: MatchContext, +) { const innerContext = context || {}; const matrix = lengthMatrix( array1, diff --git a/src/filters/nested.js b/src/filters/nested.ts similarity index 77% rename from src/filters/nested.js rename to src/filters/nested.ts index 3c1e6d5d..83669235 100644 --- a/src/filters/nested.js +++ b/src/filters/nested.ts @@ -1,56 +1,61 @@ import DiffContext from '../contexts/diff'; import PatchContext from '../contexts/patch'; import ReverseContext from '../contexts/reverse'; +import type { Filter } from '../pipe'; +import type { ArrayDelta, Delta, ObjectDelta } from '../types'; -export function collectChildrenDiffFilter(context) { +export const collectChildrenDiffFilter: Filter = (context) => { if (!context || !context.children) { return; } const length = context.children.length; let child; - let result = context.result; + let result = context.result as ObjectDelta | ArrayDelta; for (let index = 0; index < length; index++) { child = context.children[index]; if (typeof child.result === 'undefined') { continue; } result = result || {}; - result[child.childName] = child.result; + (result as Record)[child.childName!] = child.result; } if (result && context.leftIsArray) { result._t = 'a'; } context.setResult(result).exit(); -} +}; collectChildrenDiffFilter.filterName = 'collectChildren'; -export function objectsDiffFilter(context) { +export const objectsDiffFilter: Filter = (context) => { if (context.leftIsArray || context.leftType !== 'object') { return; } + const left = context.left as Record; + const right = context.right as Record; + let name; let child; - const propertyFilter = context.options.propertyFilter; - for (name in context.left) { - if (!Object.prototype.hasOwnProperty.call(context.left, name)) { + const propertyFilter = context.options!.propertyFilter; + for (name in left) { + if (!Object.prototype.hasOwnProperty.call(left, name)) { continue; } if (propertyFilter && !propertyFilter(name, context)) { continue; } - child = new DiffContext(context.left[name], context.right[name]); + child = new DiffContext(left[name], right[name]); context.push(child, name); } - for (name in context.right) { - if (!Object.prototype.hasOwnProperty.call(context.right, name)) { + for (name in right) { + if (!Object.prototype.hasOwnProperty.call(right, name)) { continue; } if (propertyFilter && !propertyFilter(name, context)) { continue; } - if (typeof context.left[name] === 'undefined') { - child = new DiffContext(undefined, context.right[name]); + if (typeof left[name] === 'undefined') { + child = new DiffContext(undefined, right[name]); context.push(child, name); } } @@ -60,7 +65,7 @@ export function objectsDiffFilter(context) { return; } context.exit(); -} +}; objectsDiffFilter.filterName = 'objects'; export const patchFilter = function nestedPatchFilter(context) { diff --git a/src/filters/texts.js b/src/filters/texts.ts similarity index 71% rename from src/filters/texts.js rename to src/filters/texts.ts index b7b92c38..1fd7af9b 100644 --- a/src/filters/texts.js +++ b/src/filters/texts.ts @@ -1,22 +1,29 @@ -/* global diff_match_patch */ import dmp from 'diff-match-patch'; +import type { Filter } from '../pipe'; +import type DiffContext from '../contexts/diff'; + +declare global { + const diff_match_patch: typeof dmp | undefined; +} + +interface DiffPatch { + diff: (txt1: string, txt2: string) => string; + patch: (txt1: string, string: string) => string; +} const TEXT_DIFF = 2; const DEFAULT_MIN_LENGTH = 60; -let cachedDiffPatch = null; - -const getDiffMatchPatch = function (required) { - /* jshint camelcase: false */ +let cachedDiffPatch: DiffPatch | null = null; +const getDiffMatchPatch = function (required?: boolean) { if (!cachedDiffPatch) { - let instance; - /* eslint-disable camelcase, new-cap */ + let instance: dmp | null | undefined; if (typeof diff_match_patch !== 'undefined') { // already loaded, probably a browser instance = typeof diff_match_patch === 'function' ? new diff_match_patch() - : new diff_match_patch.diff_match_patch(); + : new (diff_match_patch as typeof dmp).diff_match_patch(); } else if (dmp) { try { instance = dmp && new dmp(); @@ -24,28 +31,31 @@ const getDiffMatchPatch = function (required) { instance = null; } } - /* eslint-enable camelcase, new-cap */ if (!instance) { if (!required) { return null; } - const error = new Error('text diff_match_patch library not found'); + const error: Error & { diff_match_patch_not_found?: boolean } = new Error( + 'text diff_match_patch library not found', + ); // eslint-disable-next-line camelcase error.diff_match_patch_not_found = true; throw error; } cachedDiffPatch = { diff: function (txt1, txt2) { - return instance.patch_toText(instance.patch_make(txt1, txt2)); + return instance!.patch_toText(instance!.patch_make(txt1, txt2)); }, patch: function (txt1, patch) { - const results = instance.patch_apply( - instance.patch_fromText(patch), + const results = instance!.patch_apply( + instance!.patch_fromText(patch), txt1, ); for (let i = 0; i < results[1].length; i++) { if (!results[1][i]) { - const error = new Error('text patch failed'); + const error: Error & { textPatchFailed?: boolean } = new Error( + 'text patch failed', + ); error.textPatchFailed = true; } } @@ -56,17 +66,21 @@ const getDiffMatchPatch = function (required) { return cachedDiffPatch; }; -export const diffFilter = function textsDiffFilter(context) { +export const diffFilter: Filter = function textsDiffFilter( + context, +) { if (context.leftType !== 'string') { return; } + const left = context.left as string; + const right = context.right as string; const minLength = (context.options && context.options.textDiff && context.options.textDiff.minLength) || DEFAULT_MIN_LENGTH; - if (context.left.length < minLength || context.right.length < minLength) { - context.setResult([context.left, context.right]).exit(); + if (left.length < minLength || right.length < minLength) { + context.setResult([left, right]).exit(); return; } // large text, try to use a text-diff algorithm @@ -74,11 +88,11 @@ export const diffFilter = function textsDiffFilter(context) { if (!diffMatchPatch) { // diff-match-patch library not available, // fallback to regular string replace - context.setResult([context.left, context.right]).exit(); + context.setResult([left, right]).exit(); return; } const diff = diffMatchPatch.diff; - context.setResult([diff(context.left, context.right), 0, TEXT_DIFF]).exit(); + context.setResult([diff(left, right), 0, TEXT_DIFF]).exit(); }; diffFilter.filterName = 'texts'; diff --git a/src/filters/trivial.js b/src/filters/trivial.js deleted file mode 100644 index 1d05c6ce..00000000 --- a/src/filters/trivial.js +++ /dev/null @@ -1,114 +0,0 @@ -const isArray = - typeof Array.isArray === 'function' - ? Array.isArray - : function (a) { - return a instanceof Array; - }; - -export const diffFilter = function trivialMatchesDiffFilter(context) { - if (context.left === context.right) { - context.setResult(undefined).exit(); - return; - } - if (typeof context.left === 'undefined') { - if (typeof context.right === 'function') { - throw new Error('functions are not supported'); - } - context.setResult([context.right]).exit(); - return; - } - if (typeof context.right === 'undefined') { - context.setResult([context.left, 0, 0]).exit(); - return; - } - if ( - typeof context.left === 'function' || - typeof context.right === 'function' - ) { - throw new Error('functions are not supported'); - } - context.leftType = context.left === null ? 'null' : typeof context.left; - context.rightType = context.right === null ? 'null' : typeof context.right; - if (context.leftType !== context.rightType) { - context.setResult([context.left, context.right]).exit(); - return; - } - if (context.leftType === 'boolean' || context.leftType === 'number') { - context.setResult([context.left, context.right]).exit(); - return; - } - if (context.leftType === 'object') { - context.leftIsArray = isArray(context.left); - } - if (context.rightType === 'object') { - context.rightIsArray = isArray(context.right); - } - if (context.leftIsArray !== context.rightIsArray) { - context.setResult([context.left, context.right]).exit(); - return; - } - - if (context.left instanceof RegExp) { - if (context.right instanceof RegExp) { - context - .setResult([context.left.toString(), context.right.toString()]) - .exit(); - } else { - context.setResult([context.left, context.right]).exit(); - } - } -}; -diffFilter.filterName = 'trivial'; - -export const patchFilter = function trivialMatchesPatchFilter(context) { - if (typeof context.delta === 'undefined') { - context.setResult(context.left).exit(); - return; - } - context.nested = !isArray(context.delta); - if (context.nested) { - return; - } - if (context.delta.length === 1) { - context.setResult(context.delta[0]).exit(); - return; - } - if (context.delta.length === 2) { - if (context.left instanceof RegExp) { - const regexArgs = /^\/(.*)\/([gimyu]+)$/.exec(context.delta[1]); - if (regexArgs) { - context.setResult(new RegExp(regexArgs[1], regexArgs[2])).exit(); - return; - } - } - context.setResult(context.delta[1]).exit(); - return; - } - if (context.delta.length === 3 && context.delta[2] === 0) { - context.setResult(undefined).exit(); - } -}; -patchFilter.filterName = 'trivial'; - -export const reverseFilter = function trivialReferseFilter(context) { - if (typeof context.delta === 'undefined') { - context.setResult(context.delta).exit(); - return; - } - context.nested = !isArray(context.delta); - if (context.nested) { - return; - } - if (context.delta.length === 1) { - context.setResult([context.delta[0], 0, 0]).exit(); - return; - } - if (context.delta.length === 2) { - context.setResult([context.delta[1], context.delta[0]]).exit(); - return; - } - if (context.delta.length === 3 && context.delta[2] === 0) { - context.setResult([context.delta[0]]).exit(); - } -}; -reverseFilter.filterName = 'trivial'; diff --git a/src/filters/trivial.ts b/src/filters/trivial.ts new file mode 100644 index 00000000..d9e9b89b --- /dev/null +++ b/src/filters/trivial.ts @@ -0,0 +1,111 @@ +import type { Filter } from '../pipe'; +import type DiffContext from '../contexts/diff'; + +export const diffFilter: Filter = + function trivialMatchesDiffFilter(context) { + if (context.left === context.right) { + context.setResult(undefined).exit(); + return; + } + if (typeof context.left === 'undefined') { + if (typeof context.right === 'function') { + throw new Error('functions are not supported'); + } + context.setResult([context.right]).exit(); + return; + } + if (typeof context.right === 'undefined') { + context.setResult([context.left, 0, 0]).exit(); + return; + } + if ( + typeof context.left === 'function' || + typeof context.right === 'function' + ) { + throw new Error('functions are not supported'); + } + context.leftType = context.left === null ? 'null' : typeof context.left; + context.rightType = context.right === null ? 'null' : typeof context.right; + if (context.leftType !== context.rightType) { + context.setResult([context.left, context.right]).exit(); + return; + } + if (context.leftType === 'boolean' || context.leftType === 'number') { + context.setResult([context.left, context.right]).exit(); + return; + } + if (context.leftType === 'object') { + context.leftIsArray = Array.isArray(context.left); + } + if (context.rightType === 'object') { + context.rightIsArray = Array.isArray(context.right); + } + if (context.leftIsArray !== context.rightIsArray) { + context.setResult([context.left, context.right]).exit(); + return; + } + + if (context.left instanceof RegExp) { + if (context.right instanceof RegExp) { + context + .setResult([context.left.toString(), context.right.toString()]) + .exit(); + } else { + context.setResult([context.left, context.right]).exit(); + } + } + }; +diffFilter.filterName = 'trivial'; + +export const patchFilter = function trivialMatchesPatchFilter(context) { + if (typeof context.delta === 'undefined') { + context.setResult(context.left).exit(); + return; + } + context.nested = !Array.isArray(context.delta); + if (context.nested) { + return; + } + if (context.delta.length === 1) { + context.setResult(context.delta[0]).exit(); + return; + } + if (context.delta.length === 2) { + if (context.left instanceof RegExp) { + const regexArgs = /^\/(.*)\/([gimyu]+)$/.exec(context.delta[1]); + if (regexArgs) { + context.setResult(new RegExp(regexArgs[1], regexArgs[2])).exit(); + return; + } + } + context.setResult(context.delta[1]).exit(); + return; + } + if (context.delta.length === 3 && context.delta[2] === 0) { + context.setResult(undefined).exit(); + } +}; +patchFilter.filterName = 'trivial'; + +export const reverseFilter = function trivialReferseFilter(context) { + if (typeof context.delta === 'undefined') { + context.setResult(context.delta).exit(); + return; + } + context.nested = !Array.isArray(context.delta); + if (context.nested) { + return; + } + if (context.delta.length === 1) { + context.setResult([context.delta[0], 0, 0]).exit(); + return; + } + if (context.delta.length === 2) { + context.setResult([context.delta[1], context.delta[0]]).exit(); + return; + } + if (context.delta.length === 3 && context.delta[2] === 0) { + context.setResult([context.delta[0]]).exit(); + } +}; +reverseFilter.filterName = 'trivial'; diff --git a/src/processor.ts b/src/processor.ts index 32e7dc50..5d178d39 100644 --- a/src/processor.ts +++ b/src/processor.ts @@ -18,21 +18,24 @@ class Processor { return this.selfOptions; } - pipe(name: string | Pipe>, pipeArg?: Pipe>) { + pipe>( + name: string | Pipe, + pipeArg?: Pipe, + ) { let pipe = pipeArg; if (typeof name === 'string') { if (typeof pipe === 'undefined') { return this.pipes[name]!; } else { - this.pipes[name] = pipe; + this.pipes[name] = pipe as Pipe>; } } - if (name && (name as Pipe).name) { + if (name && (name as Pipe).name) { pipe = name as Pipe>; if (pipe.processor === this) { return pipe; } - this.pipes[pipe.name] = pipe; + this.pipes[pipe.name] = pipe as Pipe>; } pipe!.processor = this; return pipe!; diff --git a/src/types.ts b/src/types.ts index 6f00dc73..26b9ad1f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -24,7 +24,7 @@ export interface ObjectDelta { export interface ArrayDelta { _t: 'a'; - [index: `${number}` | `_${number}`]: Delta; + [index: number | `_${number}`]: Delta; } export type MovedDelta = [unknown, number, 3]; From c4ef7355a809bf8fb94d0905a7cb25620a8739b3 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Mon, 4 Sep 2023 21:33:17 -0400 Subject: [PATCH 06/19] Type patch filters --- src/contexts/patch.ts | 2 + src/filters/arrays.ts | 96 ++++++++++++++++++++++++------------------ src/filters/nested.ts | 63 +++++++++++++++------------ src/filters/texts.ts | 29 ++++++++++--- src/filters/trivial.ts | 69 ++++++++++++++++++------------ src/types.ts | 4 +- 6 files changed, 164 insertions(+), 99 deletions(-) diff --git a/src/contexts/patch.ts b/src/contexts/patch.ts index c2ee5458..fd7371eb 100644 --- a/src/contexts/patch.ts +++ b/src/contexts/patch.ts @@ -6,6 +6,8 @@ class PatchContext extends Context { delta: Delta; pipe: 'patch'; + nested?: boolean; + constructor(left: unknown, delta: Delta) { super(); this.left = left; diff --git a/src/filters/arrays.ts b/src/filters/arrays.ts index bf41e7c9..13796113 100644 --- a/src/filters/arrays.ts +++ b/src/filters/arrays.ts @@ -4,7 +4,14 @@ import ReverseContext from '../contexts/reverse'; import lcs from './lcs'; import type { Filter } from '../pipe'; -import type { AddedDelta, DeletedDelta, MovedDelta } from '../types'; +import type { + AddedDelta, + ArrayDelta, + DeletedDelta, + Delta, + MovedDelta, + ObjectDelta, +} from '../types'; const ARRAY_MOVE = 3; @@ -264,55 +271,65 @@ export const diffFilter: Filter = function arraysDiffFilter( diffFilter.filterName = 'arrays'; const compare = { - numerically(a, b) { + numerically(this: void, a: number, b: number) { return a - b; }, - numericallyBy(name) { - return (a, b) => a[name] - b[name]; + numericallyBy( + name: { [K in keyof T]: T[K] extends number ? K : never }[keyof T], + ) { + return (a: T, b: T) => (a[name] as number) - (b[name] as number); }, }; -export const patchFilter = function nestedPatchFilter(context) { +export const patchFilter: Filter = function nestedPatchFilter( + context, +) { if (!context.nested) { return; } - if (context.delta._t !== 'a') { + const nestedDelta = context.delta as ObjectDelta | ArrayDelta; + if (nestedDelta._t !== 'a') { return; } let index; let index1; - const delta = context.delta; - const array = context.left; + const delta = nestedDelta as ArrayDelta; + const array = context.left as unknown[]; // first, separate removals, insertions and modifications - let toRemove = []; - let toInsert = []; - const toModify = []; + let toRemove: number[] = []; + let toInsert: { index: number; value: unknown }[] = []; + const toModify: { index: number; delta: Delta }[] = []; for (index in delta) { if (index !== '_t') { if (index[0] === '_') { + const removedOrMovedIndex = index as `_${number}`; // removed item from original array - if (delta[index][2] === 0 || delta[index][2] === ARRAY_MOVE) { + if ( + delta[removedOrMovedIndex][2] === 0 || + delta[removedOrMovedIndex][2] === ARRAY_MOVE + ) { toRemove.push(parseInt(index.slice(1), 10)); } else { throw new Error( 'only removal or move can be applied at original array indices,' + - ` invalid diff type: ${delta[index][2]}`, + ` invalid diff type: ${delta[removedOrMovedIndex][2]}`, ); } } else { - if (delta[index].length === 1) { + const numberIndex = index as `${number}`; + if ((delta[numberIndex] as unknown[]).length === 1) { // added item at new array toInsert.push({ - index: parseInt(index, 10), - value: delta[index][0], + index: parseInt(numberIndex, 10), + value: (delta[numberIndex] as AddedDelta)[0], }); } else { // modified item at new array toModify.push({ - index: parseInt(index, 10), - delta: delta[index], + index: parseInt(numberIndex, 10), + delta: delta[numberIndex], }); } } @@ -348,39 +365,38 @@ export const patchFilter = function nestedPatchFilter(context) { if (toModifyLength > 0) { for (index = 0; index < toModifyLength; index++) { const modification = toModify[index]; - child = new PatchContext( - context.left[modification.index], - modification.delta, - ); + child = new PatchContext(array[modification.index], modification.delta); context.push(child, modification.index); } } if (!context.children) { - context.setResult(context.left).exit(); + context.setResult(array).exit(); return; } context.exit(); }; patchFilter.filterName = 'arrays'; -export const collectChildrenPatchFilter = function collectChildrenPatchFilter( - context, -) { - if (!context || !context.children) { - return; - } - if (context.delta._t !== 'a') { - return; - } - const length = context.children.length; - let child; - for (let index = 0; index < length; index++) { - child = context.children[index]; - context.left[child.childName] = child.result; - } - context.setResult(context.left).exit(); -}; +export const collectChildrenPatchFilter: Filter = + function collectChildrenPatchFilter(context) { + if (!context || !context.children) { + return; + } + const deltaWithChildren = context.delta as ObjectDelta | ArrayDelta; + if (deltaWithChildren._t !== 'a') { + return; + } + const array = context.left as unknown[]; + const length = context.children.length; + let child; + for (let index = 0; index < length; index++) { + child = context.children[index]; + const arrayIndex = child.childName as number; + array[arrayIndex] = child.result; + } + context.setResult(array).exit(); + }; collectChildrenPatchFilter.filterName = 'arraysCollectChildren'; export const reverseFilter = function arraysReverseFilter(context) { diff --git a/src/filters/nested.ts b/src/filters/nested.ts index 83669235..6888238a 100644 --- a/src/filters/nested.ts +++ b/src/filters/nested.ts @@ -68,47 +68,56 @@ export const objectsDiffFilter: Filter = (context) => { }; objectsDiffFilter.filterName = 'objects'; -export const patchFilter = function nestedPatchFilter(context) { +export const patchFilter: Filter = function nestedPatchFilter( + context, +) { if (!context.nested) { return; } - if (context.delta._t) { + const nestedDelta = context.delta as ObjectDelta | ArrayDelta; + if (nestedDelta._t) { return; } + const objectDelta = nestedDelta as ObjectDelta; let name; let child; - for (name in context.delta) { - child = new PatchContext(context.left[name], context.delta[name]); + for (name in objectDelta) { + child = new PatchContext( + (context.left as Record)[name], + objectDelta[name], + ); context.push(child, name); } context.exit(); }; patchFilter.filterName = 'objects'; -export const collectChildrenPatchFilter = function collectChildrenPatchFilter( - context, -) { - if (!context || !context.children) { - return; - } - if (context.delta._t) { - return; - } - const length = context.children.length; - let child; - for (let index = 0; index < length; index++) { - child = context.children[index]; - if ( - Object.prototype.hasOwnProperty.call(context.left, child.childName) && - child.result === undefined - ) { - delete context.left[child.childName]; - } else if (context.left[child.childName] !== child.result) { - context.left[child.childName] = child.result; +export const collectChildrenPatchFilter: Filter = + function collectChildrenPatchFilter(context) { + if (!context || !context.children) { + return; } - } - context.setResult(context.left).exit(); -}; + const deltaWithChildren = context.delta as ObjectDelta | ArrayDelta; + if (deltaWithChildren._t) { + return; + } + const object = context.left as Record; + const length = context.children.length; + let child; + for (let index = 0; index < length; index++) { + child = context.children[index]; + const property = child.childName as string; + if ( + Object.prototype.hasOwnProperty.call(context.left, property) && + child.result === undefined + ) { + delete object[property]; + } else if (object[property] !== child.result) { + object[property] = child.result; + } + } + context.setResult(object).exit(); + }; collectChildrenPatchFilter.filterName = 'collectChildren'; export const reverseFilter = function nestedReverseFilter(context) { diff --git a/src/filters/texts.ts b/src/filters/texts.ts index 1fd7af9b..04b34856 100644 --- a/src/filters/texts.ts +++ b/src/filters/texts.ts @@ -1,6 +1,14 @@ import dmp from 'diff-match-patch'; import type { Filter } from '../pipe'; import type DiffContext from '../contexts/diff'; +import type PatchContext from '../contexts/patch'; +import type { + AddedDelta, + DeletedDelta, + ModifiedDelta, + MovedDelta, + TextDiffDelta, +} from '../types'; declare global { const diff_match_patch: typeof dmp | undefined; @@ -15,7 +23,9 @@ const TEXT_DIFF = 2; const DEFAULT_MIN_LENGTH = 60; let cachedDiffPatch: DiffPatch | null = null; -const getDiffMatchPatch = function (required?: boolean) { +function getDiffMatchPatch(required: true): DiffPatch; +function getDiffMatchPatch(required?: boolean): DiffPatch; +function getDiffMatchPatch(required?: boolean) { if (!cachedDiffPatch) { let instance: dmp | null | undefined; if (typeof diff_match_patch !== 'undefined') { @@ -64,7 +74,7 @@ const getDiffMatchPatch = function (required?: boolean) { }; } return cachedDiffPatch; -}; +} export const diffFilter: Filter = function textsDiffFilter( context, @@ -96,17 +106,26 @@ export const diffFilter: Filter = function textsDiffFilter( }; diffFilter.filterName = 'texts'; -export const patchFilter = function textsPatchFilter(context) { +export const patchFilter: Filter = function textsPatchFilter( + context, +) { if (context.nested) { return; } - if (context.delta[2] !== TEXT_DIFF) { + const nonNestedDelta = context.delta as + | AddedDelta + | ModifiedDelta + | DeletedDelta + | MovedDelta + | TextDiffDelta; + if (nonNestedDelta[2] !== TEXT_DIFF) { return; } + const textDiffDelta = nonNestedDelta as TextDiffDelta; // text-diff, use a text-patch algorithm const patch = getDiffMatchPatch(true).patch; - context.setResult(patch(context.left, context.delta[0])).exit(); + context.setResult(patch(context.left as string, textDiffDelta[0])).exit(); }; patchFilter.filterName = 'texts'; diff --git a/src/filters/trivial.ts b/src/filters/trivial.ts index d9e9b89b..7741dfd5 100644 --- a/src/filters/trivial.ts +++ b/src/filters/trivial.ts @@ -1,5 +1,13 @@ import type { Filter } from '../pipe'; import type DiffContext from '../contexts/diff'; +import type PatchContext from '../contexts/patch'; +import type { + AddedDelta, + DeletedDelta, + ModifiedDelta, + MovedDelta, + TextDiffDelta, +} from '../types'; export const diffFilter: Filter = function trivialMatchesDiffFilter(context) { @@ -57,34 +65,43 @@ export const diffFilter: Filter = }; diffFilter.filterName = 'trivial'; -export const patchFilter = function trivialMatchesPatchFilter(context) { - if (typeof context.delta === 'undefined') { - context.setResult(context.left).exit(); - return; - } - context.nested = !Array.isArray(context.delta); - if (context.nested) { - return; - } - if (context.delta.length === 1) { - context.setResult(context.delta[0]).exit(); - return; - } - if (context.delta.length === 2) { - if (context.left instanceof RegExp) { - const regexArgs = /^\/(.*)\/([gimyu]+)$/.exec(context.delta[1]); - if (regexArgs) { - context.setResult(new RegExp(regexArgs[1], regexArgs[2])).exit(); - return; +export const patchFilter: Filter = + function trivialMatchesPatchFilter(context) { + if (typeof context.delta === 'undefined') { + context.setResult(context.left).exit(); + return; + } + context.nested = !Array.isArray(context.delta); + if (context.nested) { + return; + } + const nonNestedDelta = context.delta as + | AddedDelta + | ModifiedDelta + | DeletedDelta + | MovedDelta + | TextDiffDelta; + if (nonNestedDelta.length === 1) { + context.setResult(nonNestedDelta[0]).exit(); + return; + } + if (nonNestedDelta.length === 2) { + if (context.left instanceof RegExp) { + const regexArgs = /^\/(.*)\/([gimyu]+)$/.exec( + nonNestedDelta[1] as string, + ); + if (regexArgs) { + context.setResult(new RegExp(regexArgs[1], regexArgs[2])).exit(); + return; + } } + context.setResult(nonNestedDelta[1]).exit(); + return; } - context.setResult(context.delta[1]).exit(); - return; - } - if (context.delta.length === 3 && context.delta[2] === 0) { - context.setResult(undefined).exit(); - } -}; + if (nonNestedDelta.length === 3 && nonNestedDelta[2] === 0) { + context.setResult(undefined).exit(); + } + }; patchFilter.filterName = 'trivial'; export const reverseFilter = function trivialReferseFilter(context) { diff --git a/src/types.ts b/src/types.ts index 26b9ad1f..738a5820 100644 --- a/src/types.ts +++ b/src/types.ts @@ -24,7 +24,9 @@ export interface ObjectDelta { export interface ArrayDelta { _t: 'a'; - [index: number | `_${number}`]: Delta; + [index: number]: Delta; + [index: `${number}`]: Delta; + [index: `_${number}`]: DeletedDelta | MovedDelta; } export type MovedDelta = [unknown, number, 3]; From 0025f1072c450035c44c43e4096df15d5fe6819e Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Mon, 4 Sep 2023 22:02:15 -0400 Subject: [PATCH 07/19] Reverse filters --- src/contexts/reverse.ts | 3 ++ src/filters/arrays.ts | 104 ++++++++++++++++++++++++---------------- src/filters/dates.ts | 2 +- src/filters/nested.ts | 52 +++++++++++--------- src/filters/texts.ts | 37 +++++++++----- src/filters/trivial.ts | 52 +++++++++++--------- src/pipe.ts | 6 +-- src/processor.ts | 4 +- src/types.ts | 9 +++- 9 files changed, 159 insertions(+), 110 deletions(-) diff --git a/src/contexts/reverse.ts b/src/contexts/reverse.ts index 53124ca6..0d91bc16 100644 --- a/src/contexts/reverse.ts +++ b/src/contexts/reverse.ts @@ -5,6 +5,9 @@ class ReverseContext extends Context { delta: Delta; pipe: 'reverse'; + nested?: boolean; + newName?: `_${number}`; + constructor(delta: Delta) { super(); this.delta = delta; diff --git a/src/filters/arrays.ts b/src/filters/arrays.ts index 13796113..ff8d4dd8 100644 --- a/src/filters/arrays.ts +++ b/src/filters/arrays.ts @@ -3,14 +3,17 @@ import PatchContext from '../contexts/patch'; import ReverseContext from '../contexts/reverse'; import lcs from './lcs'; -import type { Filter } from '../pipe'; + import type { AddedDelta, ArrayDelta, DeletedDelta, Delta, + Filter, + ModifiedDelta, MovedDelta, ObjectDelta, + TextDiffDelta, } from '../types'; const ARRAY_MOVE = 3; @@ -399,50 +402,64 @@ export const collectChildrenPatchFilter: Filter = }; collectChildrenPatchFilter.filterName = 'arraysCollectChildren'; -export const reverseFilter = function arraysReverseFilter(context) { - if (!context.nested) { - if (context.delta[2] === ARRAY_MOVE) { - context.newName = `_${context.delta[1]}`; - context - .setResult([ - context.delta[0], - parseInt(context.childName.substring(1), 10), - ARRAY_MOVE, - ]) - .exit(); +export const reverseFilter: Filter = + function arraysReverseFilter(context) { + if (!context.nested) { + const nonNestedDelta = context.delta as + | AddedDelta + | ModifiedDelta + | DeletedDelta + | MovedDelta + | TextDiffDelta; + if (nonNestedDelta[2] === ARRAY_MOVE) { + const arrayMoveDelta = nonNestedDelta as MovedDelta; + context.newName = `_${arrayMoveDelta[1]}`; + context + .setResult([ + arrayMoveDelta[0], + parseInt((context.childName as `_${number}`).substring(1), 10), + ARRAY_MOVE, + ]) + .exit(); + } + return; } - return; - } - if (context.delta._t !== 'a') { - return; - } - let name; - let child; - for (name in context.delta) { - if (name === '_t') { - continue; + const nestedDelta = context.delta as ObjectDelta | ArrayDelta; + if (nestedDelta._t !== 'a') { + return; } - child = new ReverseContext(context.delta[name]); - context.push(child, name); - } - context.exit(); -}; + const arrayDelta = nestedDelta as ArrayDelta; + let name; + let child; + for (name in arrayDelta) { + if (name === '_t') { + continue; + } + child = new ReverseContext(arrayDelta[name as `${number}`]); + context.push(child, name); + } + context.exit(); + }; reverseFilter.filterName = 'arrays'; -const reverseArrayDeltaIndex = (delta, index, itemDelta) => { +const reverseArrayDeltaIndex = ( + delta: ArrayDelta, + index: string | number, + itemDelta: Delta, +) => { if (typeof index === 'string' && index[0] === '_') { return parseInt(index.substring(1), 10); } else if (Array.isArray(itemDelta) && itemDelta[2] === 0) { - return `_${index}`; + return `_${index as number}` as const; } let reverseIndex = +index; for (const deltaIndex in delta) { - const deltaItem = delta[deltaIndex]; + const deltaItem = delta[deltaIndex as `${number}` | `_${number}`]; if (Array.isArray(deltaItem)) { if (deltaItem[2] === ARRAY_MOVE) { const moveFromIndex = parseInt(deltaIndex.substring(1), 10); - const moveToIndex = deltaItem[1]; + const moveToIndex = (deltaItem as MovedDelta)[1]; if (moveToIndex === +index) { return moveFromIndex; } @@ -459,7 +476,10 @@ const reverseArrayDeltaIndex = (delta, index, itemDelta) => { if (deleteIndex <= reverseIndex) { reverseIndex++; } - } else if (deltaItem.length === 1 && deltaIndex <= reverseIndex) { + } else if ( + deltaItem.length === 1 && + parseInt(deltaIndex, 10) <= reverseIndex + ) { reverseIndex--; } } @@ -468,33 +488,33 @@ const reverseArrayDeltaIndex = (delta, index, itemDelta) => { return reverseIndex; }; -export function collectChildrenReverseFilter(context) { +export const collectChildrenReverseFilter: Filter = ( + context, +) => { if (!context || !context.children) { return; } - if (context.delta._t !== 'a') { + const deltaWithChildren = context.delta as ObjectDelta | ArrayDelta; + if (deltaWithChildren._t !== 'a') { return; } + const arrayDelta = deltaWithChildren as ArrayDelta; const length = context.children.length; let child; - const delta = { + const delta: ArrayDelta = { _t: 'a', }; for (let index = 0; index < length; index++) { child = context.children[index]; - let name = child.newName; + let name: `_${number}` | number = child.newName!; if (typeof name === 'undefined') { - name = reverseArrayDeltaIndex( - context.delta, - child.childName, - child.result, - ); + name = reverseArrayDeltaIndex(arrayDelta, child.childName!, child.result); } if (delta[name] !== child.result) { delta[name] = child.result; } } context.setResult(delta).exit(); -} +}; collectChildrenReverseFilter.filterName = 'arraysCollectChildren'; diff --git a/src/filters/dates.ts b/src/filters/dates.ts index 3702d702..d82ff250 100644 --- a/src/filters/dates.ts +++ b/src/filters/dates.ts @@ -1,4 +1,4 @@ -import type { Filter } from '../pipe'; +import type { Filter } from '../types'; import type DiffContext from '../contexts/diff'; export const diffFilter: Filter = function datesDiffFilter( diff --git a/src/filters/nested.ts b/src/filters/nested.ts index 6888238a..3cf184b5 100644 --- a/src/filters/nested.ts +++ b/src/filters/nested.ts @@ -1,8 +1,7 @@ import DiffContext from '../contexts/diff'; import PatchContext from '../contexts/patch'; import ReverseContext from '../contexts/reverse'; -import type { Filter } from '../pipe'; -import type { ArrayDelta, Delta, ObjectDelta } from '../types'; +import type { ArrayDelta, Delta, Filter, ObjectDelta } from '../types'; export const collectChildrenDiffFilter: Filter = (context) => { if (!context || !context.children) { @@ -120,39 +119,46 @@ export const collectChildrenPatchFilter: Filter = }; collectChildrenPatchFilter.filterName = 'collectChildren'; -export const reverseFilter = function nestedReverseFilter(context) { - if (!context.nested) { - return; - } - if (context.delta._t) { - return; - } - let name; - let child; - for (name in context.delta) { - child = new ReverseContext(context.delta[name]); - context.push(child, name); - } - context.exit(); -}; +export const reverseFilter: Filter = + function nestedReverseFilter(context) { + if (!context.nested) { + return; + } + const nestedDelta = context.delta as ObjectDelta | ArrayDelta; + if (nestedDelta._t) { + return; + } + const objectDelta = context.delta as ObjectDelta; + let name; + let child; + for (name in objectDelta) { + child = new ReverseContext(objectDelta[name]); + context.push(child, name); + } + context.exit(); + }; reverseFilter.filterName = 'objects'; -export function collectChildrenReverseFilter(context) { +export const collectChildrenReverseFilter: Filter = ( + context, +) => { if (!context || !context.children) { return; } - if (context.delta._t) { + const deltaWithChildren = context.delta as ObjectDelta | ArrayDelta; + if (deltaWithChildren._t) { return; } const length = context.children.length; let child; - const delta = {}; + const delta: ObjectDelta = {}; for (let index = 0; index < length; index++) { child = context.children[index]; - if (delta[child.childName] !== child.result) { - delta[child.childName] = child.result; + const property = child.childName as string; + if (delta[property] !== child.result) { + delta[property] = child.result; } } context.setResult(delta).exit(); -} +}; collectChildrenReverseFilter.filterName = 'collectChildren'; diff --git a/src/filters/texts.ts b/src/filters/texts.ts index 04b34856..ca395603 100644 --- a/src/filters/texts.ts +++ b/src/filters/texts.ts @@ -1,10 +1,11 @@ import dmp from 'diff-match-patch'; -import type { Filter } from '../pipe'; import type DiffContext from '../contexts/diff'; import type PatchContext from '../contexts/patch'; +import type ReverseContext from '../contexts/reverse'; import type { AddedDelta, DeletedDelta, + Filter, ModifiedDelta, MovedDelta, TextDiffDelta, @@ -129,7 +130,7 @@ export const patchFilter: Filter = function textsPatchFilter( }; patchFilter.filterName = 'texts'; -const textDeltaReverse = function (delta) { +const textDeltaReverse = function (delta: string) { let i; let l; let line; @@ -142,7 +143,7 @@ const textDeltaReverse = function (delta) { line = lines[i]; const lineStart = line.slice(0, 1); if (lineStart === '@') { - header = headerRegex.exec(line); + header = headerRegex.exec(line)!; lineHeader = i; // fix header @@ -171,15 +172,25 @@ const textDeltaReverse = function (delta) { return lines.join('\n'); }; -export const reverseFilter = function textsReverseFilter(context) { - if (context.nested) { - return; - } - if (context.delta[2] !== TEXT_DIFF) { - return; - } +export const reverseFilter: Filter = + function textsReverseFilter(context) { + if (context.nested) { + return; + } + const nonNestedDelta = context.delta as + | AddedDelta + | ModifiedDelta + | DeletedDelta + | MovedDelta + | TextDiffDelta; + if (nonNestedDelta[2] !== TEXT_DIFF) { + return; + } + const textDiffDelta = nonNestedDelta as TextDiffDelta; - // text-diff, use a text-diff algorithm - context.setResult([textDeltaReverse(context.delta[0]), 0, TEXT_DIFF]).exit(); -}; + // text-diff, use a text-diff algorithm + context + .setResult([textDeltaReverse(textDiffDelta[0]), 0, TEXT_DIFF]) + .exit(); + }; reverseFilter.filterName = 'texts'; diff --git a/src/filters/trivial.ts b/src/filters/trivial.ts index 7741dfd5..205e4404 100644 --- a/src/filters/trivial.ts +++ b/src/filters/trivial.ts @@ -1,9 +1,10 @@ -import type { Filter } from '../pipe'; import type DiffContext from '../contexts/diff'; import type PatchContext from '../contexts/patch'; +import type ReverseContext from '../contexts/reverse'; import type { AddedDelta, DeletedDelta, + Filter, ModifiedDelta, MovedDelta, TextDiffDelta, @@ -104,25 +105,32 @@ export const patchFilter: Filter = }; patchFilter.filterName = 'trivial'; -export const reverseFilter = function trivialReferseFilter(context) { - if (typeof context.delta === 'undefined') { - context.setResult(context.delta).exit(); - return; - } - context.nested = !Array.isArray(context.delta); - if (context.nested) { - return; - } - if (context.delta.length === 1) { - context.setResult([context.delta[0], 0, 0]).exit(); - return; - } - if (context.delta.length === 2) { - context.setResult([context.delta[1], context.delta[0]]).exit(); - return; - } - if (context.delta.length === 3 && context.delta[2] === 0) { - context.setResult([context.delta[0]]).exit(); - } -}; +export const reverseFilter: Filter = + function trivialReferseFilter(context) { + if (typeof context.delta === 'undefined') { + context.setResult(context.delta).exit(); + return; + } + context.nested = !Array.isArray(context.delta); + if (context.nested) { + return; + } + const nonNestedDelta = context.delta as + | AddedDelta + | ModifiedDelta + | DeletedDelta + | MovedDelta + | TextDiffDelta; + if (nonNestedDelta.length === 1) { + context.setResult([nonNestedDelta[0], 0, 0]).exit(); + return; + } + if (nonNestedDelta.length === 2) { + context.setResult([nonNestedDelta[1], nonNestedDelta[0]]).exit(); + return; + } + if (nonNestedDelta.length === 3 && nonNestedDelta[2] === 0) { + context.setResult([nonNestedDelta[0]]).exit(); + } + }; reverseFilter.filterName = 'trivial'; diff --git a/src/pipe.ts b/src/pipe.ts index c77f6193..9e1fbf41 100644 --- a/src/pipe.ts +++ b/src/pipe.ts @@ -1,10 +1,6 @@ import type Context from './contexts/context'; import type Processor from './processor'; - -export interface Filter> { - (context: TContext): void; - filterName: string; -} +import type { Filter } from './types'; class Pipe> { name: string; diff --git a/src/processor.ts b/src/processor.ts index 5d178d39..dbd5e437 100644 --- a/src/processor.ts +++ b/src/processor.ts @@ -1,6 +1,6 @@ -import type { Options } from './types'; -import type Pipe from './pipe'; import type Context from './contexts/context'; +import type Pipe from './pipe'; +import type { Options } from './types'; class Processor { selfOptions: Options; diff --git a/src/types.ts b/src/types.ts index 738a5820..93cb9377 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,4 @@ +import type Context from './contexts/context'; import type DiffContext from './contexts/diff'; export interface Options { @@ -24,8 +25,7 @@ export interface ObjectDelta { export interface ArrayDelta { _t: 'a'; - [index: number]: Delta; - [index: `${number}`]: Delta; + [index: number | `${number}`]: Delta; [index: `_${number}`]: DeletedDelta | MovedDelta; } @@ -42,3 +42,8 @@ export type Delta = | MovedDelta | TextDiffDelta | undefined; + +export interface Filter> { + (context: TContext): void; + filterName: string; +} From 789aa63742da254a94970593c30c527046e669a3 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Mon, 4 Sep 2023 22:08:27 -0400 Subject: [PATCH 08/19] Add bad type cast --- src/filters/arrays.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/filters/arrays.ts b/src/filters/arrays.ts index ff8d4dd8..b77abbbd 100644 --- a/src/filters/arrays.ts +++ b/src/filters/arrays.ts @@ -512,7 +512,8 @@ export const collectChildrenReverseFilter: Filter = ( name = reverseArrayDeltaIndex(arrayDelta, child.childName!, child.result); } if (delta[name] !== child.result) { - delta[name] = child.result; + // TODO Is this right and, if so, how should it be expressed? + delta[name] = child.result as DeletedDelta | MovedDelta; } } context.setResult(delta).exit(); From 7689b792d9fa93a7f747a162078bfca0c827f4bc Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Mon, 4 Sep 2023 22:23:27 -0400 Subject: [PATCH 09/19] Lie --- src/filters/arrays.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/filters/arrays.ts b/src/filters/arrays.ts index b77abbbd..e923c7db 100644 --- a/src/filters/arrays.ts +++ b/src/filters/arrays.ts @@ -512,8 +512,8 @@ export const collectChildrenReverseFilter: Filter = ( name = reverseArrayDeltaIndex(arrayDelta, child.childName!, child.result); } if (delta[name] !== child.result) { - // TODO Is this right and, if so, how should it be expressed? - delta[name] = child.result as DeletedDelta | MovedDelta; + // There's no way to type this well. + delta[name as number] = child.result; } } context.setResult(delta).exit(); From fe4f5aa3d488bb214a53ba301e63345c3cdfaf96 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 5 Sep 2023 09:32:18 -0400 Subject: [PATCH 10/19] Type jsonpatch formatter --- src/formatters/base.js | 260 --------------------- src/formatters/base.ts | 454 ++++++++++++++++++++++++++++++++++++ src/formatters/jsonpatch.js | 180 -------------- src/formatters/jsonpatch.ts | 235 +++++++++++++++++++ 4 files changed, 689 insertions(+), 440 deletions(-) delete mode 100644 src/formatters/base.js create mode 100644 src/formatters/base.ts delete mode 100644 src/formatters/jsonpatch.js create mode 100644 src/formatters/jsonpatch.ts diff --git a/src/formatters/base.js b/src/formatters/base.js deleted file mode 100644 index be1e4a45..00000000 --- a/src/formatters/base.js +++ /dev/null @@ -1,260 +0,0 @@ -const isArray = - typeof Array.isArray === 'function' - ? Array.isArray - : (a) => a instanceof Array; - -const getObjectKeys = - typeof Object.keys === 'function' - ? (obj) => Object.keys(obj) - : (obj) => { - const names = []; - for (const property in obj) { - if (Object.prototype.hasOwnProperty.call(obj, property)) { - names.push(property); - } - } - return names; - }; - -const trimUnderscore = (str) => { - if (str.substring(0, 1) === '_') { - return str.slice(1); - } - return str; -}; - -const arrayKeyToSortNumber = (key) => { - if (key === '_t') { - return -1; - } else { - if (key.substring(0, 1) === '_') { - return parseInt(key.slice(1), 10); - } else { - return parseInt(key, 10) + 0.1; - } - } -}; - -const arrayKeyComparer = (key1, key2) => - arrayKeyToSortNumber(key1) - arrayKeyToSortNumber(key2); - -class BaseFormatter { - format(delta, left) { - const context = {}; - this.prepareContext(context); - this.recurse(context, delta, left); - return this.finalize(context); - } - - prepareContext(context) { - context.buffer = []; - context.out = function (...args) { - this.buffer.push(...args); - }; - } - - typeFormattterNotFound(context, deltaType) { - throw new Error(`cannot format delta type: ${deltaType}`); - } - - typeFormattterErrorFormatter(context, err) { - return err.toString(); - } - - finalize({ buffer }) { - if (isArray(buffer)) { - return buffer.join(''); - } - } - - recurse(context, delta, left, key, leftKey, movedFrom, isLast) { - const useMoveOriginHere = delta && movedFrom; - const leftValue = useMoveOriginHere ? movedFrom.value : left; - - if (typeof delta === 'undefined' && typeof key === 'undefined') { - return undefined; - } - - const type = this.getDeltaType(delta, movedFrom); - const nodeType = - type === 'node' ? (delta._t === 'a' ? 'array' : 'object') : ''; - - if (typeof key !== 'undefined') { - this.nodeBegin(context, key, leftKey, type, nodeType, isLast); - } else { - this.rootBegin(context, type, nodeType); - } - - let typeFormattter; - try { - typeFormattter = - this[`format_${type}`] || this.typeFormattterNotFound(context, type); - typeFormattter.call( - this, - context, - delta, - leftValue, - key, - leftKey, - movedFrom, - ); - } catch (err) { - this.typeFormattterErrorFormatter( - context, - err, - delta, - leftValue, - key, - leftKey, - movedFrom, - ); - if (typeof console !== 'undefined' && console.error) { - console.error(err.stack); - } - } - - if (typeof key !== 'undefined') { - this.nodeEnd(context, key, leftKey, type, nodeType, isLast); - } else { - this.rootEnd(context, type, nodeType); - } - } - - formatDeltaChildren(context, delta, left) { - const self = this; - this.forEachDeltaKey(delta, left, (key, leftKey, movedFrom, isLast) => { - self.recurse( - context, - delta[key], - left ? left[leftKey] : undefined, - key, - leftKey, - movedFrom, - isLast, - ); - }); - } - - forEachDeltaKey(delta, left, fn) { - const keys = getObjectKeys(delta); - const arrayKeys = delta._t === 'a'; - const moveDestinations = {}; - let name; - if (typeof left !== 'undefined') { - for (name in left) { - if (Object.prototype.hasOwnProperty.call(left, name)) { - if ( - typeof delta[name] === 'undefined' && - (!arrayKeys || typeof delta[`_${name}`] === 'undefined') - ) { - keys.push(name); - } - } - } - } - // look for move destinations - for (name in delta) { - if (Object.prototype.hasOwnProperty.call(delta, name)) { - const value = delta[name]; - if (isArray(value) && value[2] === 3) { - moveDestinations[value[1].toString()] = { - key: name, - value: left && left[parseInt(name.substring(1))], - }; - if (this.includeMoveDestinations !== false) { - if ( - typeof left === 'undefined' && - typeof delta[value[1]] === 'undefined' - ) { - keys.push(value[1].toString()); - } - } - } - } - } - if (arrayKeys) { - keys.sort(arrayKeyComparer); - } else { - keys.sort(); - } - for (let index = 0, length = keys.length; index < length; index++) { - const key = keys[index]; - if (arrayKeys && key === '_t') { - continue; - } - const leftKey = arrayKeys ? parseInt(trimUnderscore(key), 10) : key; - const isLast = index === length - 1; - fn(key, leftKey, moveDestinations[leftKey], isLast); - } - } - - getDeltaType(delta, movedFrom) { - if (typeof delta === 'undefined') { - if (typeof movedFrom !== 'undefined') { - return 'movedestination'; - } - return 'unchanged'; - } - if (isArray(delta)) { - if (delta.length === 1) { - return 'added'; - } - if (delta.length === 2) { - return 'modified'; - } - if (delta.length === 3 && delta[2] === 0) { - return 'deleted'; - } - if (delta.length === 3 && delta[2] === 2) { - return 'textdiff'; - } - if (delta.length === 3 && delta[2] === 3) { - return 'moved'; - } - } else if (typeof delta === 'object') { - return 'node'; - } - return 'unknown'; - } - - parseTextDiff(value) { - const output = []; - const lines = value.split('\n@@ '); - for (let i = 0, l = lines.length; i < l; i++) { - const line = lines[i]; - const lineOutput = { - pieces: [], - }; - const location = /^(?:@@ )?[-+]?(\d+),(\d+)/.exec(line).slice(1); - lineOutput.location = { - line: location[0], - chr: location[1], - }; - const pieces = line.split('\n').slice(1); - for ( - let pieceIndex = 0, piecesLength = pieces.length; - pieceIndex < piecesLength; - pieceIndex++ - ) { - const piece = pieces[pieceIndex]; - if (!piece.length) { - continue; - } - const pieceOutput = { - type: 'context', - }; - if (piece.substring(0, 1) === '+') { - pieceOutput.type = 'added'; - } else if (piece.substring(0, 1) === '-') { - pieceOutput.type = 'deleted'; - } - pieceOutput.text = piece.slice(1); - lineOutput.pieces.push(pieceOutput); - } - output.push(lineOutput); - } - return output; - } -} - -export default BaseFormatter; diff --git a/src/formatters/base.ts b/src/formatters/base.ts new file mode 100644 index 00000000..0aad6207 --- /dev/null +++ b/src/formatters/base.ts @@ -0,0 +1,454 @@ +import type { + AddedDelta, + ArrayDelta, + DeletedDelta, + Delta, + ModifiedDelta, + MovedDelta, + ObjectDelta, + TextDiffDelta, +} from '../types'; + +const trimUnderscore = (str: string) => { + if (str.substring(0, 1) === '_') { + return str.slice(1); + } + return str; +}; + +const arrayKeyToSortNumber = (key: string) => { + if (key === '_t') { + return -1; + } else { + if (key.substring(0, 1) === '_') { + return parseInt(key.slice(1), 10); + } else { + return parseInt(key, 10) + 0.1; + } + } +}; + +const arrayKeyComparer = (key1: string, key2: string) => + arrayKeyToSortNumber(key1) - arrayKeyToSortNumber(key2); + +export interface BaseFormatterContext { + buffer: string[]; + out: (...args: string[]) => void; +} + +export type DeltaType = + | 'movedestination' + | 'unchanged' + | 'added' + | 'modified' + | 'deleted' + | 'textdiff' + | 'moved' + | 'node' + | 'unknown'; + +export type NodeType = 'array' | 'object' | ''; + +interface DeltaTypeMap { + movedestination: undefined; + unchanged: undefined; + added: AddedDelta; + modified: ModifiedDelta; + deleted: DeletedDelta; + textdiff: TextDiffDelta; + moved: MovedDelta; + node: ObjectDelta | ArrayDelta; +} + +interface MoveDestination { + key: `_${number}`; + value: unknown; +} + +type Formatter = { + [TDeltaType in keyof DeltaTypeMap as `format_${keyof DeltaTypeMap}`]: ( + context: TContext, + delta: DeltaTypeMap[TDeltaType], + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ) => void; +}; + +abstract class BaseFormatter< + TContext extends BaseFormatterContext, + TFormatted = string | undefined, +> { + includeMoveDestinations?: boolean; + + format(delta: Delta, left: unknown): TFormatted { + const context: Partial = {}; + this.prepareContext(context); + const preparedContext = context as TContext; + this.recurse(preparedContext, delta, left); + return this.finalize(preparedContext) as TFormatted; + } + + prepareContext(context: Partial) { + context.buffer = []; + context.out = function (...args) { + this.buffer!.push(...args); + }; + } + + typeFormattterNotFound(context: TContext, deltaType: 'unknown'): never { + throw new Error(`cannot format delta type: ${deltaType}`); + } + + /* eslint-disable @typescript-eslint/no-unused-vars */ + typeFormattterErrorFormatter( + context: TContext, + err: unknown, + delta: Delta, + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ) {} + /* eslint-enable @typescript-eslint/no-unused-vars */ + + finalize({ buffer }: TContext) { + if (Array.isArray(buffer)) { + return buffer.join(''); + } + } + + recurse( + context: TContext, + delta: DeltaTypeMap[TDeltaType], + left: unknown, + key?: string, + leftKey?: string | number, + movedFrom?: MoveDestination | undefined, + isLast?: boolean, + ) { + const useMoveOriginHere = delta && movedFrom; + const leftValue = useMoveOriginHere ? movedFrom.value : left; + + if (typeof delta === 'undefined' && typeof key === 'undefined') { + return undefined; + } + + const type = this.getDeltaType(delta, movedFrom); + const nodeType = + type === 'node' + ? (delta as ArrayDelta)._t === 'a' + ? 'array' + : 'object' + : ''; + + if (typeof key !== 'undefined') { + this.nodeBegin(context, key, leftKey!, type, nodeType, isLast!); + } else { + this.rootBegin(context, type, nodeType); + } + + let typeFormattter: + | (( + context: TContext, + delta: DeltaTypeMap[TDeltaType], + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ) => void) + | undefined; + try { + typeFormattter = + type !== 'unknown' + ? (this as Formatter)[`format_${type}`] + : this.typeFormattterNotFound(context, type); + typeFormattter.call( + this, + context, + delta, + leftValue, + key, + leftKey, + movedFrom, + ); + } catch (err) { + this.typeFormattterErrorFormatter( + context, + err, + delta, + leftValue, + key, + leftKey, + movedFrom, + ); + if (typeof console !== 'undefined' && console.error) { + console.error((err as Error).stack); + } + } + + if (typeof key !== 'undefined') { + this.nodeEnd(context, key, leftKey!, type, nodeType, isLast!); + } else { + this.rootEnd(context, type, nodeType); + } + } + + formatDeltaChildren( + context: TContext, + delta: ObjectDelta | ArrayDelta, + left: unknown, + ) { + this.forEachDeltaKey(delta, left, (key, leftKey, movedFrom, isLast) => { + this.recurse( + context, + (delta as Record)[key], + left ? (left as Record)[leftKey] : undefined, + key, + leftKey, + movedFrom, + isLast, + ); + }); + } + + forEachDeltaKey( + delta: ObjectDelta | ArrayDelta, + left: unknown, + fn: ( + key: string, + leftKey: string | number, + moveDestination: MoveDestination | undefined, + isLast: boolean, + ) => void, + ) { + const keys = Object.keys(delta); + const arrayKeys = delta._t === 'a'; + const moveDestinations: { + [index: string | number]: MoveDestination | undefined; + } = {}; + let name; + if (typeof left !== 'undefined') { + for (name in left) { + if (Object.prototype.hasOwnProperty.call(left, name)) { + if ( + typeof (delta as Record)[name] === 'undefined' && + (!arrayKeys || + typeof (delta as ArrayDelta)[`_${name}` as `_${number}`] === + 'undefined') + ) { + keys.push(name); + } + } + } + } + // look for move destinations + for (name in delta) { + if (Object.prototype.hasOwnProperty.call(delta, name)) { + const value = (delta as Record)[name]; + if (Array.isArray(value) && value[2] === 3) { + const movedDelta = value as MovedDelta; + moveDestinations[`${movedDelta[1]}`] = { + key: name as `_${number}`, + value: left && (left as unknown[])[parseInt(name.substring(1), 10)], + }; + if (this.includeMoveDestinations !== false) { + if ( + typeof left === 'undefined' && + typeof (delta as ArrayDelta)[movedDelta[1]] === 'undefined' + ) { + keys.push(movedDelta[1].toString()); + } + } + } + } + } + if (arrayKeys) { + keys.sort(arrayKeyComparer); + } else { + keys.sort(); + } + for (let index = 0, length = keys.length; index < length; index++) { + const key = keys[index]; + if (arrayKeys && key === '_t') { + continue; + } + const leftKey = arrayKeys ? parseInt(trimUnderscore(key), 10) : key; + const isLast = index === length - 1; + fn(key, leftKey, moveDestinations[leftKey], isLast); + } + } + + getDeltaType(delta: Delta, movedFrom: MoveDestination | undefined) { + if (typeof delta === 'undefined') { + if (typeof movedFrom !== 'undefined') { + return 'movedestination'; + } + return 'unchanged'; + } + if (Array.isArray(delta)) { + if (delta.length === 1) { + return 'added'; + } + if (delta.length === 2) { + return 'modified'; + } + if (delta.length === 3 && delta[2] === 0) { + return 'deleted'; + } + if (delta.length === 3 && delta[2] === 2) { + return 'textdiff'; + } + if (delta.length === 3 && delta[2] === 3) { + return 'moved'; + } + } else if (typeof delta === 'object') { + return 'node'; + } + return 'unknown'; + } + + parseTextDiff(value) { + const output = []; + const lines = value.split('\n@@ '); + for (let i = 0, l = lines.length; i < l; i++) { + const line = lines[i]; + const lineOutput = { + pieces: [], + }; + const location = /^(?:@@ )?[-+]?(\d+),(\d+)/.exec(line).slice(1); + lineOutput.location = { + line: location[0], + chr: location[1], + }; + const pieces = line.split('\n').slice(1); + for ( + let pieceIndex = 0, piecesLength = pieces.length; + pieceIndex < piecesLength; + pieceIndex++ + ) { + const piece = pieces[pieceIndex]; + if (!piece.length) { + continue; + } + const pieceOutput = { + type: 'context', + }; + if (piece.substring(0, 1) === '+') { + pieceOutput.type = 'added'; + } else if (piece.substring(0, 1) === '-') { + pieceOutput.type = 'deleted'; + } + pieceOutput.text = piece.slice(1); + lineOutput.pieces.push(pieceOutput); + } + output.push(lineOutput); + } + return output; + } + + abstract rootBegin( + context: TContext, + type: DeltaType, + nodeType: NodeType, + ): void; + + abstract rootEnd( + context: TContext, + type: DeltaType, + nodeType: NodeType, + ): void; + + abstract nodeBegin( + context: TContext, + key: string, + leftKey: string | number, + type: DeltaType, + nodeType: NodeType, + isLast: boolean, + ): void; + + abstract nodeEnd( + context: TContext, + key: string, + leftKey: string | number, + type: DeltaType, + nodeType: NodeType, + isLast: boolean, + ): void; + + abstract format_unchanged( + context: TContext, + delta: undefined, + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ): void; + + abstract format_movedestination( + context: TContext, + delta: undefined, + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ): void; + + abstract format_node( + context: TContext, + delta: ObjectDelta | ArrayDelta, + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ): void; + + abstract format_added( + context: TContext, + delta: AddedDelta, + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ): void; + + abstract format_modified( + context: TContext, + delta: ModifiedDelta, + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ): void; + + abstract format_deleted( + context: TContext, + delta: DeletedDelta, + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ): void; + + abstract format_moved( + context: TContext, + delta: MovedDelta, + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ): void; + + abstract format_textdiff( + context: TContext, + delta: TextDiffDelta, + leftValue: unknown, + key: string | undefined, + leftKey: string | number | undefined, + movedFrom: MoveDestination | undefined, + ): void; +} + +export default BaseFormatter; diff --git a/src/formatters/jsonpatch.js b/src/formatters/jsonpatch.js deleted file mode 100644 index ebc28664..00000000 --- a/src/formatters/jsonpatch.js +++ /dev/null @@ -1,180 +0,0 @@ -import BaseFormatter from './base'; - -const OPERATIONS = { - add: 'add', - remove: 'remove', - replace: 'replace', - move: 'move', -}; - -class JSONFormatter extends BaseFormatter { - constructor() { - super(); - this.includeMoveDestinations = true; - } - - prepareContext(context) { - super.prepareContext(context); - context.result = []; - context.path = []; - context.pushCurrentOp = function (obj) { - const { op, value } = obj; - const val = { - op, - path: this.currentPath(), - }; - if (typeof value !== 'undefined') { - val.value = value; - } - this.result.push(val); - }; - - context.pushMoveOp = function (to) { - const from = this.currentPath(); - this.result.push({ - op: OPERATIONS.move, - from, - path: this.toPath(to), - }); - }; - - context.currentPath = function () { - return `/${this.path.join('/')}`; - }; - - context.toPath = function (toPath) { - const to = this.path.slice(); - to[to.length - 1] = toPath; - return `/${to.join('/')}`; - }; - } - - typeFormattterErrorFormatter(context, err) { - context.out(`[ERROR] ${err}`); - } - - rootBegin() {} - rootEnd() {} - - nodeBegin({ path }, key, leftKey) { - path.push(leftKey); - } - - nodeEnd({ path }) { - path.pop(); - } - - /* jshint camelcase: false */ - /* eslint-disable camelcase */ - - format_unchanged() {} - - format_movedestination() {} - - format_node(context, delta, left) { - this.formatDeltaChildren(context, delta, left); - } - - format_added(context, delta) { - context.pushCurrentOp({ op: OPERATIONS.add, value: delta[0] }); - } - - format_modified(context, delta) { - context.pushCurrentOp({ op: OPERATIONS.replace, value: delta[1] }); - } - - format_deleted(context) { - context.pushCurrentOp({ op: OPERATIONS.remove }); - } - - format_moved(context, delta) { - const to = delta[1]; - context.pushMoveOp(to); - } - - format_textdiff() { - throw new Error('Not implemented'); - } - - format(delta, left) { - const context = {}; - this.prepareContext(context); - this.recurse(context, delta, left); - return context.result; - } -} - -/* jshint camelcase: true */ -/* eslint-enable camelcase */ - -export default JSONFormatter; - -const last = (arr) => arr[arr.length - 1]; - -const sortBy = (arr, pred) => { - arr.sort(pred); - return arr; -}; - -const compareByIndexDesc = (indexA, indexB) => { - const lastA = parseInt(indexA, 10); - const lastB = parseInt(indexB, 10); - if (!(isNaN(lastA) || isNaN(lastB))) { - return lastB - lastA; - } else { - return 0; - } -}; - -const opsByDescendingOrder = (removeOps) => - sortBy(removeOps, (a, b) => { - const splitA = a.path.split('/'); - const splitB = b.path.split('/'); - if (splitA.length !== splitB.length) { - return splitA.length - splitB.length; - } else { - return compareByIndexDesc(last(splitA), last(splitB)); - } - }); - -export const partitionOps = (arr, fns) => { - const initArr = Array(fns.length + 1) - .fill() - .map(() => []); - return arr - .map((item) => { - let position = fns.map((fn) => fn(item)).indexOf(true); - if (position < 0) { - position = fns.length; - } - return { item, position }; - }) - .reduce((acc, item) => { - acc[item.position].push(item.item); - return acc; - }, initArr); -}; -const isMoveOp = ({ op }) => op === 'move'; -const isRemoveOp = ({ op }) => op === 'remove'; - -const reorderOps = (diff) => { - const [moveOps, removedOps, restOps] = partitionOps(diff, [ - isMoveOp, - isRemoveOp, - ]); - const removeOpsReverse = opsByDescendingOrder(removedOps); - return [...removeOpsReverse, ...moveOps, ...restOps]; -}; - -let defaultInstance; - -export const format = (delta, left) => { - if (!defaultInstance) { - defaultInstance = new JSONFormatter(); - } - return reorderOps(defaultInstance.format(delta, left)); -}; - -export const log = (delta, left) => { - console.log(format(delta, left)); -}; diff --git a/src/formatters/jsonpatch.ts b/src/formatters/jsonpatch.ts new file mode 100644 index 00000000..4d1ba835 --- /dev/null +++ b/src/formatters/jsonpatch.ts @@ -0,0 +1,235 @@ +import BaseFormatter from './base'; +import type { BaseFormatterContext } from './base'; +import type { + AddedDelta, + ArrayDelta, + Delta, + ModifiedDelta, + ObjectDelta, +} from '../types'; +import { MovedDelta } from '../types'; + +const OPERATIONS = { + add: 'add', + remove: 'remove', + replace: 'replace', + move: 'move', +} as const; + +interface AddOp { + op: 'add'; + path: string; + value: unknown; +} + +interface RemoveOp { + op: 'remove'; + path: string; +} + +interface ReplaceOp { + op: 'replace'; + path: string; + value: unknown; +} + +interface MoveOp { + op: 'move'; + from: string; + path: string; +} + +type Op = AddOp | RemoveOp | ReplaceOp | MoveOp; + +interface JSONFormatterContext extends BaseFormatterContext { + result: Op[]; + path: (string | number)[]; + pushCurrentOp: ( + obj: + | { op: 'add'; value: unknown } + | { op: 'remove' } + | { op: 'replace'; value: unknown }, + ) => void; + pushMoveOp: (to: number) => void; + currentPath: () => string; + toPath: (to: number) => string; +} + +class JSONFormatter extends BaseFormatter { + constructor() { + super(); + this.includeMoveDestinations = true; + } + + prepareContext(context: Partial) { + super.prepareContext(context); + context.result = []; + context.path = []; + context.pushCurrentOp = function (obj) { + if (obj.op === 'add' || obj.op === 'replace') { + this.result!.push({ + op: obj.op, + path: this.currentPath!(), + value: obj.value, + }); + } else if (obj.op === 'remove') { + this.result!.push({ op: obj.op, path: this.currentPath!() }); + } else { + obj satisfies never; + } + }; + + context.pushMoveOp = function (to) { + const from = this.currentPath!(); + this.result!.push({ + op: OPERATIONS.move, + from, + path: this.toPath!(to), + }); + }; + + context.currentPath = function () { + return `/${this.path!.join('/')}`; + }; + + context.toPath = function (toPath) { + const to = this.path!.slice(); + to[to.length - 1] = toPath; + return `/${to.join('/')}`; + }; + } + + typeFormattterErrorFormatter(context: JSONFormatterContext, err: unknown) { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + context.out(`[ERROR] ${err}`); + } + + rootBegin() {} + + rootEnd() {} + + nodeBegin( + { path }: JSONFormatterContext, + key: string, + leftKey: string | number, + ) { + path.push(leftKey); + } + + nodeEnd({ path }: JSONFormatterContext) { + path.pop(); + } + + format_unchanged() {} + + format_movedestination() {} + + format_node( + context: JSONFormatterContext, + delta: ObjectDelta | ArrayDelta, + left: unknown, + ) { + this.formatDeltaChildren(context, delta, left); + } + + format_added(context: JSONFormatterContext, delta: AddedDelta) { + context.pushCurrentOp({ op: OPERATIONS.add, value: delta[0] }); + } + + format_modified(context: JSONFormatterContext, delta: ModifiedDelta) { + context.pushCurrentOp({ op: OPERATIONS.replace, value: delta[1] }); + } + + format_deleted(context: JSONFormatterContext) { + context.pushCurrentOp({ op: OPERATIONS.remove }); + } + + format_moved(context: JSONFormatterContext, delta: MovedDelta) { + const to = delta[1]; + context.pushMoveOp(to); + } + + format_textdiff() { + throw new Error('Not implemented'); + } + + format(delta: Delta, left: unknown) { + const context = {}; + this.prepareContext(context); + const preparedContext = context as JSONFormatterContext; + this.recurse(preparedContext, delta, left); + return preparedContext.result; + } +} + +export default JSONFormatter; + +const last = (arr: T[]) => arr[arr.length - 1]; + +const sortBy = (arr: T[], pred: (a: T, b: T) => number) => { + arr.sort(pred); + return arr; +}; + +const compareByIndexDesc = (indexA: string, indexB: string) => { + const lastA = parseInt(indexA, 10); + const lastB = parseInt(indexB, 10); + if (!(isNaN(lastA) || isNaN(lastB))) { + return lastB - lastA; + } else { + return 0; + } +}; + +const opsByDescendingOrder = (removeOps: Op[]) => + sortBy(removeOps, (a, b) => { + const splitA = a.path.split('/'); + const splitB = b.path.split('/'); + if (splitA.length !== splitB.length) { + return splitA.length - splitB.length; + } else { + return compareByIndexDesc(last(splitA), last(splitB)); + } + }); + +export const partitionOps = (arr: Op[], fns: ((op: Op) => boolean)[]) => { + const initArr: Op[][] = Array(fns.length + 1) + .fill(undefined) + .map(() => []); + return arr + .map((item) => { + let position = fns.map((fn) => fn(item)).indexOf(true); + if (position < 0) { + position = fns.length; + } + return { item, position }; + }) + .reduce((acc, item) => { + acc[item.position].push(item.item); + return acc; + }, initArr); +}; +const isMoveOp = ({ op }: Op) => op === 'move'; +const isRemoveOp = ({ op }: Op) => op === 'remove'; + +const reorderOps = (diff: Op[]) => { + const [moveOps, removedOps, restOps] = partitionOps(diff, [ + isMoveOp, + isRemoveOp, + ]); + const removeOpsReverse = opsByDescendingOrder(removedOps); + return [...removeOpsReverse, ...moveOps, ...restOps]; +}; + +let defaultInstance: JSONFormatter | undefined; + +export const format = (delta: Delta, left: unknown) => { + if (!defaultInstance) { + defaultInstance = new JSONFormatter(); + } + return reorderOps(defaultInstance.format(delta, left)); +}; + +export const log = (delta: Delta, left: unknown) => { + console.log(format(delta, left)); +}; From b66419d646865b68ee71ad1d987bddc4273c9231 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 5 Sep 2023 21:12:57 -0400 Subject: [PATCH 11/19] Type annotated formatter --- src/formatters/{annotated.js => annotated.ts} | 174 ++++++++++++++---- src/formatters/base.ts | 32 +++- 2 files changed, 165 insertions(+), 41 deletions(-) rename src/formatters/{annotated.js => annotated.ts} (56%) diff --git a/src/formatters/annotated.js b/src/formatters/annotated.ts similarity index 56% rename from src/formatters/annotated.js rename to src/formatters/annotated.ts index 155cc832..d300fa50 100644 --- a/src/formatters/annotated.js +++ b/src/formatters/annotated.ts @@ -1,12 +1,30 @@ import BaseFormatter from './base'; +import type { BaseFormatterContext, DeltaType, NodeType } from './base'; +import type { + AddedDelta, + ArrayDelta, + DeletedDelta, + Delta, + ModifiedDelta, + MovedDelta, + ObjectDelta, + TextDiffDelta, +} from '../types'; -class AnnotatedFormatter extends BaseFormatter { +interface AnnotatedFormatterContext extends BaseFormatterContext { + indentLevel?: number; + indentPad?: string; + indent: (levels?: number) => void; + row: (json: string, htmlNote?: string) => void; +} + +class AnnotatedFormatter extends BaseFormatter { constructor() { super(); this.includeMoveDestinations = false; } - prepareContext(context) { + prepareContext(context: Partial) { super.prepareContext(context); context.indent = function (levels) { this.indentLevel = @@ -14,25 +32,29 @@ class AnnotatedFormatter extends BaseFormatter { this.indentPad = new Array(this.indentLevel + 1).join('  '); }; context.row = (json, htmlNote) => { - context.out( + context.out!( '' + '
',
       );
-      context.out(context.indentPad);
-      context.out('
');
-      context.out(json);
-      context.out('
'); - context.out(htmlNote); - context.out('
'); + context.out!(context.indentPad); + context.out!('
');
+      context.out!(json);
+      context.out!('
'); + context.out!(htmlNote); + context.out!('
'); }; } - typeFormattterErrorFormatter(context, err) { + typeFormattterErrorFormatter( + context: AnnotatedFormatterContext, + err: unknown, + ) { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions context.row('', `
${err}
`); } - formatTextDiffString(context, value) { + formatTextDiffString(context: AnnotatedFormatterContext, value: string) { const lines = this.parseTextDiff(value); context.out('
    '); for (let i = 0, l = lines.length; i < l; i++) { @@ -57,7 +79,11 @@ class AnnotatedFormatter extends BaseFormatter { context.out('
'); } - rootBegin(context, type, nodeType) { + rootBegin( + context: AnnotatedFormatterContext, + type: DeltaType, + nodeType: NodeType, + ) { context.out(''); if (type === 'node') { context.row('{'); @@ -71,7 +97,7 @@ class AnnotatedFormatter extends BaseFormatter { } } - rootEnd(context, type) { + rootEnd(context: AnnotatedFormatterContext, type: DeltaType) { if (type === 'node') { context.indent(-1); context.row('}'); @@ -79,7 +105,13 @@ class AnnotatedFormatter extends BaseFormatter { context.out('
'); } - nodeBegin(context, key, leftKey, type, nodeType) { + nodeBegin( + context: AnnotatedFormatterContext, + key: string, + leftKey: string | number, + type: DeltaType, + nodeType: NodeType, + ) { context.row(`"${key}": {`); if (type === 'node') { context.indent(); @@ -92,32 +124,103 @@ class AnnotatedFormatter extends BaseFormatter { } } - nodeEnd(context, key, leftKey, type, nodeType, isLast) { + nodeEnd( + context: AnnotatedFormatterContext, + key: string, + leftKey: string | number, + type: DeltaType, + nodeType: NodeType, + isLast: boolean, + ) { if (type === 'node') { context.indent(-1); } context.row(`}${isLast ? '' : ','}`); } - /* jshint camelcase: false */ - - /* eslint-disable camelcase */ format_unchanged() {} format_movedestination() {} - format_node(context, delta, left) { + format_node( + context: AnnotatedFormatterContext, + delta: ObjectDelta | ArrayDelta, + left: unknown, + ) { // recurse this.formatDeltaChildren(context, delta, left); } -} -/* eslint-enable camelcase */ + format_added( + context: AnnotatedFormatterContext, + delta: AddedDelta, + left: unknown, + key: string | undefined, + leftKey: string | number | undefined, + ) { + formatAnyChange.call(this, context, delta, left, key, leftKey); + } + + format_modified( + context: AnnotatedFormatterContext, + delta: ModifiedDelta, + left: unknown, + key: string | undefined, + leftKey: string | number | undefined, + ) { + formatAnyChange.call(this, context, delta, left, key, leftKey); + } + + format_deleted( + context: AnnotatedFormatterContext, + delta: DeletedDelta, + left: unknown, + key: string | undefined, + leftKey: string | number | undefined, + ) { + formatAnyChange.call(this, context, delta, left, key, leftKey); + } + + format_moved( + context: AnnotatedFormatterContext, + delta: MovedDelta, + left: unknown, + key: string | undefined, + leftKey: string | number | undefined, + ) { + formatAnyChange.call(this, context, delta, left, key, leftKey); + } -const wrapPropertyName = (name) => + format_textdiff( + context: AnnotatedFormatterContext, + delta: TextDiffDelta, + left: unknown, + key: string | undefined, + leftKey: string | number | undefined, + ) { + formatAnyChange.call(this, context, delta, left, key, leftKey); + } +} + +const wrapPropertyName = (name: string | number | undefined) => `
"${name}"
`; -const deltaAnnotations = { +interface DeltaTypeAnnotationsMap { + added: AddedDelta; + modified: ModifiedDelta; + deleted: DeletedDelta; + moved: MovedDelta; + textdiff: TextDiffDelta; +} + +const deltaAnnotations: { + [DeltaType in keyof DeltaTypeAnnotationsMap]: ( + delta: DeltaTypeAnnotationsMap[DeltaType], + left: unknown, + key: string | undefined, + leftKey: string | number | undefined, + ) => string; +} = { added(delta, left, key, leftKey) { const formatLegend = '
([newValue])
'; if (typeof leftKey === 'undefined') { @@ -169,12 +272,19 @@ const deltaAnnotations = { }, }; -const formatAnyChange = function (context, delta) { - const deltaType = this.getDeltaType(delta); +const formatAnyChange = function < + TDeltaType extends keyof DeltaTypeAnnotationsMap, +>( + this: AnnotatedFormatter, + context: AnnotatedFormatterContext, + delta: DeltaTypeAnnotationsMap[TDeltaType], + left: unknown, + key: string | undefined, + leftKey: string | number | undefined, +) { + const deltaType = this.getDeltaType(delta) as TDeltaType; const annotator = deltaAnnotations[deltaType]; - const htmlNote = - annotator && - annotator.apply(annotator, Array.prototype.slice.call(arguments, 1)); + const htmlNote = annotator && annotator(delta, left, key, leftKey); let json = JSON.stringify(delta, null, 2); if (deltaType === 'textdiff') { // split text diffs lines @@ -185,21 +295,17 @@ const formatAnyChange = function (context, delta) { context.indent(-1); }; -/* eslint-disable camelcase */ AnnotatedFormatter.prototype.format_added = formatAnyChange; AnnotatedFormatter.prototype.format_modified = formatAnyChange; AnnotatedFormatter.prototype.format_deleted = formatAnyChange; AnnotatedFormatter.prototype.format_moved = formatAnyChange; AnnotatedFormatter.prototype.format_textdiff = formatAnyChange; -/* eslint-enable camelcase */ - -/* jshint camelcase: true */ export default AnnotatedFormatter; -let defaultInstance; +let defaultInstance: AnnotatedFormatter | undefined; -export function format(delta, left) { +export function format(delta: Delta, left: unknown) { if (!defaultInstance) { defaultInstance = new AnnotatedFormatter(); } diff --git a/src/formatters/base.ts b/src/formatters/base.ts index 0aad6207..366c34d8 100644 --- a/src/formatters/base.ts +++ b/src/formatters/base.ts @@ -76,6 +76,21 @@ type Formatter = { ) => void; }; +interface LineOutputPiece { + type: 'context' | 'added' | 'deleted'; + text: string; +} + +interface LineOutputLocation { + line: string; + chr: string; +} + +interface LineOutput { + pieces: LineOutputPiece[]; + location: LineOutputLocation; +} + abstract class BaseFormatter< TContext extends BaseFormatterContext, TFormatted = string | undefined, @@ -280,7 +295,7 @@ abstract class BaseFormatter< } } - getDeltaType(delta: Delta, movedFrom: MoveDestination | undefined) { + getDeltaType(delta: Delta, movedFrom?: MoveDestination | undefined) { if (typeof delta === 'undefined') { if (typeof movedFrom !== 'undefined') { return 'movedestination'; @@ -309,15 +324,18 @@ abstract class BaseFormatter< return 'unknown'; } - parseTextDiff(value) { + parseTextDiff(value: string) { const output = []; const lines = value.split('\n@@ '); for (let i = 0, l = lines.length; i < l; i++) { const line = lines[i]; - const lineOutput = { + const lineOutput: { + pieces: LineOutputPiece[]; + location?: LineOutputLocation; + } = { pieces: [], }; - const location = /^(?:@@ )?[-+]?(\d+),(\d+)/.exec(line).slice(1); + const location = /^(?:@@ )?[-+]?(\d+),(\d+)/.exec(line)!.slice(1); lineOutput.location = { line: location[0], chr: location[1], @@ -332,7 +350,7 @@ abstract class BaseFormatter< if (!piece.length) { continue; } - const pieceOutput = { + const pieceOutput: Partial = { type: 'context', }; if (piece.substring(0, 1) === '+') { @@ -341,9 +359,9 @@ abstract class BaseFormatter< pieceOutput.type = 'deleted'; } pieceOutput.text = piece.slice(1); - lineOutput.pieces.push(pieceOutput); + lineOutput.pieces.push(pieceOutput as LineOutputPiece); } - output.push(lineOutput); + output.push(lineOutput as LineOutput); } return output; } From 8797f40b37f183c265b02fff9a96b06a443c9666 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 5 Sep 2023 21:51:38 -0400 Subject: [PATCH 12/19] Console formatter --- src/formatters/annotated.ts | 4 +- src/formatters/{console.js => console.ts} | 133 ++++++++++++++-------- 2 files changed, 88 insertions(+), 49 deletions(-) rename src/formatters/{console.js => console.ts} (56%) diff --git a/src/formatters/annotated.ts b/src/formatters/annotated.ts index d300fa50..e2317553 100644 --- a/src/formatters/annotated.ts +++ b/src/formatters/annotated.ts @@ -37,11 +37,11 @@ class AnnotatedFormatter extends BaseFormatter { '
',
       );
-      context.out!(context.indentPad);
+      if (context.indentPad != null) context.out!(context.indentPad);
       context.out!('
');
       context.out!(json);
       context.out!('
'); - context.out!(htmlNote); + if (htmlNote != null) context.out!(htmlNote); context.out!('
'); }; } diff --git a/src/formatters/console.js b/src/formatters/console.ts similarity index 56% rename from src/formatters/console.js rename to src/formatters/console.ts index 81e2b77e..c92cfef2 100644 --- a/src/formatters/console.js +++ b/src/formatters/console.ts @@ -1,41 +1,53 @@ import chalk from 'chalk'; import BaseFormatter from './base'; +import type { BaseFormatterContext, DeltaType, NodeType } from './base'; +import type { + AddedDelta, + ArrayDelta, + DeletedDelta, + Delta, + ModifiedDelta, + MovedDelta, + ObjectDelta, + TextDiffDelta, +} from '../types'; + +const colors: { [key: string]: chalk.Chalk | undefined } = { + added: chalk.green, + deleted: chalk.red, + movedestination: chalk.gray, + moved: chalk.yellow, + unchanged: chalk.gray, + error: chalk.white.bgRed, + textDiffLine: chalk.gray, +}; -function chalkColor(name) { - return ( - (chalk && chalk[name]) || - function (...args) { - return args; - } - ); +interface ConsoleFormatterContext extends BaseFormatterContext { + indentLevel?: number; + indentPad?: string; + outLine: () => void; + indent: (levels?: number) => void; + color?: (chalk.Chalk | undefined)[]; + pushColor: (color: chalk.Chalk | undefined) => void; + popColor: () => void; } -const colors = { - added: chalkColor('green'), - deleted: chalkColor('red'), - movedestination: chalkColor('gray'), - moved: chalkColor('yellow'), - unchanged: chalkColor('gray'), - error: chalkColor('white.bgRed'), - textDiffLine: chalkColor('gray'), -}; - -class ConsoleFormatter extends BaseFormatter { +class ConsoleFormatter extends BaseFormatter { constructor() { super(); this.includeMoveDestinations = false; } - prepareContext(context) { + prepareContext(context: Partial) { super.prepareContext(context); context.indent = function (levels) { this.indentLevel = (this.indentLevel || 0) + (typeof levels === 'undefined' ? 1 : levels); this.indentPad = new Array(this.indentLevel + 1).join(' '); - this.outLine(); + this.outLine!(); }; context.outLine = function () { - this.buffer.push(`\n${this.indentPad || ''}`); + this.buffer!.push(`\n${this.indentPad || ''}`); }; context.out = function (...args) { for (let i = 0, l = args.length; i < l; i++) { @@ -44,7 +56,7 @@ class ConsoleFormatter extends BaseFormatter { if (this.color && this.color[0]) { text = this.color[0](text); } - this.buffer.push(text); + this.buffer!.push(text); } }; context.pushColor = function (color) { @@ -57,17 +69,18 @@ class ConsoleFormatter extends BaseFormatter { }; } - typeFormattterErrorFormatter(context, err) { + typeFormattterErrorFormatter(context: ConsoleFormatterContext, err: unknown) { context.pushColor(colors.error); + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions context.out(`[ERROR]${err}`); context.popColor(); } - formatValue(context, value) { + formatValue(context: ConsoleFormatterContext, value: unknown) { context.out(JSON.stringify(value, null, 2)); } - formatTextDiffString(context, value) { + formatTextDiffString(context: ConsoleFormatterContext, value: string) { const lines = this.parseTextDiff(value); context.indent(); for (let i = 0, l = lines.length; i < l; i++) { @@ -93,7 +106,11 @@ class ConsoleFormatter extends BaseFormatter { context.indent(-1); } - rootBegin(context, type, nodeType) { + rootBegin( + context: ConsoleFormatterContext, + type: DeltaType, + nodeType: NodeType, + ) { context.pushColor(colors[type]); if (type === 'node') { context.out(nodeType === 'array' ? '[' : '{'); @@ -101,7 +118,11 @@ class ConsoleFormatter extends BaseFormatter { } } - rootEnd(context, type, nodeType) { + rootEnd( + context: ConsoleFormatterContext, + type: DeltaType, + nodeType: NodeType, + ) { if (type === 'node') { context.indent(-1); context.out(nodeType === 'array' ? ']' : '}'); @@ -109,7 +130,13 @@ class ConsoleFormatter extends BaseFormatter { context.popColor(); } - nodeBegin(context, key, leftKey, type, nodeType) { + nodeBegin( + context: ConsoleFormatterContext, + key: string, + leftKey: string | number, + type: DeltaType, + nodeType: NodeType, + ) { context.pushColor(colors[type]); context.out(`${leftKey}: `); if (type === 'node') { @@ -118,7 +145,14 @@ class ConsoleFormatter extends BaseFormatter { } } - nodeEnd(context, key, leftKey, type, nodeType, isLast) { + nodeEnd( + context: ConsoleFormatterContext, + key: string, + leftKey: string | number, + type: DeltaType, + nodeType: NodeType, + isLast: boolean, + ) { if (type === 'node') { context.indent(-1); context.out(nodeType === 'array' ? ']' : `}${isLast ? '' : ','}`); @@ -129,33 +163,42 @@ class ConsoleFormatter extends BaseFormatter { context.popColor(); } - /* jshint camelcase: false */ - /* eslint-disable camelcase */ - - format_unchanged(context, delta, left) { + format_unchanged( + context: ConsoleFormatterContext, + delta: undefined, + left: unknown, + ) { if (typeof left === 'undefined') { return; } this.formatValue(context, left); } - format_movedestination(context, delta, left) { + format_movedestination( + context: ConsoleFormatterContext, + delta: undefined, + left: unknown, + ) { if (typeof left === 'undefined') { return; } this.formatValue(context, left); } - format_node(context, delta, left) { + format_node( + context: ConsoleFormatterContext, + delta: ObjectDelta | ArrayDelta, + left: unknown, + ) { // recurse this.formatDeltaChildren(context, delta, left); } - format_added(context, delta) { + format_added(context: ConsoleFormatterContext, delta: AddedDelta) { this.formatValue(context, delta[0]); } - format_modified(context, delta) { + format_modified(context: ConsoleFormatterContext, delta: ModifiedDelta) { context.pushColor(colors.deleted); this.formatValue(context, delta[0]); context.popColor(); @@ -165,34 +208,30 @@ class ConsoleFormatter extends BaseFormatter { context.popColor(); } - format_deleted(context, delta) { + format_deleted(context: ConsoleFormatterContext, delta: DeletedDelta) { this.formatValue(context, delta[0]); } - format_moved(context, delta) { + format_moved(context: ConsoleFormatterContext, delta: MovedDelta) { context.out(`==> ${delta[1]}`); } - format_textdiff(context, delta) { + format_textdiff(context: ConsoleFormatterContext, delta: TextDiffDelta) { this.formatTextDiffString(context, delta[0]); } } -/* eslint-enable camelcase */ - -/* jshint camelcase: true */ - export default ConsoleFormatter; -let defaultInstance; +let defaultInstance: ConsoleFormatter | undefined; -export const format = (delta, left) => { +export const format = (delta: Delta, left: unknown) => { if (!defaultInstance) { defaultInstance = new ConsoleFormatter(); } return defaultInstance.format(delta, left); }; -export function log(delta, left) { +export function log(delta: Delta, left: unknown) { console.log(format(delta, left)); } From ba8be3cc2bbcf794ddeccba0f32602789c89897f Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 5 Sep 2023 22:03:18 -0400 Subject: [PATCH 13/19] HTML formatter --- src/formatters/{html.js => html.ts} | 128 +++++++++++++++++--------- src/formatters/{index.js => index.ts} | 0 2 files changed, 87 insertions(+), 41 deletions(-) rename src/formatters/{html.js => html.ts} (71%) rename src/formatters/{index.js => index.ts} (100%) diff --git a/src/formatters/html.js b/src/formatters/html.ts similarity index 71% rename from src/formatters/html.js rename to src/formatters/html.ts index ad462028..975cb664 100644 --- a/src/formatters/html.js +++ b/src/formatters/html.ts @@ -1,15 +1,31 @@ import BaseFormatter from './base'; +import type { BaseFormatterContext, DeltaType, NodeType } from './base'; +import type { + AddedDelta, + ArrayDelta, + DeletedDelta, + Delta, + ModifiedDelta, + MovedDelta, + ObjectDelta, + TextDiffDelta, +} from '../types'; -class HtmlFormatter extends BaseFormatter { - typeFormattterErrorFormatter(context, err) { +interface HtmlFormatterContext extends BaseFormatterContext { + hasArrows?: boolean; +} + +class HtmlFormatter extends BaseFormatter { + typeFormattterErrorFormatter(context: HtmlFormatterContext, err: unknown) { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions context.out(`
${err}
`); } - formatValue(context, value) { + formatValue(context: HtmlFormatterContext, value: unknown) { context.out(`
${htmlEscape(JSON.stringify(value, null, 2))}
`); } - formatTextDiffString(context, value) { + formatTextDiffString(context: HtmlFormatterContext, value: string) { const lines = this.parseTextDiff(value); context.out('
    '); for (let i = 0, l = lines.length; i < l; i++) { @@ -36,14 +52,18 @@ class HtmlFormatter extends BaseFormatter { context.out('
'); } - rootBegin(context, type, nodeType) { + rootBegin( + context: HtmlFormatterContext, + type: DeltaType, + nodeType: NodeType, + ) { const nodeClass = `jsondiffpatch-${type}${ nodeType ? ` jsondiffpatch-child-node-type-${nodeType}` : '' }`; context.out(`
`); } - rootEnd(context) { + rootEnd(context: HtmlFormatterContext) { context.out( `
${ context.hasArrows @@ -54,7 +74,13 @@ class HtmlFormatter extends BaseFormatter { ); } - nodeBegin(context, key, leftKey, type, nodeType) { + nodeBegin( + context: HtmlFormatterContext, + key: string, + leftKey: string | number, + type: DeltaType, + nodeType: NodeType, + ) { const nodeClass = `jsondiffpatch-${type}${ nodeType ? ` jsondiffpatch-child-node-type-${nodeType}` : '' }`; @@ -64,14 +90,15 @@ class HtmlFormatter extends BaseFormatter { ); } - nodeEnd(context) { + nodeEnd(context: HtmlFormatterContext) { context.out(''); } - /* jshint camelcase: false */ - /* eslint-disable camelcase */ - - format_unchanged(context, delta, left) { + format_unchanged( + context: HtmlFormatterContext, + delta: undefined, + left: unknown, + ) { if (typeof left === 'undefined') { return; } @@ -80,7 +107,11 @@ class HtmlFormatter extends BaseFormatter { context.out(''); } - format_movedestination(context, delta, left) { + format_movedestination( + context: HtmlFormatterContext, + delta: undefined, + left: unknown, + ) { if (typeof left === 'undefined') { return; } @@ -89,7 +120,11 @@ class HtmlFormatter extends BaseFormatter { context.out(''); } - format_node(context, delta, left) { + format_node( + context: HtmlFormatterContext, + delta: ObjectDelta | ArrayDelta, + left: unknown, + ) { // recurse const nodeType = delta._t === 'a' ? 'array' : 'object'; context.out( @@ -99,13 +134,13 @@ class HtmlFormatter extends BaseFormatter { context.out(''); } - format_added(context, delta) { + format_added(context: HtmlFormatterContext, delta: AddedDelta) { context.out('
'); this.formatValue(context, delta[0]); context.out('
'); } - format_modified(context, delta) { + format_modified(context: HtmlFormatterContext, delta: ModifiedDelta) { context.out('
'); this.formatValue(context, delta[0]); context.out( @@ -115,13 +150,13 @@ class HtmlFormatter extends BaseFormatter { context.out('
'); } - format_deleted(context, delta) { + format_deleted(context: HtmlFormatterContext, delta: DeletedDelta) { context.out('
'); this.formatValue(context, delta[0]); context.out('
'); } - format_moved(context, delta) { + format_moved(context: HtmlFormatterContext, delta: MovedDelta) { context.out('
'); this.formatValue(context, delta[0]); context.out( @@ -152,16 +187,16 @@ class HtmlFormatter extends BaseFormatter { context.hasArrows = true; } - format_textdiff(context, delta) { + format_textdiff(context: HtmlFormatterContext, delta: TextDiffDelta) { context.out('
'); this.formatTextDiffString(context, delta[0]); context.out('
'); } } -function htmlEscape(text) { +function htmlEscape(text: string) { let html = text; - const replacements = [ + const replacements: [RegExp, string][] = [ [/&/g, '&'], [//g, '>'], @@ -174,17 +209,26 @@ function htmlEscape(text) { return html; } -const adjustArrows = function jsondiffpatchHtmlFormatterAdjustArrows(nodeArg) { +const adjustArrows = function jsondiffpatchHtmlFormatterAdjustArrows( + nodeArg?: Element, +) { const node = nodeArg || document; - const getElementText = ({ textContent, innerText }) => + const getElementText = ({ textContent, innerText }: HTMLDivElement) => textContent || innerText; - const eachByQuery = (el, query, fn) => { + const eachByQuery = ( + el: Element | Document, + query: string, + fn: (element: HTMLElement) => void, + ) => { const elems = el.querySelectorAll(query); for (let i = 0, l = elems.length; i < l; i++) { - fn(elems[i]); + fn(elems[i] as HTMLElement); } }; - const eachChildren = ({ children }, fn) => { + const eachChildren = ( + { children }: ParentNode, + fn: (child: Element, index: number) => void, + ) => { for (let i = 0, l = children.length; i < l; i++) { fn(children[i], i); } @@ -193,18 +237,18 @@ const adjustArrows = function jsondiffpatchHtmlFormatterAdjustArrows(nodeArg) { node, '.jsondiffpatch-arrow', ({ parentNode, children, style }) => { - const arrowParent = parentNode; - const svg = children[0]; - const path = svg.children[1]; + const arrowParent = parentNode as HTMLElement; + const svg = children[0] as SVGSVGElement; + const path = svg.children[1] as SVGPathElement; svg.style.display = 'none'; const destination = getElementText( - arrowParent.querySelector('.jsondiffpatch-moved-destination'), + arrowParent.querySelector('.jsondiffpatch-moved-destination')!, ); - const container = arrowParent.parentNode; - let destinationElem; + const container = arrowParent.parentNode!; + let destinationElem: HTMLElement | undefined; eachChildren(container, (child) => { if (child.getAttribute('data-key') === destination) { - destinationElem = child; + destinationElem = child as HTMLElement; } }); if (!destinationElem) { @@ -212,7 +256,7 @@ const adjustArrows = function jsondiffpatchHtmlFormatterAdjustArrows(nodeArg) { } try { const distance = destinationElem.offsetTop - arrowParent.offsetTop; - svg.setAttribute('height', Math.abs(distance) + 6); + svg.setAttribute('height', `${Math.abs(distance) + 6}`); style.top = `${-8 + (distance > 0 ? 0 : distance)}px`; const curve = distance > 0 @@ -227,10 +271,11 @@ const adjustArrows = function jsondiffpatchHtmlFormatterAdjustArrows(nodeArg) { ); }; -/* jshint camelcase: true */ -/* eslint-enable camelcase */ - -export const showUnchanged = (show, node, delay) => { +export const showUnchanged = ( + show?: boolean, + node?: Element, + delay?: number, +) => { const el = node || document.body; const prefix = 'jsondiffpatch-unchanged-'; const classes = { @@ -284,13 +329,14 @@ export const showUnchanged = (show, node, delay) => { }, delay); }; -export const hideUnchanged = (node, delay) => showUnchanged(false, node, delay); +export const hideUnchanged = (node?: Element, delay?: number) => + showUnchanged(false, node, delay); export default HtmlFormatter; -let defaultInstance; +let defaultInstance: HtmlFormatter | undefined; -export function format(delta, left) { +export function format(delta: Delta, left: unknown) { if (!defaultInstance) { defaultInstance = new HtmlFormatter(); } diff --git a/src/formatters/index.js b/src/formatters/index.ts similarity index 100% rename from src/formatters/index.js rename to src/formatters/index.ts From 0340746f57d4fc29b1df829dcd8d85ebf31b150b Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 5 Sep 2023 22:07:10 -0400 Subject: [PATCH 14/19] Fix lint --- src/pipe.ts | 1 + src/processor.ts | 9 ++++++++- src/types.ts | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pipe.ts b/src/pipe.ts index 9e1fbf41..23ab1150 100644 --- a/src/pipe.ts +++ b/src/pipe.ts @@ -2,6 +2,7 @@ import type Context from './contexts/context'; import type Processor from './processor'; import type { Filter } from './types'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any class Pipe> { name: string; filters: Filter[]; diff --git a/src/processor.ts b/src/processor.ts index dbd5e437..562ca104 100644 --- a/src/processor.ts +++ b/src/processor.ts @@ -4,6 +4,7 @@ import type { Options } from './types'; class Processor { selfOptions: Options; + // eslint-disable-next-line @typescript-eslint/no-explicit-any pipes: { [pipeName: string]: Pipe> }; constructor(options?: Options) { @@ -18,6 +19,7 @@ class Processor { return this.selfOptions; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any pipe>( name: string | Pipe, pipeArg?: Pipe, @@ -27,20 +29,24 @@ class Processor { if (typeof pipe === 'undefined') { return this.pipes[name]!; } else { + // eslint-disable-next-line @typescript-eslint/no-explicit-any this.pipes[name] = pipe as Pipe>; } } if (name && (name as Pipe).name) { - pipe = name as Pipe>; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + pipe = name as Pipe>; if (pipe.processor === this) { return pipe; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any this.pipes[pipe.name] = pipe as Pipe>; } pipe!.processor = this; return pipe!; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any process>( input: TContext, pipe?: Pipe, @@ -70,6 +76,7 @@ class Processor { } } } + // eslint-disable-next-line @typescript-eslint/no-unsafe-return return context.hasResult ? context.result : undefined; } } diff --git a/src/types.ts b/src/types.ts index 93cb9377..93f5cfdf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -43,6 +43,7 @@ export type Delta = | TextDiffDelta | undefined; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export interface Filter> { (context: TContext): void; filterName: string; From 354569bc425eea74a36a7aad8bad652f5a8c1e7b Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 5 Sep 2023 22:12:48 -0400 Subject: [PATCH 15/19] Update build --- .babelrc | 5 +- package-lock.json | 396 +++++++++++++++++++++++++--------------------- package.json | 5 +- rollup.config.mjs | 20 +-- 4 files changed, 235 insertions(+), 191 deletions(-) diff --git a/.babelrc b/.babelrc index 9375ee59..f45b63d4 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,6 @@ { - "presets": [["@babel/preset-env", { "targets": "defaults" }]] + "presets": [ + ["@babel/preset-env", { "targets": "defaults" }], + "@babel/preset-typescript" + ] } diff --git a/package-lock.json b/package-lock.json index 21820ca2..e6b4af28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,8 +16,9 @@ "jsondiffpatch": "bin/jsondiffpatch" }, "devDependencies": { - "@babel/core": "^7.22.10", - "@babel/preset-env": "^7.22.10", + "@babel/core": "^7.22.15", + "@babel/preset-env": "^7.22.15", + "@babel/preset-typescript": "^7.22.15", "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-commonjs": "^25.0.4", "@rollup/plugin-node-resolve": "^15.2.0", @@ -59,12 +60,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.10", + "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" }, "engines": { @@ -152,25 +153,25 @@ } }, "node_modules/@babel/core": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", - "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.15.tgz", + "integrity": "sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-compilation-targets": "^7.22.10", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.10", - "@babel/parser": "^7.22.10", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.22.15", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.22.15", + "@babel/helpers": "^7.22.15", + "@babel/parser": "^7.22.15", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.22.15", + "@babel/types": "^7.22.15", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" }, "engines": { @@ -182,12 +183,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", + "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.10", + "@babel/types": "^7.22.15", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -221,13 +222,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", "browserslist": "^4.21.9", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -237,15 +238,15 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.10.tgz", - "integrity": "sha512-5IBb77txKYQPpOEdUdIhBx8VrZyDCQ+H82H0+5dX1TmuscP5vJKEE3cKurjtIw/vFwzbVH48VweE78kVDBrqjA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.22.9", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -327,40 +328,40 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", - "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.15.tgz", + "integrity": "sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.15.tgz", + "integrity": "sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-validator-identifier": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -470,18 +471,18 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", + "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", "dev": true, "engines": { "node": ">=6.9.0" @@ -502,23 +503,23 @@ } }, "node_modules/@babel/helpers": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", - "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz", + "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.5", @@ -601,9 +602,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.15.tgz", + "integrity": "sha512-RWmQ/sklUN9BvGGpCDgSubhHWfAx24XDTDObup4ffvxaYsptOg2P3KG0j+1eWKLxpkX0j0uHxmpq2Z1SP/VhxA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -613,9 +614,9 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz", - "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz", + "integrity": "sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -628,14 +629,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", - "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz", + "integrity": "sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.5" + "@babel/plugin-transform-optional-chaining": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -949,9 +950,9 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.10.tgz", - "integrity": "sha512-eueE8lvKVzq5wIObKK/7dvoeKJ+xc6TvRn6aysIjS6pSCeLy7S/eVi7pEQknZqyqvzaNKdDtem8nUNTBgDVR2g==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.15.tgz", + "integrity": "sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", @@ -999,9 +1000,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.10.tgz", - "integrity": "sha512-1+kVpGAOOI1Albt6Vse7c8pHzcZQdQKW+wJH+g8mCaszOdDVwRXa/slHPqIw+oJAJANTKDMuM2cBdV0Dg618Vg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.15.tgz", + "integrity": "sha512-G1czpdJBZCtngoK1sJgloLiOHUnkb/bLZwqVZD8kXmq0ZnVfTTWUcs9OWtp0mBtYJ+4LQY1fllqBkOIPhXmFmw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1030,12 +1031,12 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", - "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz", + "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, @@ -1047,18 +1048,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz", - "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz", + "integrity": "sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-function-name": "^7.22.5", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", "@babel/helper-split-export-declaration": "^7.22.6", "globals": "^11.1.0" }, @@ -1086,9 +1087,9 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.10.tgz", - "integrity": "sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.15.tgz", + "integrity": "sha512-HzG8sFl1ZVGTme74Nw+X01XsUTqERVQ6/RLHo3XjGRzm7XD6QTtfS3NJotVgCGy8BzkDqRjRBD8dAyJn5TuvSQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1132,9 +1133,9 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", - "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz", + "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1164,9 +1165,9 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", - "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz", + "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1180,9 +1181,9 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", - "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz", + "integrity": "sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1212,9 +1213,9 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", - "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz", + "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1243,9 +1244,9 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", - "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz", + "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1290,12 +1291,12 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", - "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.15.tgz", + "integrity": "sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, @@ -1307,13 +1308,13 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", - "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz", + "integrity": "sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.22.9", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.5" }, @@ -1372,9 +1373,9 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", - "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz", + "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1388,9 +1389,9 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", - "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz", + "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1404,16 +1405,16 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", - "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz", + "integrity": "sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.22.5" + "@babel/plugin-transform-parameters": "^7.22.15" }, "engines": { "node": ">=6.9.0" @@ -1439,9 +1440,9 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", - "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz", + "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1455,9 +1456,9 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.10.tgz", - "integrity": "sha512-MMkQqZAZ+MGj+jGTG3OTuhKeBpNcO+0oCEbrGNEaOmiEn+1MzRyQlYsruGiU8RTK3zV6XwrVJTmwiDOyYK6J9g==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.15.tgz", + "integrity": "sha512-ngQ2tBhq5vvSJw2Q2Z9i7ealNkpDMU0rGWnHPKqRZO0tzZ5tlaoz4hDvhXioOoaE0X2vfNss1djwg0DXlfu30A==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -1472,9 +1473,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", - "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz", + "integrity": "sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1503,13 +1504,13 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", - "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz", + "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, @@ -1642,6 +1643,24 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz", + "integrity": "sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.22.10", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz", @@ -1706,17 +1725,17 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.10.tgz", - "integrity": "sha512-riHpLb1drNkpLlocmSyEg4oYJIQFeXAK/d7rI6mbD0XsvoTOOweXDmQPG/ErxsEhWk3rl3Q/3F6RFQlVFS8m0A==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.15.tgz", + "integrity": "sha512-tZFHr54GBkHk6hQuVA8w4Fmq+MSPsfvMG0vPnOYyTnJpyfMqybL8/MbNCPRT9zc2KBO2pe4tq15g6Uno4Jpoag==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.10", + "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -1737,41 +1756,41 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.22.5", - "@babel/plugin-transform-async-generator-functions": "^7.22.10", + "@babel/plugin-transform-async-generator-functions": "^7.22.15", "@babel/plugin-transform-async-to-generator": "^7.22.5", "@babel/plugin-transform-block-scoped-functions": "^7.22.5", - "@babel/plugin-transform-block-scoping": "^7.22.10", + "@babel/plugin-transform-block-scoping": "^7.22.15", "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-class-static-block": "^7.22.5", - "@babel/plugin-transform-classes": "^7.22.6", + "@babel/plugin-transform-class-static-block": "^7.22.11", + "@babel/plugin-transform-classes": "^7.22.15", "@babel/plugin-transform-computed-properties": "^7.22.5", - "@babel/plugin-transform-destructuring": "^7.22.10", + "@babel/plugin-transform-destructuring": "^7.22.15", "@babel/plugin-transform-dotall-regex": "^7.22.5", "@babel/plugin-transform-duplicate-keys": "^7.22.5", - "@babel/plugin-transform-dynamic-import": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.11", "@babel/plugin-transform-exponentiation-operator": "^7.22.5", - "@babel/plugin-transform-export-namespace-from": "^7.22.5", - "@babel/plugin-transform-for-of": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.11", + "@babel/plugin-transform-for-of": "^7.22.15", "@babel/plugin-transform-function-name": "^7.22.5", - "@babel/plugin-transform-json-strings": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.11", "@babel/plugin-transform-literals": "^7.22.5", - "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.11", "@babel/plugin-transform-member-expression-literals": "^7.22.5", "@babel/plugin-transform-modules-amd": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.5", - "@babel/plugin-transform-modules-systemjs": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.15", + "@babel/plugin-transform-modules-systemjs": "^7.22.11", "@babel/plugin-transform-modules-umd": "^7.22.5", "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", "@babel/plugin-transform-new-target": "^7.22.5", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5", - "@babel/plugin-transform-numeric-separator": "^7.22.5", - "@babel/plugin-transform-object-rest-spread": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", + "@babel/plugin-transform-numeric-separator": "^7.22.11", + "@babel/plugin-transform-object-rest-spread": "^7.22.15", "@babel/plugin-transform-object-super": "^7.22.5", - "@babel/plugin-transform-optional-catch-binding": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.10", - "@babel/plugin-transform-parameters": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.11", + "@babel/plugin-transform-optional-chaining": "^7.22.15", + "@babel/plugin-transform-parameters": "^7.22.15", "@babel/plugin-transform-private-methods": "^7.22.5", - "@babel/plugin-transform-private-property-in-object": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.11", "@babel/plugin-transform-property-literals": "^7.22.5", "@babel/plugin-transform-regenerator": "^7.22.10", "@babel/plugin-transform-reserved-words": "^7.22.5", @@ -1785,7 +1804,7 @@ "@babel/plugin-transform-unicode-regex": "^7.22.5", "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", "@babel/preset-modules": "0.1.6-no-external-plugins", - "@babel/types": "^7.22.10", + "@babel/types": "^7.22.15", "babel-plugin-polyfill-corejs2": "^0.4.5", "babel-plugin-polyfill-corejs3": "^0.8.3", "babel-plugin-polyfill-regenerator": "^0.5.2", @@ -1813,6 +1832,25 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, + "node_modules/@babel/preset-typescript": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.15.tgz", + "integrity": "sha512-HblhNmh6yM+cU4VwbBRpxFhxsTdfS1zsvH9W+gEjD0ARV9+8B4sNfpI6GuhePti84nuvhiwKS539jKPFHskA9A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.15", + "@babel/plugin-transform-typescript": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/regjsgen": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", @@ -1832,33 +1870,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.15.tgz", + "integrity": "sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.22.15", "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-function-name": "^7.22.5", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1867,13 +1905,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", + "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.15", "to-fast-properties": "^2.0.0" }, "engines": { diff --git a/package.json b/package.json index 793e4a72..83ff0c60 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,9 @@ "diff-match-patch": "^1.0.5" }, "devDependencies": { - "@babel/core": "^7.22.10", - "@babel/preset-env": "^7.22.10", + "@babel/core": "^7.22.15", + "@babel/preset-env": "^7.22.15", + "@babel/preset-typescript": "^7.22.15", "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-commonjs": "^25.0.4", "@rollup/plugin-node-resolve": "^15.2.0", diff --git a/rollup.config.mjs b/rollup.config.mjs index eed79c89..5623e502 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -9,12 +9,11 @@ import { visualizer } from 'rollup-plugin-visualizer'; import pkg from './package.json' assert { type: 'json' }; -const copySrcFileToDist = copyFromFolderToDist('src'); const copyDocsFileToDist = copyFromFolderToDist('docs'); export default [ { - input: 'src/main.js', + input: 'src/main.ts', external: ['chalk'], output: { name: pkg.name, @@ -32,13 +31,14 @@ export default [ babel({ exclude: 'node_modules/**', babelHelpers: 'bundled', + extensions: ['.js', '.jsx', '.es6', '.es', '.mjs', '.ts'], }), - resolve(), // so Rollup can find node modules - commonjs(), // so Rollup can convert node modules to ES modules + resolve({ extensions: ['.mjs', '.js', '.json', '.node', '.ts'] }), + commonjs(), ], }, { - input: 'src/main.js', + input: 'src/main.ts', external: ['chalk', 'diff-match-patch'], output: { name: pkg.name, @@ -61,13 +61,14 @@ export default [ babel({ exclude: 'node_modules/**', babelHelpers: 'bundled', + extensions: ['.js', '.jsx', '.es6', '.es', '.mjs', '.ts'], }), - resolve(), // so Rollup can find node modules - commonjs(), // so Rollup can convert node modules to ES modules + resolve({ extensions: ['.mjs', '.js', '.json', '.node', '.ts'] }), + commonjs(), ], }, { - input: 'src/main.js', + input: 'src/main.ts', external: [ // external node modules 'diff-match-patch', @@ -77,8 +78,9 @@ export default [ babel({ exclude: 'node_modules/**', babelHelpers: 'bundled', + extensions: ['.js', '.jsx', '.es6', '.es', '.mjs', '.ts'], }), - copySrcFileToDist('index.d.ts'), + resolve({ extensions: ['.mjs', '.js', '.json', '.node', '.ts'] }), copyDocsFileToDist('formatters-styles/annotated.css'), copyDocsFileToDist('formatters-styles/html.css'), ], From 8dc0b8a75c09c907af5039a602f8937bf3d62412 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 5 Sep 2023 22:13:49 -0400 Subject: [PATCH 16/19] Update CI --- .github/workflows/CI.yml | 1 + docs/test/index.html | 86 ---------------------------------------- 2 files changed, 1 insertion(+), 86 deletions(-) delete mode 100644 docs/test/index.html diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c780564d..95571b71 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -18,6 +18,7 @@ jobs: cache: 'npm' - run: npm ci - run: npm run build + - run: npm run type-check - run: npm run test - run: npm run lint - run: npm run format-check diff --git a/docs/test/index.html b/docs/test/index.html deleted file mode 100644 index 199975b6..00000000 --- a/docs/test/index.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - jsondiffpatch tests - - - - - - - -

jsondiffpatch tests

- -
- - - From 1988d6683ec1d5e89bd6fe7929b9df291479e9dc Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 5 Sep 2023 22:42:37 -0400 Subject: [PATCH 17/19] Generate declaration files as part of build --- .github/workflows/CI.yml | 1 - package-lock.json | 55 +++++++++++++++++++++++++++------------- package.json | 6 +++-- rollup.config.mjs | 9 ++++--- src/main.ts | 2 ++ tsconfig.json | 10 ++------ 6 files changed, 52 insertions(+), 31 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 95571b71..c780564d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -18,7 +18,6 @@ jobs: cache: 'npm' - run: npm ci - run: npm run build - - run: npm run type-check - run: npm run test - run: npm run lint - run: npm run format-check diff --git a/package-lock.json b/package-lock.json index e6b4af28..c04e81bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,10 @@ "version": "0.5.0", "license": "MIT", "dependencies": { + "@rollup/plugin-typescript": "^11.1.3", "chalk": "^3.0.0", - "diff-match-patch": "^1.0.5" + "diff-match-patch": "^1.0.5", + "tslib": "^2.6.2" }, "bin": { "jsondiffpatch": "bin/jsondiffpatch" @@ -2724,11 +2726,35 @@ } } }, + "node_modules/@rollup/plugin-typescript": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.3.tgz", + "integrity": "sha512-8o6cNgN44kQBcpsUJTbTXMTtb87oR1O0zgP3Dxm71hrNgparap3VujgofEilTYJo+ivf2ke6uy3/E5QEaiRlDA==", + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0||^3.0.0", + "tslib": "*", + "typescript": ">=3.7.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "tslib": { + "optional": true + } + } + }, "node_modules/@rollup/pluginutils": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.3.tgz", "integrity": "sha512-hfllNN4a80rwNQ9QCxhxuHCGHMAvabXqxNdaChUSSadMre7t4iEUI6fFAhBOn/eIYTgYVhBv7vCLsAJ4u3lf3g==", - "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -2814,8 +2840,7 @@ "node_modules/@types/estree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" }, "node_modules/@types/graceful-fs": { "version": "4.1.6", @@ -4091,8 +4116,7 @@ "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, "node_modules/esutils": { "version": "2.0.3", @@ -4298,8 +4322,7 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "node_modules/gensync": { "version": "1.0.0-beta.2", @@ -4437,7 +4460,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -4562,7 +4584,6 @@ "version": "2.13.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "dev": true, "dependencies": { "has": "^1.0.3" }, @@ -6058,8 +6079,7 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-type": { "version": "4.0.0", @@ -6080,7 +6100,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -6359,7 +6378,6 @@ "version": "1.22.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -6460,7 +6478,7 @@ "version": "3.28.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.0.tgz", "integrity": "sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==", - "dev": true, + "devOptional": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -6711,7 +6729,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -6798,6 +6815,11 @@ "typescript": ">=4.2.0" } }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6835,7 +6857,6 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 83ff0c60..d12db8c7 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "browser": "dist/jsondiffpatch.umd.js", "main": "dist/jsondiffpatch.cjs.js", "module": "dist/jsondiffpatch.esm.js", - "types": "./dist/index", + "types": "dist/types/main.d.ts", "files": [ "dist", "bin" @@ -19,7 +19,7 @@ }, "scripts": { "build": "rollup -c", - "type-check": "tsc", + "type-check": "tsc --noEmit", "lint": "eslint src", "test": "jest --coverage", "format": "prettier . --write", @@ -48,6 +48,7 @@ "@rollup/plugin-commonjs": "^25.0.4", "@rollup/plugin-node-resolve": "^15.2.0", "@rollup/plugin-replace": "^5.0.2", + "@rollup/plugin-typescript": "^11.1.3", "@typescript-eslint/eslint-plugin": "^6.6.0", "@typescript-eslint/parser": "^6.6.0", "eslint": "^8.47.0", @@ -56,6 +57,7 @@ "prettier": "^3.0.2", "rollup": "^3.28.0", "rollup-plugin-visualizer": "^5.9.2", + "tslib": "^2.6.2", "typescript": "~5.2.2" }, "license": "MIT", diff --git a/rollup.config.mjs b/rollup.config.mjs index 5623e502..d5cf4008 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -5,6 +5,7 @@ import { fileURLToPath } from 'node:url'; import babel from '@rollup/plugin-babel'; import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; +import typescript from '@rollup/plugin-typescript'; import { visualizer } from 'rollup-plugin-visualizer'; import pkg from './package.json' assert { type: 'json' }; @@ -33,8 +34,9 @@ export default [ babelHelpers: 'bundled', extensions: ['.js', '.jsx', '.es6', '.es', '.mjs', '.ts'], }), - resolve({ extensions: ['.mjs', '.js', '.json', '.node', '.ts'] }), + resolve(), commonjs(), + typescript({ compilerOptions: { emitDeclarationOnly: true }, noForceEmit: true }), ], }, { @@ -63,8 +65,9 @@ export default [ babelHelpers: 'bundled', extensions: ['.js', '.jsx', '.es6', '.es', '.mjs', '.ts'], }), - resolve({ extensions: ['.mjs', '.js', '.json', '.node', '.ts'] }), + resolve(), commonjs(), + typescript({ compilerOptions: { emitDeclarationOnly: true }, noForceEmit: true }), ], }, { @@ -80,7 +83,7 @@ export default [ babelHelpers: 'bundled', extensions: ['.js', '.jsx', '.es6', '.es', '.mjs', '.ts'], }), - resolve({ extensions: ['.mjs', '.js', '.json', '.node', '.ts'] }), + typescript({ compilerOptions: { emitDeclarationOnly: true }, noForceEmit: true }), copyDocsFileToDist('formatters-styles/annotated.css'), copyDocsFileToDist('formatters-styles/html.css'), ], diff --git a/src/main.ts b/src/main.ts index 8760749c..5ed186e0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,6 +8,8 @@ export * as formatters from './formatters/index'; export * as console from './formatters/console'; +export type * from './types'; + export function create(options?: Options) { return new DiffPatcher(options); } diff --git a/tsconfig.json b/tsconfig.json index 38e163be..50262fe3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,10 @@ { "compilerOptions": { "target": "es2016", - // "lib": [], "module": "node16", "types": [], - // "resolveJsonModule": true, - // "declaration": true, - // "declarationMap": true, - // "emitDeclarationOnly": true, - // "outFile": "./", - // "outDir": "./", - "noEmit": true, + "declaration": true, + "outDir": "./dist/types", "isolatedModules": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, From 98d708ae2144f78be8d21e15174a5aad43018ee6 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 5 Sep 2023 22:45:15 -0400 Subject: [PATCH 18/19] Format --- rollup.config.mjs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/rollup.config.mjs b/rollup.config.mjs index d5cf4008..d8e14da6 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -36,7 +36,10 @@ export default [ }), resolve(), commonjs(), - typescript({ compilerOptions: { emitDeclarationOnly: true }, noForceEmit: true }), + typescript({ + compilerOptions: { emitDeclarationOnly: true }, + noForceEmit: true, + }), ], }, { @@ -67,7 +70,10 @@ export default [ }), resolve(), commonjs(), - typescript({ compilerOptions: { emitDeclarationOnly: true }, noForceEmit: true }), + typescript({ + compilerOptions: { emitDeclarationOnly: true }, + noForceEmit: true, + }), ], }, { @@ -83,7 +89,10 @@ export default [ babelHelpers: 'bundled', extensions: ['.js', '.jsx', '.es6', '.es', '.mjs', '.ts'], }), - typescript({ compilerOptions: { emitDeclarationOnly: true }, noForceEmit: true }), + typescript({ + compilerOptions: { emitDeclarationOnly: true }, + noForceEmit: true, + }), copyDocsFileToDist('formatters-styles/annotated.css'), copyDocsFileToDist('formatters-styles/html.css'), ], From e2ca12d51be87eae9691eda3a8fbe61a25d82e62 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 5 Sep 2023 22:48:59 -0400 Subject: [PATCH 19/19] Remove duplicate --- src/formatters/annotated.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/formatters/annotated.ts b/src/formatters/annotated.ts index e2317553..e2828c2f 100644 --- a/src/formatters/annotated.ts +++ b/src/formatters/annotated.ts @@ -295,12 +295,6 @@ const formatAnyChange = function < context.indent(-1); }; -AnnotatedFormatter.prototype.format_added = formatAnyChange; -AnnotatedFormatter.prototype.format_modified = formatAnyChange; -AnnotatedFormatter.prototype.format_deleted = formatAnyChange; -AnnotatedFormatter.prototype.format_moved = formatAnyChange; -AnnotatedFormatter.prototype.format_textdiff = formatAnyChange; - export default AnnotatedFormatter; let defaultInstance: AnnotatedFormatter | undefined;