diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js index 86634230..3c45e724 100644 --- a/packages/api/src/controllers/plugins.js +++ b/packages/api/src/controllers/plugins.js @@ -106,6 +106,10 @@ module.exports = { // ); }, + async saveRemovePlugins() { + await fs.writeFile(path.join(datadir(), 'removed-plugins'), this.removedPlugins.join('\n')); + }, + install_meta: 'post', async install({ packageName }) { if (!hasPermission(`plugins/install`)) return; @@ -114,6 +118,8 @@ module.exports = { await downloadPackage(packageName, dir); } socket.emitChanged(`installed-plugins-changed`); + this.removedPlugins = this.removedPlugins.filter((x) => x != packageName); + await this.saveRemovePlugins(); }, uninstall_meta: 'post', @@ -123,7 +129,16 @@ module.exports = { await fs.rmdir(dir, { recursive: true }); socket.emitChanged(`installed-plugins-changed`); this.removedPlugins.push(packageName); - await fs.writeFile(path.join(datadir(), 'removed-plugins'), this.removedPlugins.join('\n')); + await this.saveRemovePlugins(); + }, + + upgrade_meta: 'post', + async upgrade({ packageName }) { + if (!hasPermission(`plugins/install`)) return; + const dir = path.join(pluginsdir(), packageName); + await fs.rmdir(dir, { recursive: true }); + await downloadPackage(packageName, dir); + socket.emitChanged(`installed-plugins-changed`); }, command_meta: 'post', diff --git a/packages/web/package.json b/packages/web/package.json index 1ace9649..976de807 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -11,6 +11,7 @@ "ace-builds": "^1.4.8", "axios": "^0.19.0", "chart.js": "^2.9.4", + "compare-versions": "^3.6.0", "cross-env": "^6.0.3", "dbgate-datalib": "^1.0.0", "dbgate-sqltree": "^1.0.0", diff --git a/packages/web/src/tabs/PluginTab.js b/packages/web/src/tabs/PluginTab.js index 811d81f8..55fd55a9 100644 --- a/packages/web/src/tabs/PluginTab.js +++ b/packages/web/src/tabs/PluginTab.js @@ -5,6 +5,7 @@ import Markdown from 'markdown-to-jsx'; import useTheme from '../theme/useTheme'; import useFetch from '../utility/useFetch'; import LoadingInfo from '../widgets/LoadingInfo'; +import compareVersions from 'compare-versions'; import { extractPluginIcon, extractPluginAuthor } from '../plugins/manifestExtractors'; import FormStyledButton from '../widgets/FormStyledButton'; import axios from '../utility/axios'; @@ -72,13 +73,18 @@ function PluginTabCore({ packageName }) { const handleUninstall = async () => { axios.post('plugins/uninstall', { packageName }); }; + const handleUpgrade = async () => { + axios.post('plugins/upgrade', { packageName }); + }; if (info == null) { return ; } + const installedFound = installed.find((x) => x.name == packageName); + const onlineFound = manifest; + if (manifest == null) { - const installedFound = installed.find((x) => x.name == packageName); if (installedFound) { manifest = installedFound; readme = installedFound.readme; @@ -97,15 +103,21 @@ function PluginTabCore({ packageName }) { {extractPluginAuthor(manifest)} - {manifest.version && manifest.version} + {installedFound ? installedFound.version : manifest.version} - {hasPermission('plugins/install') && !installed.find((x) => x.name == packageName) && ( + {hasPermission('plugins/install') && !installedFound && ( )} - {hasPermission('plugins/install') && !!installed.find((x) => x.name == packageName) && ( + {hasPermission('plugins/install') && !!installedFound && ( )} + {hasPermission('plugins/install') && + installedFound && + onlineFound && + compareVersions(onlineFound.version, installedFound.version) > 0 && ( + + )} @@ -122,3 +134,5 @@ export default function PluginTab({ packageName }) { ); } + +PluginTab.matchingProps = ['packageName']; diff --git a/yarn.lock b/yarn.lock index 6346d073..3ed60528 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3262,6 +3262,11 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= +compare-versions@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" + integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== + component-bind@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"