mirror of
https://github.com/Eugeny/tabby.git
synced 2026-08-24 02:34:19 -05:00
clean up the plugin manager
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import { app } from 'electron'
|
||||
import * as nodeModule from 'module'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
|
||||
// This module is imported before any other main-process module so that errors thrown
|
||||
// while importing those modules (which run before index.ts's own body) still get logged.
|
||||
nodeModule.enableCompileCache?.()
|
||||
|
||||
export function logMainError (label: string, err: unknown): void {
|
||||
const detail = err instanceof Error ? err.stack ?? err.message : String(err)
|
||||
|
||||
@@ -11,7 +11,6 @@ import 'dotenv/config'
|
||||
process.env.TABBY_PLUGINS ??= ''
|
||||
process.env.TABBY_CONFIG_DIRECTORY ??= app.getPath('userData')
|
||||
|
||||
import 'v8-compile-cache'
|
||||
import 'source-map-support/register'
|
||||
import './sentry'
|
||||
import './lru'
|
||||
|
||||
@@ -1,40 +1,17 @@
|
||||
import { promisify } from 'util'
|
||||
|
||||
import Arborist from '@npmcli/arborist'
|
||||
|
||||
// Arborist is npm's own install engine, used in-process so we don't have to bundle the 18 MB npm CLI
|
||||
// and run it via ELECTRON_RUN_AS_NODE. reify() resolves and installs the full dependency tree.
|
||||
export class PluginManager {
|
||||
npm: any
|
||||
npmReady?: Promise<void>
|
||||
|
||||
async ensureLoaded (): Promise<void> {
|
||||
if (!this.npmReady) {
|
||||
this.npmReady = new Promise(resolve => {
|
||||
const npm = require('npm')
|
||||
npm.load(err => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
return
|
||||
}
|
||||
npm.config.set('global', false)
|
||||
this.npm = npm
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
return this.npmReady
|
||||
async install (targetPath: string, name: string, version: string): Promise<void> {
|
||||
await new Arborist({ path: targetPath, save: false, audit: false, fund: false })
|
||||
.reify({ add: [`${name}@${version}`] })
|
||||
}
|
||||
|
||||
async install (path: string, name: string, version: string): Promise<void> {
|
||||
await this.ensureLoaded()
|
||||
this.npm.prefix = path
|
||||
return promisify(this.npm.commands.install)([`${name}@${version}`])
|
||||
}
|
||||
|
||||
async uninstall (path: string, name: string): Promise<void> {
|
||||
await this.ensureLoaded()
|
||||
this.npm.prefix = path
|
||||
return promisify(this.npm.commands.remove)([name])
|
||||
async uninstall (targetPath: string, name: string): Promise<void> {
|
||||
await new Arborist({ path: targetPath, save: false })
|
||||
.reify({ rm: [name] })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const pluginManager = new PluginManager()
|
||||
|
||||
+3
-7
@@ -16,6 +16,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2",
|
||||
"@npmcli/arborist": "^9",
|
||||
"any-promise": "^1.3.0",
|
||||
"atomically": "^2.0.2",
|
||||
"dunder-proto": "^1",
|
||||
@@ -30,11 +31,9 @@
|
||||
"mz": "^2.7.0",
|
||||
"native-process-working-directory": "^1.0.2",
|
||||
"node-pty": "^1.2.0-beta.8",
|
||||
"npm": "12",
|
||||
"russh": "0.1.37",
|
||||
"rxjs": "^7.5.7",
|
||||
"source-map-support": "^0.5.20",
|
||||
"v8-compile-cache": "^2.3.0",
|
||||
"yargs": "^17.7.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
@@ -49,7 +48,7 @@
|
||||
"devDependencies": {
|
||||
"@ngx-translate/core": "^14.0.0",
|
||||
"@types/mz": "2.7.4",
|
||||
"@types/node": "20.3.1"
|
||||
"@types/node": "22"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tabby-community-color-schemes": "*",
|
||||
@@ -66,9 +65,6 @@
|
||||
"node-abi": "4.9.0",
|
||||
"node-gyp": "^10.0.0",
|
||||
"nan": "2.22.2",
|
||||
"node-addon-api": "^8.3.0",
|
||||
"string-width": "^4.2.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
"node-addon-api": "^8.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'v8-compile-cache'
|
||||
require('module').enableCompileCache?.()
|
||||
|
||||
import '../lib/lru'
|
||||
import 'source-sans-pro/source-sans-pro.css'
|
||||
import 'source-code-pro/source-code-pro.css'
|
||||
|
||||
@@ -36,7 +36,6 @@ const config = {
|
||||
],
|
||||
},
|
||||
externals: {
|
||||
'v8-compile-cache': 'commonjs v8-compile-cache',
|
||||
'any-promise': 'commonjs any-promise',
|
||||
electron: 'commonjs electron',
|
||||
'electron-config': 'commonjs electron-config',
|
||||
@@ -46,7 +45,7 @@ const config = {
|
||||
fs: 'commonjs fs',
|
||||
glasstron: 'commonjs glasstron',
|
||||
mz: 'commonjs mz',
|
||||
npm: 'commonjs npm',
|
||||
'@npmcli/arborist': 'commonjs @npmcli/arborist',
|
||||
'node:os': 'commonjs os',
|
||||
'node-pty': 'commonjs node-pty',
|
||||
path: 'commonjs path',
|
||||
|
||||
@@ -72,7 +72,6 @@ export default () => ({
|
||||
},
|
||||
externals: {
|
||||
'@electron/remote': 'commonjs @electron/remote',
|
||||
'v8-compile-cache': 'commonjs v8-compile-cache',
|
||||
child_process: 'commonjs child_process',
|
||||
electron: 'commonjs electron',
|
||||
fs: 'commonjs fs',
|
||||
|
||||
+418
-677
File diff suppressed because it is too large
Load Diff
@@ -34,29 +34,26 @@ ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav')
|
||||
strong.d-block {{plugin.name}}
|
||||
small.d-block.text-muted {{plugin.description}}
|
||||
ng-template(ngbPanelContent)
|
||||
.row
|
||||
.col-4
|
||||
div.d-flex.flex-column.flex-md-row.gap-2
|
||||
button.btn.btn-primary.btn-block.justify-content-center(
|
||||
(click)='installPlugin(plugin)',
|
||||
[disabled]='busy.has(plugin.name)'
|
||||
)
|
||||
i.fas.fa-fw.fa-cloud-download(*ngIf='busy.get(plugin.name) != BusyState.Installing')
|
||||
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
|
||||
span.ms-2(translate) Get
|
||||
|
||||
button.btn.btn-secondary.btn-block.justify-content-center(
|
||||
*ngIf='plugin.homepage',
|
||||
(click)='showPluginHomepage(plugin)'
|
||||
)
|
||||
i.fas.fa-fw.fa-external-link-alt
|
||||
span.ms-2(translate) Homepage
|
||||
.d-flex.flex-column.flex-md-row.gap-3.align-items-start
|
||||
button.btn.btn-primary.btn-block.justify-content-center(
|
||||
(click)='installPlugin(plugin)',
|
||||
[disabled]='busy.has(plugin.name)'
|
||||
)
|
||||
i.fas.fa-fw.fa-cloud-download(*ngIf='busy.get(plugin.name) != BusyState.Installing')
|
||||
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
|
||||
span.ms-2(translate) Get
|
||||
|
||||
.col-8
|
||||
button.btn.btn-secondary.btn-block.justify-content-center(
|
||||
*ngIf='plugin.homepage',
|
||||
(click)='showPluginHomepage(plugin)'
|
||||
)
|
||||
i.fas.fa-fw.fa-external-link-alt
|
||||
span.ms-2(translate) Homepage
|
||||
|
||||
.ms-auto
|
||||
div
|
||||
ng-container(*ngTemplateOutlet='pluginInfo; context: { plugin }')
|
||||
|
||||
.mt-2 {{plugin.description}}
|
||||
|
||||
li(ngbNavItem)
|
||||
a(ngbNavLink, translate) Installed
|
||||
ng-template(ngbNavContent)
|
||||
@@ -94,49 +91,44 @@ ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav')
|
||||
)
|
||||
|
||||
ng-template(ngbPanelContent)
|
||||
.row
|
||||
.col-4
|
||||
button.btn.btn-warning.btn-block.justify-content-center(
|
||||
(click)='togglePlugin(plugin)',
|
||||
*ngIf='isPluginEnabled(plugin)',
|
||||
[disabled]='!canDisablePlugin(plugin)',
|
||||
translate
|
||||
) Disable
|
||||
.d-flex.flex-column.flex-md-row.gap-3.align-items-start
|
||||
button.btn.btn-warning.btn-block.justify-content-center(
|
||||
(click)='togglePlugin(plugin)',
|
||||
*ngIf='isPluginEnabled(plugin)',
|
||||
[disabled]='!canDisablePlugin(plugin)',
|
||||
translate
|
||||
) Disable
|
||||
|
||||
button.btn.btn-success.btn-block.justify-content-center(
|
||||
(click)='togglePlugin(plugin)',
|
||||
*ngIf='canDisablePlugin(plugin) && !isPluginEnabled(plugin)',
|
||||
translate
|
||||
) Enable
|
||||
button.btn.btn-success.btn-block.justify-content-center(
|
||||
(click)='togglePlugin(plugin)',
|
||||
*ngIf='canDisablePlugin(plugin) && !isPluginEnabled(plugin)',
|
||||
translate
|
||||
) Enable
|
||||
|
||||
button.btn.btn-danger.btn-block.justify-content-center(
|
||||
(click)='uninstallPlugin(plugin)',
|
||||
*ngIf='!plugin.isBuiltin',
|
||||
[disabled]='busy.has(plugin.name)'
|
||||
)
|
||||
i.fas.fa-fw.fa-trash(*ngIf='busy.get(plugin.name) != BusyState.Uninstalling')
|
||||
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Uninstalling')
|
||||
span(translate) Uninstall
|
||||
.col-8
|
||||
button.btn.btn-danger.btn-block.justify-content-center(
|
||||
(click)='uninstallPlugin(plugin)',
|
||||
*ngIf='!plugin.isBuiltin',
|
||||
[disabled]='busy.has(plugin.name)'
|
||||
)
|
||||
i.fas.fa-fw.fa-trash(*ngIf='busy.get(plugin.name) != BusyState.Uninstalling')
|
||||
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Uninstalling')
|
||||
span(translate) Uninstall
|
||||
|
||||
.ms-auto
|
||||
div
|
||||
ng-container(*ngTemplateOutlet='pluginInfo; context: { plugin }')
|
||||
|
||||
.mt-2 {{plugin.description}}
|
||||
|
||||
ng-template(#pluginInfo, let-plugin='plugin')
|
||||
.row.align-items-center
|
||||
.col-4
|
||||
strong(translate) Version
|
||||
.col-8
|
||||
span {{plugin.version}}
|
||||
.row.align-items-center
|
||||
.col-4
|
||||
strong(translate) Author
|
||||
.col-8
|
||||
.badge.text-bg-success(*ngIf='plugin.isOfficial')
|
||||
i.fas.fa-check
|
||||
span.ms-1(translate) Official
|
||||
a.btn.btn-link.px-0.w-auto((click)='showPluginInfo(plugin)', *ngIf='!plugin.isOfficial')
|
||||
span {{plugin.author}}
|
||||
i.fas.fa-fw.fa-external-link-alt.ms-2
|
||||
.d-flex.align-items-center.gap-3
|
||||
strong(translate) Version
|
||||
span {{plugin.version}}
|
||||
.d-flex.align-items-center.gap-3
|
||||
strong(translate) Author
|
||||
.badge.text-bg-success(*ngIf='plugin.isOfficial')
|
||||
i.fas.fa-check
|
||||
span.ms-1(translate) Official
|
||||
a.btn.btn-link.px-0.w-auto((click)='showPluginInfo(plugin)', *ngIf='!plugin.isOfficial')
|
||||
span {{plugin.author}}
|
||||
i.fas.fa-fw.fa-external-link-alt.ms-2
|
||||
|
||||
.mb-4([ngbNavOutlet]='nav')
|
||||
|
||||
@@ -124,7 +124,8 @@ export class PluginsSettingsTabComponent {
|
||||
}
|
||||
|
||||
async upgradePlugin (plugin: PluginInfo): Promise<void> {
|
||||
return this.installPlugin(this.knownUpgrades[plugin.name]!)
|
||||
await this.installPlugin(this.knownUpgrades[plugin.name]!)
|
||||
this.knownUpgrades[plugin.name] = null
|
||||
}
|
||||
|
||||
showPluginInfo (plugin: PluginInfo) {
|
||||
|
||||
@@ -60,7 +60,7 @@ export class PluginManagerService {
|
||||
description: item.package.description,
|
||||
version: item.package.version,
|
||||
homepage: item.package.links.homepage,
|
||||
author: item.package.author?.name,
|
||||
author: item.package.maintainers?.[0]?.username,
|
||||
isOfficial: item.package.publisher.username === OFFICIAL_NPM_ACCOUNT,
|
||||
searchScore: item.searchScore,
|
||||
})),
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"author": "Tabby Developers",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "14.14.14",
|
||||
"@types/node": "22",
|
||||
"ansi-colors": "^4.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
+11
-4
@@ -2,12 +2,19 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@14.14.14":
|
||||
version "14.14.14"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.14.tgz#f7fd5f3cc8521301119f63910f0fb965c7d761ae"
|
||||
integrity sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ==
|
||||
"@types/node@22":
|
||||
version "22.20.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.20.1.tgz#84e7cdf63cdaa20c134aa317ccc901aa21e16f0e"
|
||||
integrity sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==
|
||||
dependencies:
|
||||
undici-types "~6.21.0"
|
||||
|
||||
ansi-colors@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
|
||||
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
|
||||
|
||||
undici-types@~6.21.0:
|
||||
version "6.21.0"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb"
|
||||
integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"author": "Tabby Developers",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "20.3.1",
|
||||
"@types/node": "22",
|
||||
"ansi-colors": "^4.1.1",
|
||||
"strip-ansi": "^7.0.0"
|
||||
},
|
||||
|
||||
+11
-4
@@ -9,10 +9,12 @@
|
||||
dependencies:
|
||||
ipv6 "*"
|
||||
|
||||
"@types/node@20.3.1":
|
||||
version "20.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe"
|
||||
integrity sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==
|
||||
"@types/node@22":
|
||||
version "22.20.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.20.1.tgz#84e7cdf63cdaa20c134aa317ccc901aa21e16f0e"
|
||||
integrity sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==
|
||||
dependencies:
|
||||
undici-types "~6.21.0"
|
||||
|
||||
ansi-colors@^4.1.1:
|
||||
version "4.1.3"
|
||||
@@ -185,6 +187,11 @@ tmp@^0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.7.tgz#26f4db11d1601ce8012dcb8a798ece1c06a99059"
|
||||
integrity sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==
|
||||
|
||||
undici-types@~6.21.0:
|
||||
version "6.21.0"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb"
|
||||
integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==
|
||||
|
||||
winston@0.8.x:
|
||||
version "0.8.3"
|
||||
resolved "https://registry.yarnpkg.com/winston/-/winston-0.8.3.tgz#64b6abf4cd01adcaefd5009393b1d8e8bec19db0"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"ansi-colors": "^4.1.1",
|
||||
"@types/node": "14.14.31"
|
||||
"@types/node": "22"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/animations": "^15",
|
||||
|
||||
+11
-4
@@ -2,12 +2,19 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@14.14.31":
|
||||
version "14.14.31"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
|
||||
integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
|
||||
"@types/node@22":
|
||||
version "22.20.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.20.1.tgz#84e7cdf63cdaa20c134aa317ccc901aa21e16f0e"
|
||||
integrity sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==
|
||||
dependencies:
|
||||
undici-types "~6.21.0"
|
||||
|
||||
ansi-colors@^4.1.1:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b"
|
||||
integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==
|
||||
|
||||
undici-types@~6.21.0:
|
||||
version "6.21.0"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb"
|
||||
integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git a/node_modules/browserify-sign/browser/index.js b/node_modules/browserify-sign/browser/index.js
|
||||
index e6df44c..641e18e 100644
|
||||
--- a/node_modules/browserify-sign/browser/index.js
|
||||
+++ b/node_modules/browserify-sign/browser/index.js
|
||||
@@ -11,6 +11,8 @@ Object.keys(algorithms).forEach(function (key) {
|
||||
algorithms[key.toLowerCase()] = algorithms[key]
|
||||
})
|
||||
|
||||
+algorithms['sha1'] = algorithms['RSA-SHA1']
|
||||
+
|
||||
function Sign (algorithm) {
|
||||
stream.Writable.call(this)
|
||||
|
||||
Reference in New Issue
Block a user