Feature: support rule provider

This commit is contained in:
Dreamacro 2020-06-06 23:48:17 +08:00
parent 836b4ba7c6
commit 7be76d374a
13 changed files with 458 additions and 257 deletions

369
package-lock.json generated
View File

@ -45,12 +45,12 @@
} }
}, },
"@babel/code-frame": { "@babel/code-frame": {
"version": "7.8.3", "version": "7.10.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz",
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/highlight": "^7.8.3" "@babel/highlight": "^7.10.1"
} }
}, },
"@babel/compat-data": { "@babel/compat-data": {
@ -65,19 +65,19 @@
} }
}, },
"@babel/core": { "@babel/core": {
"version": "7.10.1", "version": "7.10.2",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.1.tgz", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz",
"integrity": "sha512-u8XiZ6sMXW/gPmoP5ijonSUln4unazG291X0XAQ5h0s8qnAFr6BRRZGUEK+jtRWdmB0NTJQt7Uga25q8GetIIg==", "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/code-frame": "^7.10.1", "@babel/code-frame": "^7.10.1",
"@babel/generator": "^7.10.1", "@babel/generator": "^7.10.2",
"@babel/helper-module-transforms": "^7.10.1", "@babel/helper-module-transforms": "^7.10.1",
"@babel/helpers": "^7.10.1", "@babel/helpers": "^7.10.1",
"@babel/parser": "^7.10.1", "@babel/parser": "^7.10.2",
"@babel/template": "^7.10.1", "@babel/template": "^7.10.1",
"@babel/traverse": "^7.10.1", "@babel/traverse": "^7.10.1",
"@babel/types": "^7.10.1", "@babel/types": "^7.10.2",
"convert-source-map": "^1.7.0", "convert-source-map": "^1.7.0",
"debug": "^4.1.0", "debug": "^4.1.0",
"gensync": "^1.0.0-beta.1", "gensync": "^1.0.0-beta.1",
@ -88,24 +88,15 @@
"source-map": "^0.5.0" "source-map": "^0.5.0"
}, },
"dependencies": { "dependencies": {
"@babel/code-frame": { "@babel/types": {
"version": "7.10.1", "version": "7.10.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz",
"integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==",
"dev": true,
"requires": {
"@babel/highlight": "^7.10.1"
}
},
"@babel/highlight": {
"version": "7.10.1",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz",
"integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/helper-validator-identifier": "^7.10.1", "@babel/helper-validator-identifier": "^7.10.1",
"chalk": "^2.0.0", "lodash": "^4.17.13",
"js-tokens": "^4.0.0" "to-fast-properties": "^2.0.0"
} }
}, },
"debug": { "debug": {
@ -126,15 +117,28 @@
} }
}, },
"@babel/generator": { "@babel/generator": {
"version": "7.10.1", "version": "7.10.2",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.1.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz",
"integrity": "sha512-AT0YPLQw9DI21tliuJIdplVfLHya6mcGa8ctkv7n4Qv+hYacJrKmNWIteAK1P9iyLikFIAkwqJ7HAOqIDLFfgA==", "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/types": "^7.10.1", "@babel/types": "^7.10.2",
"jsesc": "^2.5.1", "jsesc": "^2.5.1",
"lodash": "^4.17.13", "lodash": "^4.17.13",
"source-map": "^0.5.0" "source-map": "^0.5.0"
},
"dependencies": {
"@babel/types": {
"version": "7.10.2",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz",
"integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.10.1",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
} }
}, },
"@babel/helper-annotate-as-pure": { "@babel/helper-annotate-as-pure": {
@ -178,9 +182,9 @@
} }
}, },
"@babel/helper-compilation-targets": { "@babel/helper-compilation-targets": {
"version": "7.10.1", "version": "7.10.2",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.1.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz",
"integrity": "sha512-YuF8IrgSmX/+MV2plPkjEnzlC2wf+gaok8ehMNN0jodF3/sejZauExqpEVGbJua62oaWoNYIXwz4RmAsVcGyHw==", "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/compat-data": "^7.10.1", "@babel/compat-data": "^7.10.1",
@ -191,9 +195,9 @@
} }
}, },
"@babel/helper-create-class-features-plugin": { "@babel/helper-create-class-features-plugin": {
"version": "7.10.1", "version": "7.10.2",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.1.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz",
"integrity": "sha512-bwhdehBJZt84HuPUcP1HaTLuc/EywVS8rc3FgsEPDcivg+DCW+SHuLHVkYOmcBA1ZfI+Z/oZjQc/+bPmIO7uAA==", "integrity": "sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/helper-function-name": "^7.10.1", "@babel/helper-function-name": "^7.10.1",
@ -396,20 +400,20 @@
} }
}, },
"@babel/highlight": { "@babel/highlight": {
"version": "7.8.3", "version": "7.10.1",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz",
"integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/helper-validator-identifier": "^7.10.1",
"chalk": "^2.0.0", "chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0" "js-tokens": "^4.0.0"
} }
}, },
"@babel/parser": { "@babel/parser": {
"version": "7.10.1", "version": "7.10.2",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.1.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz",
"integrity": "sha512-AUTksaz3FqugBkbTZ1i+lDLG5qy8hIzCaAxEtttU6C0BtZZU9pkNZtWSVAht4EW9kl46YBiyTGMp9xTTGqViNg==", "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==",
"dev": true "dev": true
}, },
"@babel/plugin-proposal-async-generator-functions": { "@babel/plugin-proposal-async-generator-functions": {
@ -1001,13 +1005,13 @@
} }
}, },
"@babel/preset-env": { "@babel/preset-env": {
"version": "7.10.1", "version": "7.10.2",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.1.tgz", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.2.tgz",
"integrity": "sha512-bGWNfjfXRLnqbN2T4lB3pMfoic8dkRrmHpVZamSFHzGy5xklyHTobZ28TVUD2grhE5WDnu67tBj8oslIhkiOMQ==", "integrity": "sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/compat-data": "^7.10.1", "@babel/compat-data": "^7.10.1",
"@babel/helper-compilation-targets": "^7.10.1", "@babel/helper-compilation-targets": "^7.10.2",
"@babel/helper-module-imports": "^7.10.1", "@babel/helper-module-imports": "^7.10.1",
"@babel/helper-plugin-utils": "^7.10.1", "@babel/helper-plugin-utils": "^7.10.1",
"@babel/plugin-proposal-async-generator-functions": "^7.10.1", "@babel/plugin-proposal-async-generator-functions": "^7.10.1",
@ -1064,12 +1068,25 @@
"@babel/plugin-transform-unicode-escapes": "^7.10.1", "@babel/plugin-transform-unicode-escapes": "^7.10.1",
"@babel/plugin-transform-unicode-regex": "^7.10.1", "@babel/plugin-transform-unicode-regex": "^7.10.1",
"@babel/preset-modules": "^0.1.3", "@babel/preset-modules": "^0.1.3",
"@babel/types": "^7.10.1", "@babel/types": "^7.10.2",
"browserslist": "^4.12.0", "browserslist": "^4.12.0",
"core-js-compat": "^3.6.2", "core-js-compat": "^3.6.2",
"invariant": "^2.2.2", "invariant": "^2.2.2",
"levenary": "^1.1.1", "levenary": "^1.1.1",
"semver": "^5.5.0" "semver": "^5.5.0"
},
"dependencies": {
"@babel/types": {
"version": "7.10.2",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz",
"integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.10.1",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
}
} }
}, },
"@babel/preset-modules": { "@babel/preset-modules": {
@ -1127,28 +1144,6 @@
"@babel/code-frame": "^7.10.1", "@babel/code-frame": "^7.10.1",
"@babel/parser": "^7.10.1", "@babel/parser": "^7.10.1",
"@babel/types": "^7.10.1" "@babel/types": "^7.10.1"
},
"dependencies": {
"@babel/code-frame": {
"version": "7.10.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz",
"integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==",
"dev": true,
"requires": {
"@babel/highlight": "^7.10.1"
}
},
"@babel/highlight": {
"version": "7.10.1",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz",
"integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.10.1",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
}
} }
}, },
"@babel/traverse": { "@babel/traverse": {
@ -1168,26 +1163,6 @@
"lodash": "^4.17.13" "lodash": "^4.17.13"
}, },
"dependencies": { "dependencies": {
"@babel/code-frame": {
"version": "7.10.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz",
"integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==",
"dev": true,
"requires": {
"@babel/highlight": "^7.10.1"
}
},
"@babel/highlight": {
"version": "7.10.1",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz",
"integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.10.1",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"debug": { "debug": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@ -1583,6 +1558,23 @@
"fastq": "^1.6.0" "fastq": "^1.6.0"
} }
}, },
"@npmcli/move-file": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz",
"integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==",
"dev": true,
"requires": {
"mkdirp": "^1.0.4"
},
"dependencies": {
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true
}
}
},
"@scarf/scarf": { "@scarf/scarf": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.0.5.tgz", "resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.0.5.tgz",
@ -1701,9 +1693,9 @@
"dev": true "dev": true
}, },
"@types/node": { "@types/node": {
"version": "14.0.6", "version": "14.0.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.6.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.11.tgz",
"integrity": "sha512-FbNmu4F67d3oZMWBV6Y4MaPER+0EpE9eIYf2yaHhCWovc1dlXCZkqGX4NLHfVVr6umt20TNBdRzrNJIzIKfdbw==", "integrity": "sha512-lCvvI24L21ZVeIiyIUHZ5Oflv1hhHQ5E1S25IRlKIXaRkVgmXpJMI3wUJkmym2bTbCe+WoIibQnMVAU3FguaOg==",
"dev": true "dev": true
}, },
"@types/normalize-package-data": { "@types/normalize-package-data": {
@ -1772,9 +1764,9 @@
} }
}, },
"@types/react-table": { "@types/react-table": {
"version": "7.0.18", "version": "7.0.19",
"resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-7.0.18.tgz", "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-7.0.19.tgz",
"integrity": "sha512-O4iKmVYVQz+6Nl9LsLtWQz9Unsmq0UySJrh5hpV5d+wrf15skhB0dqI9ocCNovJpcYxGjHrn3VbeSyAcaxHZtA==", "integrity": "sha512-RYyEY7Yry6F2JsKhHeFsGdzuFF1hMqBStQrrazDzpBl4m/ECGHJxFVQjLBRzRwK+47ZKNPm79f7qEpHirbiCLA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/react": "*" "@types/react": "*"
@ -1884,12 +1876,12 @@
} }
}, },
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "3.0.2", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.0.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.1.0.tgz",
"integrity": "sha512-ER3bSS/A/pKQT/hjMGCK8UQzlL0yLjuCZ/G8CDFJFVTfl3X65fvq2lNYqOG8JPTfrPa2RULCdwfOyFjZEMNExQ==", "integrity": "sha512-D52KwdgkjYc+fmTZKW7CZpH5ZBJREJKZXRrveMiRCmlzZ+Rw9wRVJ1JAmHQ9b/+Ehy1ZeaylofDB9wwXUt83wg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/experimental-utils": "3.0.2", "@typescript-eslint/experimental-utils": "3.1.0",
"functional-red-black-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1",
"regexpp": "^3.0.0", "regexpp": "^3.0.0",
"semver": "^7.3.2", "semver": "^7.3.2",
@ -1905,33 +1897,33 @@
} }
}, },
"@typescript-eslint/experimental-utils": { "@typescript-eslint/experimental-utils": {
"version": "3.0.2", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.0.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.1.0.tgz",
"integrity": "sha512-4Wc4EczvoY183SSEnKgqAfkj1eLtRgBQ04AAeG+m4RhTVyaazxc1uI8IHf0qLmu7xXe9j1nn+UoDJjbmGmuqXQ==", "integrity": "sha512-Zf8JVC2K1svqPIk1CB/ehCiWPaERJBBokbMfNTNRczCbQSlQXaXtO/7OfYz9wZaecNvdSvVADt6/XQuIxhC79w==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/json-schema": "^7.0.3", "@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "3.0.2", "@typescript-eslint/typescript-estree": "3.1.0",
"eslint-scope": "^5.0.0", "eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0" "eslint-utils": "^2.0.0"
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "3.0.2", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.0.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.1.0.tgz",
"integrity": "sha512-80Z7s83e8QXHNUspqVlWwb4t5gdz/1bBBmafElbK1wwAwiD/yvJsFyHRxlEpNrt4rdK6eB3p+2WEFkEDHAKk9w==", "integrity": "sha512-NcDSJK8qTA2tPfyGiPes9HtVKLbksmuYjlgGAUs7Ld2K0swdWibnCq9IJx9kJN8JJdgUJSorFiGaPHBgH81F/Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/eslint-visitor-keys": "^1.0.0", "@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "3.0.2", "@typescript-eslint/experimental-utils": "3.1.0",
"@typescript-eslint/typescript-estree": "3.0.2", "@typescript-eslint/typescript-estree": "3.1.0",
"eslint-visitor-keys": "^1.1.0" "eslint-visitor-keys": "^1.1.0"
} }
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "3.0.2", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.0.2.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.1.0.tgz",
"integrity": "sha512-cs84mxgC9zQ6viV8MEcigfIKQmKtBkZNDYf8Gru2M+MhnA6z9q0NFMZm2IEzKqAwN8lY5mFVd1Z8DiHj6zQ3Tw==", "integrity": "sha512-+4nfYauqeQvK55PgFrmBWFVYb6IskLyOosYEmhH3mSVhfBp9AIJnjExdgDmKWoOBHRcPM8Ihfm2BFpZf0euUZQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"debug": "^4.1.1", "debug": "^4.1.1",
@ -3455,11 +3447,12 @@
"dev": true "dev": true
}, },
"cacache": { "cacache": {
"version": "15.0.3", "version": "15.0.4",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.3.tgz", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.4.tgz",
"integrity": "sha512-bc3jKYjqv7k4pWh7I/ixIjfcjPul4V4jme/WbjvwGS5LzoPL/GzXr4C5EgPNLO/QEZl9Oi61iGitYEdwcrwLCQ==", "integrity": "sha512-YlnKQqTbD/6iyoJvEY3KJftjrdBYroCbxxYXzhOzsFLWlp6KX4BOlEf4mTx0cMUfVaTS3ENL2QtDWeRYoGLkkw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@npmcli/move-file": "^1.0.1",
"chownr": "^2.0.0", "chownr": "^2.0.0",
"fs-minipass": "^2.0.0", "fs-minipass": "^2.0.0",
"glob": "^7.1.4", "glob": "^7.1.4",
@ -3470,7 +3463,6 @@
"minipass-flush": "^1.0.5", "minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.2", "minipass-pipeline": "^1.2.2",
"mkdirp": "^1.0.3", "mkdirp": "^1.0.3",
"move-file": "^2.0.0",
"p-map": "^4.0.0", "p-map": "^4.0.0",
"promise-inflight": "^1.0.1", "promise-inflight": "^1.0.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
@ -5223,9 +5215,9 @@
"dev": true "dev": true
}, },
"eslint": { "eslint": {
"version": "7.1.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.1.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.2.0.tgz",
"integrity": "sha512-DfS3b8iHMK5z/YLSme8K5cge168I8j8o1uiVmFCgnnjxZQbCGyraF8bMl7Ju4yfBmCuxD7shOF7eqGkcuIHfsA==", "integrity": "sha512-B3BtEyaDKC5MlfDa2Ha8/D6DsS4fju95zs0hjS3HdGazw+LNayai38A25qMppK37wWGWNYSPOR6oYzlz5MHsRQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/code-frame": "^7.0.0", "@babel/code-frame": "^7.0.0",
@ -5234,10 +5226,10 @@
"cross-spawn": "^7.0.2", "cross-spawn": "^7.0.2",
"debug": "^4.0.1", "debug": "^4.0.1",
"doctrine": "^3.0.0", "doctrine": "^3.0.0",
"eslint-scope": "^5.0.0", "eslint-scope": "^5.1.0",
"eslint-utils": "^2.0.0", "eslint-utils": "^2.0.0",
"eslint-visitor-keys": "^1.1.0", "eslint-visitor-keys": "^1.2.0",
"espree": "^7.0.0", "espree": "^7.1.0",
"esquery": "^1.2.0", "esquery": "^1.2.0",
"esutils": "^2.0.2", "esutils": "^2.0.2",
"file-entry-cache": "^5.0.1", "file-entry-cache": "^5.0.1",
@ -5321,6 +5313,12 @@
"ms": "^2.1.1" "ms": "^2.1.1"
} }
}, },
"eslint-visitor-keys": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz",
"integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==",
"dev": true
},
"glob-parent": { "glob-parent": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
@ -5750,9 +5748,9 @@
"dev": true "dev": true
}, },
"eslint-scope": { "eslint-scope": {
"version": "5.0.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
"dev": true, "dev": true,
"requires": { "requires": {
"esrecurse": "^4.1.0", "esrecurse": "^4.1.0",
@ -5775,14 +5773,22 @@
"dev": true "dev": true
}, },
"espree": { "espree": {
"version": "7.0.0", "version": "7.1.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-7.0.0.tgz", "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz",
"integrity": "sha512-/r2XEx5Mw4pgKdyb7GNLQNsu++asx/dltf/CI8RFi9oGHxmQFgvLbc5Op4U6i8Oaj+kdslhJtVlEZeAqH5qOTw==", "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==",
"dev": true, "dev": true,
"requires": { "requires": {
"acorn": "^7.1.1", "acorn": "^7.2.0",
"acorn-jsx": "^5.2.0", "acorn-jsx": "^5.2.0",
"eslint-visitor-keys": "^1.1.0" "eslint-visitor-keys": "^1.2.0"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz",
"integrity": "sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==",
"dev": true
}
} }
}, },
"esprima": { "esprima": {
@ -6502,9 +6508,9 @@
} }
}, },
"flatted": { "flatted": {
"version": "2.0.1", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
"integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
"dev": true "dev": true
}, },
"flush-write-stream": { "flush-write-stream": {
@ -9426,9 +9432,9 @@
} }
}, },
"min-indent": { "min-indent": {
"version": "1.0.0", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
"dev": true "dev": true
}, },
"mini-create-react-context": { "mini-create-react-context": {
@ -9657,23 +9663,6 @@
"run-queue": "^1.0.3" "run-queue": "^1.0.3"
} }
}, },
"move-file": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/move-file/-/move-file-2.0.0.tgz",
"integrity": "sha512-cdkdhNCgbP5dvS4tlGxZbD+nloio9GIimP57EjqFhwLcMjnU+XJKAZzlmg/TN/AK1LuNAdTSvm3CPPP4Xkv0iQ==",
"dev": true,
"requires": {
"path-exists": "^4.0.0"
},
"dependencies": {
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
}
}
},
"mozjpeg": { "mozjpeg": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-6.0.1.tgz", "resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-6.0.1.tgz",
@ -11511,9 +11500,9 @@
} }
}, },
"recoil": { "recoil": {
"version": "0.0.7", "version": "0.0.8",
"resolved": "https://registry.npmjs.org/recoil/-/recoil-0.0.7.tgz", "resolved": "https://registry.npmjs.org/recoil/-/recoil-0.0.8.tgz",
"integrity": "sha512-U/0kniHLk131hKhAX35QGdghVf3+PSkLcFIFoNBNy+yv62qCLm3TE5c3v4x4WYzuKgw1fxU3GGhKHAUYdyRnTQ==" "integrity": "sha512-lfIH6y9A0wQ6piucwWFZfpp9KNQ+mFdTPFPFL0m0sRCrfsuwz3lyVaaofHY6/O4BXekDoXyjYodPBgCSdw9HCw=="
}, },
"redent": { "redent": {
"version": "1.0.0", "version": "1.0.0",
@ -11527,9 +11516,9 @@
} }
}, },
"regenerate": { "regenerate": {
"version": "1.4.0", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz",
"integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==",
"dev": true "dev": true
}, },
"regenerate-unicode-properties": { "regenerate-unicode-properties": {
@ -11952,9 +11941,9 @@
"dev": true "dev": true
}, },
"sass": { "sass": {
"version": "1.26.7", "version": "1.26.8",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.26.7.tgz", "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.8.tgz",
"integrity": "sha512-xgNazdkr6yvgHEfNaOjKtZzhDZmKYMCmoRKMPrTDo7YvjaITIzU2DDYsIUuN/atAg7/JOxPeCQHH7TtCo5Tq2g==", "integrity": "sha512-yvtzyrKLGiXQu7H12ekXqsfoGT/aTKeMDyVzCB675k1HYuaj0py63i8Uf4SI9CHXj6apDhpfwbUr3gGOjdpu2Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"chokidar": ">=2.0.0 <4.0.0" "chokidar": ">=2.0.0 <4.0.0"
@ -13005,14 +12994,14 @@
"dev": true "dev": true
}, },
"stylelint": { "stylelint": {
"version": "13.5.0", "version": "13.6.0",
"resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.5.0.tgz", "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.6.0.tgz",
"integrity": "sha512-+Jy7ieKAWKTf2tmcAE7jgScxH39Urb87i0bjK/enScFaGWWaFn4kAPwepGOSk2b7CLUDVt/O6kwA0x0p/V7moQ==", "integrity": "sha512-55gG2pNjVr183JJM/tlr3KAua6vTVX7Ho/lgKKuCIWszTZ1gmrXjX4Wok53SI8wRYFPbwKAcJGULQ77OJxTcNw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@stylelint/postcss-css-in-js": "^0.37.1", "@stylelint/postcss-css-in-js": "^0.37.1",
"@stylelint/postcss-markdown": "^0.36.1", "@stylelint/postcss-markdown": "^0.36.1",
"autoprefixer": "^9.7.6", "autoprefixer": "^9.8.0",
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"cosmiconfig": "^6.0.0", "cosmiconfig": "^6.0.0",
@ -13021,10 +13010,10 @@
"file-entry-cache": "^5.0.1", "file-entry-cache": "^5.0.1",
"get-stdin": "^8.0.0", "get-stdin": "^8.0.0",
"global-modules": "^2.0.0", "global-modules": "^2.0.0",
"globby": "^11.0.0", "globby": "^11.0.1",
"globjoin": "^0.1.4", "globjoin": "^0.1.4",
"html-tags": "^3.1.0", "html-tags": "^3.1.0",
"ignore": "^5.1.4", "ignore": "^5.1.8",
"import-lazy": "^4.0.0", "import-lazy": "^4.0.0",
"imurmurhash": "^0.1.4", "imurmurhash": "^0.1.4",
"known-css-properties": "^0.19.0", "known-css-properties": "^0.19.0",
@ -13035,7 +13024,7 @@
"meow": "^7.0.1", "meow": "^7.0.1",
"micromatch": "^4.0.2", "micromatch": "^4.0.2",
"normalize-selector": "^0.2.0", "normalize-selector": "^0.2.0",
"postcss": "^7.0.30", "postcss": "^7.0.32",
"postcss-html": "^0.36.0", "postcss-html": "^0.36.0",
"postcss-less": "^3.1.4", "postcss-less": "^3.1.4",
"postcss-media-query-parser": "^0.2.3", "postcss-media-query-parser": "^0.2.3",
@ -13043,7 +13032,7 @@
"postcss-resolve-nested-selector": "^0.1.1", "postcss-resolve-nested-selector": "^0.1.1",
"postcss-safe-parser": "^4.0.2", "postcss-safe-parser": "^4.0.2",
"postcss-sass": "^0.4.4", "postcss-sass": "^0.4.4",
"postcss-scss": "^2.0.0", "postcss-scss": "^2.1.1",
"postcss-selector-parser": "^6.0.2", "postcss-selector-parser": "^6.0.2",
"postcss-syntax": "^0.36.2", "postcss-syntax": "^0.36.2",
"postcss-value-parser": "^4.1.0", "postcss-value-parser": "^4.1.0",
@ -13056,7 +13045,7 @@
"sugarss": "^2.0.0", "sugarss": "^2.0.0",
"svg-tags": "^1.0.0", "svg-tags": "^1.0.0",
"table": "^5.4.6", "table": "^5.4.6",
"v8-compile-cache": "^2.1.0", "v8-compile-cache": "^2.1.1",
"write-file-atomic": "^3.0.3" "write-file-atomic": "^3.0.3"
}, },
"dependencies": { "dependencies": {
@ -13177,9 +13166,9 @@
"dev": true "dev": true
}, },
"globby": { "globby": {
"version": "11.0.0", "version": "11.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.0.tgz", "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
"integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==", "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"array-union": "^2.1.0", "array-union": "^2.1.0",
@ -13197,9 +13186,9 @@
"dev": true "dev": true
}, },
"ignore": { "ignore": {
"version": "5.1.6", "version": "5.1.8",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.6.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
"integrity": "sha512-cgXgkypZBcCnOgSihyeqbo6gjIaIyDqPQB7Ra4vhE9m6kigdGoQDMHjviFhRZo3IMlRy6yElosoviMs5YxZXUA==", "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
"dev": true "dev": true
}, },
"import-lazy": { "import-lazy": {
@ -13315,9 +13304,9 @@
"dev": true "dev": true
}, },
"postcss": { "postcss": {
"version": "7.0.30", "version": "7.0.32",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.30.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz",
"integrity": "sha512-nu/0m+NtIzoubO+xdAlwZl/u5S5vi/y6BCsoL8D+8IxsD3XvBS8X4YEADNIVXKVuQvduiucnRv+vPIqj56EGMQ==", "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==",
"dev": true, "dev": true,
"requires": { "requires": {
"chalk": "^2.4.2", "chalk": "^2.4.2",
@ -13835,17 +13824,17 @@
} }
}, },
"terser-webpack-plugin": { "terser-webpack-plugin": {
"version": "3.0.2", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.0.2.tgz", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.0.3.tgz",
"integrity": "sha512-QeBHLJzKJHCnrPNlZj5EmOF6wwvzpVGDHvTrySIH8+jZEXfcKKCiriRmF6945rKzuZDnkOEU/LDv7qtPiiyP/Q==", "integrity": "sha512-bZFnotuIKq5Rqzrs+qIwFzGdKdffV9epG5vDSEbYzvKAhPeR5RbbrQysfPgbIIMhNAQtZD2hGwBfSKUXjXZZZw==",
"dev": true, "dev": true,
"requires": { "requires": {
"cacache": "^15.0.3", "cacache": "^15.0.4",
"find-cache-dir": "^3.3.1", "find-cache-dir": "^3.3.1",
"jest-worker": "^26.0.0", "jest-worker": "^26.0.0",
"p-limit": "^2.3.0", "p-limit": "^2.3.0",
"schema-utils": "^2.6.6", "schema-utils": "^2.6.6",
"serialize-javascript": "^3.0.0", "serialize-javascript": "^3.1.0",
"source-map": "^0.6.1", "source-map": "^0.6.1",
"terser": "^4.6.13", "terser": "^4.6.13",
"webpack-sources": "^1.4.3" "webpack-sources": "^1.4.3"
@ -14247,9 +14236,9 @@
} }
}, },
"typescript": { "typescript": {
"version": "3.9.3", "version": "3.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz",
"integrity": "sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==", "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==",
"dev": true "dev": true
}, },
"unbzip2-stream": { "unbzip2-stream": {
@ -14622,9 +14611,9 @@
"dev": true "dev": true
}, },
"v8-compile-cache": { "v8-compile-cache": {
"version": "2.1.0", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
"integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
"dev": true "dev": true
}, },
"validate-npm-package-license": { "validate-npm-package-license": {

View File

@ -29,28 +29,28 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.10.1", "@babel/cli": "^7.10.1",
"@babel/core": "^7.10.1", "@babel/core": "^7.10.2",
"@babel/preset-env": "^7.10.1", "@babel/preset-env": "^7.10.2",
"@babel/preset-react": "^7.10.1", "@babel/preset-react": "^7.10.1",
"@hot-loader/react-dom": "^16.13.0", "@hot-loader/react-dom": "^16.13.0",
"@types/classnames": "^2.2.10", "@types/classnames": "^2.2.10",
"@types/lodash-es": "^4.17.3", "@types/lodash-es": "^4.17.3",
"@types/node": "^14.0.6", "@types/node": "^14.0.11",
"@types/react": "^16.9.35", "@types/react": "^16.9.35",
"@types/react-dom": "^16.9.8", "@types/react-dom": "^16.9.8",
"@types/react-router-dom": "^5.1.5", "@types/react-router-dom": "^5.1.5",
"@types/react-table": "^7.0.18", "@types/react-table": "^7.0.19",
"@types/react-virtualized-auto-sizer": "^1.0.0", "@types/react-virtualized-auto-sizer": "^1.0.0",
"@types/react-window": "^1.8.2", "@types/react-window": "^1.8.2",
"@types/recoil": "0.0.0", "@types/recoil": "0.0.0",
"@typescript-eslint/eslint-plugin": "^3.0.2", "@typescript-eslint/eslint-plugin": "^3.1.0",
"@typescript-eslint/parser": "^3.0.2", "@typescript-eslint/parser": "^3.1.0",
"autoprefixer": "^9.8.0", "autoprefixer": "^9.8.0",
"awesome-typescript-loader": "^5.2.1", "awesome-typescript-loader": "^5.2.1",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
"babel-preset-minify": "^0.5.1", "babel-preset-minify": "^0.5.1",
"css-loader": "^3.5.3", "css-loader": "^3.5.3",
"eslint": "^7.1.0", "eslint": "^7.2.0",
"eslint-config-standard": "^14.1.1", "eslint-config-standard": "^14.1.1",
"eslint-loader": "^4.0.2", "eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.20.2", "eslint-plugin-import": "^2.20.2",
@ -65,14 +65,14 @@
"offline-plugin": "^5.0.7", "offline-plugin": "^5.0.7",
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
"react-hot-loader": "^4.12.21", "react-hot-loader": "^4.12.21",
"sass": "^1.26.7", "sass": "^1.26.8",
"sass-loader": "^8.0.2", "sass-loader": "^8.0.2",
"style-loader": "^1.2.1", "style-loader": "^1.2.1",
"stylelint": "^13.5.0", "stylelint": "^13.6.0",
"stylelint-config-standard": "^20.0.0", "stylelint-config-standard": "^20.0.0",
"stylelint-webpack-plugin": "^2.0.0", "stylelint-webpack-plugin": "^2.0.0",
"terser-webpack-plugin": "^3.0.2", "terser-webpack-plugin": "^3.0.3",
"typescript": "^3.9.3", "typescript": "^3.9.5",
"webpack": "^4.43.0", "webpack": "^4.43.0",
"webpack-cli": "^3.3.11", "webpack-cli": "^3.3.11",
"webpack-dev-middleware": "^3.7.2", "webpack-dev-middleware": "^3.7.2",
@ -93,7 +93,7 @@
"react-table": "^7.1.0", "react-table": "^7.1.0",
"react-virtualized-auto-sizer": "^1.0.2", "react-virtualized-auto-sizer": "^1.0.2",
"react-window": "^1.8.5", "react-window": "^1.8.5",
"recoil": "0.0.7", "recoil": "0.0.8",
"swr": "^0.2.2", "swr": "^0.2.2",
"use-immer": "^0.4.0" "use-immer": "^0.4.0"
} }

View File

@ -7,14 +7,15 @@ import './style.scss'
interface LoadingProps extends BaseComponentProps { interface LoadingProps extends BaseComponentProps {
visible: boolean visible: boolean
spinnerClassName?: string
} }
export function Loading (props: LoadingProps) { export function Loading (props: LoadingProps) {
const classname = classnames('loading', 'visible') const classname = classnames('loading', 'visible', props.className)
return props.visible return props.visible
? ( ? (
<div className={classname}> <div className={classname}>
<Spinner /> <Spinner className={props.spinnerClassName} />
</div> </div>
) )
: null : null

View File

@ -62,10 +62,12 @@ function ProxyGroups () {
} }
function ProxyProviders () { function ProxyProviders () {
const { providers } = useProxyProviders() const { providers, update } = useProxyProviders()
const { useTranslation } = useI18n() const { useTranslation } = useI18n()
const { t } = useTranslation('Proxies') const { t } = useTranslation('Proxies')
useSWR('providers', update)
return <> return <>
{ {
providers.length !== 0 && providers.length !== 0 &&
@ -134,10 +136,7 @@ function Proxies () {
export default function ProxyContainer () { export default function ProxyContainer () {
const { update: updateProxy } = useProxy() const { update: updateProxy } = useProxy()
const { update: updateProvider } = useProxyProviders()
useSWR('proxies', updateProxy) useSWR('proxies', updateProxy)
useSWR('providers', updateProvider)
return ( return (
<div className="page"> <div className="page">

View File

@ -0,0 +1,48 @@
import * as React from 'react'
import classnames from 'classnames'
import { Card, Tag, Icon } from '@components'
import { useI18n, useRuleProviders } from '@stores'
import { fromNow } from '@lib/date'
import { RuleProvider, updateRuleProvider } from '@lib/request'
import { useVisible } from '@lib/hook'
import './style.scss'
interface ProvidersProps {
provider: RuleProvider
}
export function Provider (props: ProvidersProps) {
const { update } = useRuleProviders()
const { useTranslation, lang } = useI18n()
const { provider } = props
const { t } = useTranslation('Proxies')
const { visible, hide, show } = useVisible()
function handleUpdate () {
show()
updateRuleProvider(provider.name).then(() => update()).finally(() => hide())
}
const updateClassnames = classnames('rule-provider-icon', { 'rule-provider-loading': visible })
return (
<Card className="rule-provider">
<div className="rule-provider-header">
<div className="rule-provider-header-part">
<span className="rule-provider-name">{ provider.name }</span>
<Tag>{ provider.vehicleType }</Tag>
<Tag className="rule-provider-behavior">{ provider.behavior }</Tag>
</div>
<div className="rule-provider-header-part">
{
provider.updatedAt &&
<span className="rule-provider-update">{ `${t('providerUpdateTime')}: ${fromNow(new Date(provider.updatedAt), lang)}`}</span>
}
<Icon className={updateClassnames} type="update" size={18} onClick={handleUpdate} />
</div>
</div>
</Card>
)
}

View File

@ -0,0 +1,79 @@
@import '~@styles/variables';
.rule-provider {
position: relative;
display: flex;
flex-direction: column;
font-size: 16px;
padding: 20px;
color: $color-black-light;
}
.rule-provider-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.rule-provider-header-part {
display: flex;
align-items: center;
}
.rule-provider-name {
width: 120px;
margin-right: 6px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.rule-provider-behavior {
margin-left: 12px;
background-color: $color-primary-dark;
color: #fff;
}
.rule-provider-spinner {
transform: scale(0.4);
}
.rule-provider-proxies {
list-style: none;
}
.rule-provider-item {
box-shadow: 0 0 24px 0 rgba(44, 138, 248, 0.2);
&:hover {
box-shadow: 0 0 24px 0 rgba(84, 117, 154, 0.4);
}
}
.rule-provider-update {
line-height: 14px;
font-size: 14px;
}
.rule-provider-icon {
display: block;
margin-left: 20px;
cursor: pointer;
&.rule-provider-loading::before {
color: $color-gray-darken;
cursor: not-allowed;
animation: spinner 2s infinite linear;
}
}
@media (max-width: 768px) {
.rule-provider-header {
flex-direction: column;
align-items: flex-start;
}
.rule-provider-header-part {
margin: 6px 0;
}
}

View File

@ -1,11 +1,43 @@
import React from 'react' import React, { useLayoutEffect } from 'react'
import { Header, Card, Row, Col } from '@components' import { Header, Card, Row, Col } from '@components'
import { useI18n, useRule } from '@stores' import { useI18n, useRule, useRuleProviders, useVersion } from '@stores'
import { FixedSizeList as List } from 'react-window' import { FixedSizeList as List } from 'react-window'
import AutoSizer from 'react-virtualized-auto-sizer' import AutoSizer from 'react-virtualized-auto-sizer'
import useSWR from 'swr' import useSWR from 'swr'
import { Provider } from './Provider'
import './style.scss' import './style.scss'
function RuleProviders () {
const { providers, update } = useRuleProviders()
const { premium } = useVersion()
const { useTranslation } = useI18n()
const { t } = useTranslation('Rules')
useLayoutEffect(() => {
if (premium) {
update()
}
}, [premium])
return <>
{
providers.length !== 0 &&
<div className="proxies-container">
<Header title={t('providerTitle')} />
<ul className="proxies-providers-list">
{
providers.map(p => (
<li className="proxies-providers-item" key={p.name}>
<Provider provider={p} />
</li>
))
}
</ul>
</div>
}
</>
}
export default function Rules () { export default function Rules () {
const { rules, update } = useRule() const { rules, update } = useRule()
const { useTranslation } = useI18n() const { useTranslation } = useI18n()
@ -34,6 +66,7 @@ export default function Rules () {
return ( return (
<div className="page"> <div className="page">
<RuleProviders />
<Header title={t('title')} /> <Header title={t('title')} />
<Card className="rules-card"> <Card className="rules-card">
<AutoSizer className="rules"> <AutoSizer className="rules">

View File

@ -4,7 +4,7 @@ import { Header, Card, Row, Col, Switch, ButtonSelect, ButtonSelectOptions, Inpu
import { useI18n, useClashXData, useAPIInfo, useGeneral, useIdentity } from '@stores' import { useI18n, useClashXData, useAPIInfo, useGeneral, useIdentity } from '@stores'
import { updateConfig } from '@lib/request' import { updateConfig } from '@lib/request'
import { useObject } from '@lib/hook' import { useObject } from '@lib/hook'
import { isClashX, jsBridge } from '@lib/jsBridge' import { jsBridge } from '@lib/jsBridge'
import { Lang } from '@i18n' import { Lang } from '@i18n'
import './style.scss' import './style.scss'
@ -19,15 +19,12 @@ export default function Settings () {
const { t } = useTranslation('Settings') const { t } = useTranslation('Settings')
const [info, set] = useObject({ const [info, set] = useObject({
socks5ProxyPort: 7891, socks5ProxyPort: 7891,
httpProxyPort: 7890, httpProxyPort: 7890
isClashX: false
}) })
useEffect(() => { useEffect(() => {
fetchGeneral() fetchGeneral()
if (isClashX()) { fetchClashXData()
fetchClashXData().then(() => set('isClashX', true))
}
}, []) }, [])
useEffect(() => { useEffect(() => {
@ -96,7 +93,7 @@ export default function Settings () {
<span className="label">{t('labels.startAtLogin')}</span> <span className="label">{t('labels.startAtLogin')}</span>
</Col> </Col>
<Col span={8} className="value-column"> <Col span={8} className="value-column">
<Switch disabled={!info.isClashX} checked={startAtLogin} onChange={handleStartAtLoginChange} /> <Switch disabled={!clashXData.isClashX} checked={startAtLogin} onChange={handleStartAtLoginChange} />
</Col> </Col>
</Col> </Col>
<Col span={12}> <Col span={12}>
@ -115,7 +112,7 @@ export default function Settings () {
</Col> </Col>
<Col span={8} className="value-column"> <Col span={8} className="value-column">
<Switch <Switch
disabled={!info.isClashX} disabled={!clashXData.isClashX}
checked={systemProxy} checked={systemProxy}
onChange={handleSetSystemProxy} onChange={handleSetSystemProxy}
/> />

View File

@ -1,7 +1,7 @@
import * as React from 'react' import * as React from 'react'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import classnames from 'classnames' import classnames from 'classnames'
import { useI18n, useVersion } from '@stores' import { useI18n, useVersion, useClashXData } from '@stores'
import './style.scss' import './style.scss'
import logo from '@assets/logo.png' import logo from '@assets/logo.png'
@ -20,9 +20,11 @@ export default function Sidebar (props: SidebarProps) {
const { routes } = props const { routes } = props
const { useTranslation } = useI18n() const { useTranslation } = useI18n()
const { version, premium, update } = useVersion() const { version, premium, update } = useVersion()
const { data: { isClashX }, update: updateClashXData } = useClashXData()
const { t } = useTranslation('SideBar') const { t } = useTranslation('SideBar')
useSWR('version', update) useSWR('version', update)
useSWR('clashx', updateClashXData)
const navlinks = routes.map( const navlinks = routes.map(
({ path, name, exact, noMobile }) => ( ({ path, name, exact, noMobile }) => (
@ -39,7 +41,7 @@ export default function Sidebar (props: SidebarProps) {
{ navlinks } { navlinks }
</ul> </ul>
<div className="sidebar-version"> <div className="sidebar-version">
<span className="sidebar-version-label">Clash { t('Version') }</span> <span className="sidebar-version-label">Clash{ isClashX && 'X' } { t('Version') }</span>
<span className="sidebar-version-text">{ version }</span> <span className="sidebar-version-text">{ version }</span>
{ premium && <span className="sidebar-version-label">Premium</span> } { premium && <span className="sidebar-version-label">Premium</span> }
</div> </div>

View File

@ -41,7 +41,9 @@ export default {
title: 'Logs' title: 'Logs'
}, },
Rules: { Rules: {
title: 'Rules' title: 'Rules',
providerTitle: 'Providers',
providerUpdateTime: 'Last updated at'
}, },
Connections: { Connections: {
title: 'Connections', title: 'Connections',

View File

@ -41,7 +41,9 @@ export default {
title: '日志' title: '日志'
}, },
Rules: { Rules: {
title: '规则' title: '规则',
providerTitle: '规则集',
providerUpdateTime: '最后更新于'
}, },
Connections: { Connections: {
title: '连接', title: '连接',

View File

@ -25,23 +25,32 @@ export interface Rule {
} }
export interface Proxies { export interface Proxies {
proxies: { proxies: Record<string, Proxy | Group>
[key: string]: Proxy | Group
}
} }
export interface Provider { export interface Provider {
name: string name: string
proxies: Array<Group | Proxy> proxies: Array<Group | Proxy>
type: 'Proxy' | 'Rule' type: 'Proxy'
vehicleType: 'HTTP' | 'File' | 'Compatible' vehicleType: 'HTTP' | 'File' | 'Compatible'
updatedAt?: string updatedAt?: string
} }
export interface ProxyProviders { export interface RuleProvider {
providers: { name: string
[key: string]: Provider type: 'Rule'
vehicleType: 'HTTP' | 'File'
behavior: string
ruleCount: number
updatedAt?: string
} }
export interface RuleProviders {
providers: Record<string, RuleProvider>
}
export interface ProxyProviders {
providers: Record<string, Provider>
} }
interface History { interface History {
@ -159,11 +168,21 @@ export async function getProxyProviders () {
}) })
} }
export async function getRuleProviders () {
const req = await getInstance()
return req.get<RuleProviders>('providers/rules')
}
export async function updateProvider (name: string) { export async function updateProvider (name: string) {
const req = await getInstance() const req = await getInstance()
return req.put<void>(`providers/proxies/${encodeURIComponent(name)}`) return req.put<void>(`providers/proxies/${encodeURIComponent(name)}`)
} }
export async function updateRuleProvider (name: string) {
const req = await getInstance()
return req.put<void>(`providers/rules/${encodeURIComponent(name)}`)
}
export async function healthCheckProvider (name: string) { export async function healthCheckProvider (name: string) {
const req = await getInstance() const req = await getInstance()
return req.get<void>(`providers/proxies/${encodeURIComponent(name)}/healthcheck`) return req.get<void>(`providers/proxies/${encodeURIComponent(name)}/healthcheck`)

View File

@ -7,7 +7,7 @@ import { getLanguage, setLanguage, Lang, locales, Language } from '@i18n'
import { useRecoilObjectWithImmer } from '@lib/recoil' import { useRecoilObjectWithImmer } from '@lib/recoil'
import * as API from '@lib/request' import * as API from '@lib/request'
import { setLocalStorageItem, partition, to } from '@lib/helper' import { setLocalStorageItem, partition, to } from '@lib/helper'
import { jsBridge } from '@lib/jsBridge' import { jsBridge, isClashX } from '@lib/jsBridge'
import * as Models from '@models' import * as Models from '@models'
const identity = atom({ const identity = atom({
@ -62,6 +62,32 @@ export function useI18n () {
return { lang, locales, setLang, useTranslation } return { lang, locales, setLang, useTranslation }
} }
export const version = atom({
key: 'version',
default: {
version: '',
premium: false
}
})
export function useVersion () {
const [data, set] = useRecoilState(version)
const { set: setIdentity } = useIdentity()
async function update () {
const [resp, err] = await to(API.getVersion())
setIdentity(!err)
set(
err
? { version: '', premium: false }
: { version: resp.data.version, premium: !!resp.data.premium }
)
}
return { version: data.version, premium: data.premium, update }
}
export const config = atom({ export const config = atom({
key: 'config', key: 'config',
default: { default: {
@ -97,6 +123,31 @@ export function useProxyProviders () {
return { providers: data, update } return { providers: data, update }
} }
export const ruleProvider = atom({
key: 'ruleProvider',
default: [] as API.RuleProvider[]
})
export function useRuleProviders () {
const [data, set] = useRecoilState(ruleProvider)
const [{ premium }] = useRecoilState(version)
async function update () {
if (!premium) {
return
}
const ruleProviders = await API.getRuleProviders()
const providers = Object.keys(ruleProviders.data.providers)
.map<API.RuleProvider>(name => ruleProviders.data.providers[name])
set(providers)
}
return { providers: data, update }
}
export const general = atom({ export const general = atom({
key: 'general', key: 'general',
default: {} as Models.Data['general'] default: {} as Models.Data['general']
@ -179,35 +230,10 @@ export const proxyMapping = selector({
} }
}) })
export const version = atom({
key: 'version',
default: {
version: '',
premium: false
}
})
export function useVersion () {
const [data, set] = useRecoilState(version)
const { set: setIdentity } = useIdentity()
async function update () {
const [resp, err] = await to(API.getVersion())
setIdentity(!err)
set(
err
? { version: '', premium: false }
: { version: resp.data.version, premium: !!resp.data.premium }
)
}
return { version: data.version, premium: data.premium, update }
}
export const clashxData = atom({ export const clashxData = atom({
key: 'clashxData', key: 'clashxData',
default: { default: {
isClashX: false,
startAtLogin: false, startAtLogin: false,
systemProxy: false systemProxy: false
} }
@ -217,10 +243,14 @@ export function useClashXData () {
const [data, set] = useRecoilState(clashxData) const [data, set] = useRecoilState(clashxData)
async function update () { async function update () {
if (!isClashX()) {
return
}
const startAtLogin = await jsBridge.getStartAtLogin() const startAtLogin = await jsBridge.getStartAtLogin()
const systemProxy = await jsBridge.isSystemProxySet() const systemProxy = await jsBridge.isSystemProxySet()
set({ startAtLogin, systemProxy }) set({ startAtLogin, systemProxy, isClashX: true })
} }
return { data, update } return { data, update }