Compare commits

..

40 Commits

Author SHA1 Message Date
Eugene Pankov
aaab475e5f fixed ssh sessions - fixes #3282 2021-01-03 18:33:03 +01:00
Eugene Pankov
e6bf76c616 reenabled @typescript-eslint/no-shadow 2021-01-02 20:53:34 +01:00
Eugene Pankov
e36bad2553 reenabled @typescript-eslint/no-unnecessary-type-assertion 2021-01-02 20:48:37 +01:00
Eugene Pankov
154cc29333 reenabled @typescript-eslint/no-untyped-public-signature 2021-01-02 20:38:45 +01:00
Eugene Pankov
1b0402c2cf reenabled @typescript-eslint/no-base-to-string 2021-01-02 20:33:32 +01:00
Eugene Pankov
15073cbc81 reenabled @typescript-eslint/no-dynamic-delete 2021-01-02 20:31:26 +01:00
Eugene Pankov
3365b143d8 fixes 2021-01-02 20:24:26 +01:00
Eugene Pankov
4d9cc91e91 reenabled @typescript-eslint/no-unnecessary-condition 2021-01-02 20:10:00 +01:00
Eugene Pankov
946f4292ef reenabled @typescript-eslint/prefer-nullish-coalescing 2021-01-02 19:09:34 +01:00
Eugene
eb12b1ae60 Merge pull request #3245 from Eugeny/dependabot/npm_and_yarn/style-loader-2.0.0
Bump style-loader from 1.3.0 to 2.0.0
2021-01-02 18:17:17 +01:00
Eugene
4765c97d31 Merge pull request #3173 from Eugeny/dependabot/npm_and_yarn/terminus-ssh/types/ssh2-0.5.46
Bump @types/ssh2 from 0.5.44 to 0.5.46 in /terminus-ssh
2021-01-02 18:16:20 +01:00
Eugene Pankov
3fb32e1a97 allow changing installation path - fixes #3267 2021-01-02 13:15:27 +01:00
Eugene Pankov
9ec1a0d253 theme fix 2021-01-02 13:12:12 +01:00
Eugene Pankov
fef19615bb fixed macOS vibrancy 2021-01-02 13:08:00 +01:00
Eugene Pankov
4d237baf33 Update hostApp.service.ts 2021-01-02 12:19:08 +01:00
Eugene Pankov
03e654b5a0 further reduce bundle 2021-01-02 11:49:56 +01:00
Eugene Pankov
ef815eaa40 Merge branch 'master' of github.com:Eugeny/terminus 2021-01-02 11:49:49 +01:00
Eugene Pankov
4771a38747 added nightly links for all platforms 2021-01-02 11:49:47 +01:00
Eugene
ce016793d4 Merge pull request #3079 from Eugeny/dependabot/npm_and_yarn/npm-user-validate-1.0.1
Bump npm-user-validate from 1.0.0 to 1.0.1
2021-01-02 11:19:12 +01:00
Eugene
3a854f04e1 Merge pull request #3233 from Eugeny/dependabot/npm_and_yarn/tar-fs-1.16.3
Bump tar-fs from 1.15.3 to 1.16.3
2021-01-02 11:18:41 +01:00
Eugene
b5658d61d9 Merge pull request #3234 from Eugeny/dependabot/npm_and_yarn/fstream-1.0.12
Bump fstream from 1.0.11 to 1.0.12
2021-01-02 11:18:24 +01:00
Eugene
02750d8581 Merge pull request #3231 from Eugeny/dependabot/npm_and_yarn/http-proxy-agent-2.1.0
Bump http-proxy-agent from 2.0.0 to 2.1.0
2021-01-02 11:18:12 +01:00
Eugene
077a3e6bba Merge pull request #3232 from Eugeny/dependabot/npm_and_yarn/stringstream-0.0.6
Bump stringstream from 0.0.5 to 0.0.6
2021-01-02 11:17:38 +01:00
Eugene Pankov
5454be032a Update windows.yml 2021-01-02 11:03:20 +01:00
Eugene Pankov
8a0b4f82db leaner build 2021-01-02 10:41:04 +01:00
Eugene Pankov
74fd1aeea5 Update linux.yml 2021-01-02 10:33:39 +01:00
Eugene Pankov
aac230e362 Update macos.yml 2021-01-02 10:20:44 +01:00
dependabot[bot]
ae82ed4a47 Bump http-proxy-agent from 2.0.0 to 2.1.0
Bumps [http-proxy-agent](https://github.com/TooTallNate/node-http-proxy-agent) from 2.0.0 to 2.1.0.
- [Release notes](https://github.com/TooTallNate/node-http-proxy-agent/releases)
- [Changelog](https://github.com/TooTallNate/node-http-proxy-agent/blob/2.1.0/History.md)
- [Commits](https://github.com/TooTallNate/node-http-proxy-agent/compare/2.0.0...2.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-01 22:13:13 +00:00
dependabot[bot]
9d1b0e9861 Bump npm-user-validate from 1.0.0 to 1.0.1
Bumps [npm-user-validate](https://github.com/npm/npm-user-validate) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/npm/npm-user-validate/releases)
- [Commits](https://github.com/npm/npm-user-validate/compare/v1.0.0...v1.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-01 22:13:10 +00:00
Eugene Pankov
8cb4e9f27d wip 2021-01-01 22:27:20 +01:00
Eugene Pankov
c8c00a2c9b wip 2021-01-01 22:23:27 +01:00
Eugene Pankov
bacb475896 merged node-pty n-api migration - potentially fixing #3261 2021-01-01 14:30:45 +01:00
Eugene Pankov
c8faa67083 fixed plugin installation - fixes #3264 2020-12-30 19:43:37 +01:00
dependabot[bot]
b6c0e3cdfb Bump tar-fs from 1.15.3 to 1.16.3
Bumps [tar-fs](https://github.com/mafintosh/tar-fs) from 1.15.3 to 1.16.3.
- [Release notes](https://github.com/mafintosh/tar-fs/releases)
- [Commits](https://github.com/mafintosh/tar-fs/compare/v1.15.3...v1.16.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-30 18:37:57 +00:00
Eugene
323581d513 Merge pull request #3235 from Eugeny/dependabot/npm_and_yarn/electron-builder-22.10.4
Bump electron-builder from 22.10.3 to 22.10.4
2020-12-30 19:37:02 +01:00
dependabot-preview[bot]
21b81f476c Bump electron-builder from 22.10.3 to 22.10.4
Bumps [electron-builder](https://github.com/electron-userland/electron-builder) from 22.10.3 to 22.10.4.
- [Release notes](https://github.com/electron-userland/electron-builder/releases)
- [Changelog](https://github.com/electron-userland/electron-builder/blob/master/CHANGELOG.md)
- [Commits](https://github.com/electron-userland/electron-builder/compare/v22.10.3...v22.10.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-27 12:06:23 +00:00
dependabot-preview[bot]
2283a5dad9 Bump style-loader from 1.3.0 to 2.0.0
Bumps [style-loader](https://github.com/webpack-contrib/style-loader) from 1.3.0 to 2.0.0.
- [Release notes](https://github.com/webpack-contrib/style-loader/releases)
- [Changelog](https://github.com/webpack-contrib/style-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/style-loader/compare/v1.3.0...v2.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-25 04:26:28 +00:00
dependabot-preview[bot]
d7565e497d Bump @types/ssh2 from 0.5.44 to 0.5.46 in /terminus-ssh
Bumps [@types/ssh2](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ssh2) from 0.5.44 to 0.5.46.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ssh2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-24 17:45:09 +00:00
dependabot[bot]
7b4e99fc5f Bump fstream from 1.0.11 to 1.0.12
Bumps [fstream](https://github.com/npm/fstream) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/npm/fstream/releases)
- [Commits](https://github.com/npm/fstream/compare/v1.0.11...v1.0.12)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-24 17:44:21 +00:00
dependabot[bot]
035a6f8da8 Bump stringstream from 0.0.5 to 0.0.6
Bumps [stringstream](https://github.com/mhart/StringStream) from 0.0.5 to 0.0.6.
- [Release notes](https://github.com/mhart/StringStream/releases)
- [Commits](https://github.com/mhart/StringStream/compare/v0.0.5...v0.0.6)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-24 17:44:15 +00:00
78 changed files with 2795 additions and 1307 deletions

View File

@@ -29,7 +29,6 @@ rules:
'@typescript-eslint/no-magic-numbers': off
'@typescript-eslint/member-delimiter-style': off
'@typescript-eslint/promise-function-async': off
'@typescript-eslint/no-unnecessary-type-assertion': off
'@typescript-eslint/require-array-sort-compare': off
'@typescript-eslint/no-floating-promises': off
'@typescript-eslint/prefer-readonly': off
@@ -95,25 +94,22 @@ rules:
- error
- single
- allowTemplateLiterals: true
'@typescript-eslint/no-confusing-void-expression': off
'@typescript-eslint/no-non-null-assertion': off
'@typescript-eslint/no-unnecessary-condition': off
'@typescript-eslint/no-untyped-public-signature': off # bugs out on constructors
'@typescript-eslint/no-unnecessary-condition':
- error
- allowConstantLoopConditions: true
'@typescript-eslint/restrict-template-expressions': off
'@typescript-eslint/no-dynamic-delete': off
'@typescript-eslint/prefer-nullish-coalescing': off
'@typescript-eslint/prefer-readonly-parameter-types': off
'@typescript-eslint/no-unsafe-member-access': off
'@typescript-eslint/no-unsafe-call': off
'@typescript-eslint/no-unsafe-return': off
'@typescript-eslint/no-base-to-string': off # broken in typescript-eslint
'@typescript-eslint/no-unsafe-assignment': off
'@typescript-eslint/naming-convention': off
'@typescript-eslint/lines-between-class-members':
- error
- exceptAfterSingleLine: true
'@typescript-eslint/dot-notation': off
'@typescript-eslint/no-confusing-void-expression': off
'@typescript-eslint/no-implicit-any-catch': off
'@typescript-eslint/member-ordering': off
'@typescript-eslint/no-var-requires': off
'@typescript-eslint/no-shadow': off

View File

@@ -36,6 +36,7 @@ jobs:
env:
DEBUG: electron-builder,electron-builder:*
GH_TOKEN: ${{ secrets.GH_TOKEN }}
USE_HARD_LINKS: false
- name: Package artifacts
run: |

View File

@@ -52,6 +52,7 @@ jobs:
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
APPSTORE_USERNAME: ${{ secrets.APPSTORE_USERNAME }}
APPSTORE_PASSWORD: ${{ secrets.APPSTORE_PASSWORD }}
USE_HARD_LINKS: false
# DEBUG: electron-builder,electron-builder:*
- name: Build packages without signing

View File

@@ -11,7 +11,7 @@ jobs:
- name: Installing Node
uses: actions/setup-node@v1
with:
node-version: 15
node-version: 14
- name: Build
shell: powershell

View File

@@ -1,12 +1,12 @@
![](https://github.com/Eugeny/terminus/raw/master/docs/readme.png)
****![](https://github.com/Eugeny/terminus/raw/master/docs/readme.png)
<p align="center">
<a href="https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/eugeny/terminus.svg?label=License&style=flat-square"></a> <a href="https://ci.appveyor.com/project/Eugeny/terminus"><img alt="AppVeyor" src="https://img.shields.io/appveyor/ci/eugeny/terminus.svg?label=CI&logo=appveyor&logoColor=white&style=flat-square"></a>
<a href="https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/eugeny/terminus.svg?label=License&style=flat-square"></a> <a href="https://ci.appveyor.com/project/Eugeny/terminus"><img alt="AppVeyor" src="https://img.shields.io/appveyor/ci/eugeny/****terminus****.svg?label=CI&logo=appveyor&logoColor=white&style=flat-square"></a>
</p>
<p align="center">
<a href="https://github.com/Eugeny/terminus/releases/latest"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/eugeny/terminus/total.svg?label=DOWNLOAD&logo=github&style=for-the-badge"></a> <a href="https://ci.appveyor.com/project/Eugeny/terminus/build/artifacts"><img src="https://img.shields.io/badge/download-nightly%20build-magenta.svg?logo=appveyor&style=for-the-badge"/></a> <a href="https://gitter.im/terminus-terminal/community"><img alt="Gitter" src="https://img.shields.io/gitter/room/terminus/community.svg?color=blue&logo=gitter&style=for-the-badge"></a>
<a href="https://github.com/Eugeny/terminus/releases/latest"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/eugeny/terminus/total.svg?label=RELEASE&logo=github&style=for-the-badge"></a> <a href="https://nightly.link/Eugeny/terminus/workflows/windows/master"><img src="https://shields.io/badge/-Nightly-blue?logo=windows&style=for-the-badge"/></a> <a href="https://nightly.link/Eugeny/terminus/workflows/macos/master"><img src="https://shields.io/badge/-Nightly-black?logo=apple&style=for-the-badge"/></a> <a href="https://nightly.link/Eugeny/terminus/workflows/linux/master"><img src="https://shields.io/badge/-Nightly-orange?logo=linux&style=for-the-badge"/></a> <a href="https://gitter.im/terminus-terminal/community"><img alt="Gitter" src="https://img.shields.io/gitter/room/terminus/community.svg?color=magenta&logo=gitter&style=for-the-badge"></a>
</p>
----

View File

@@ -1,9 +1,11 @@
import { app, ipcMain, Menu, Tray, shell, screen, globalShortcut, MenuItemConstructorOptions } from 'electron'
import * as promiseIpc from 'electron-promise-ipc'
import { loadConfig } from './config'
import { Window, WindowOptions } from './window'
import { pluginManager } from './pluginManager'
export class Application {
private tray: Tray
private tray?: Tray
private windows: Window[] = []
constructor () {
@@ -20,6 +22,14 @@ export class Application {
}
})
;(promiseIpc as any).on('plugin-manager:install', (path, name, version) => {
return pluginManager.install(path, name, version)
})
;(promiseIpc as any).on('plugin-manager:uninstall', (path, name) => {
return pluginManager.uninstall(path, name)
})
const configData = loadConfig()
if (process.platform === 'linux') {
app.commandLine.appendSwitch('no-sandbox')
@@ -121,10 +131,8 @@ export class Application {
}
disableTray (): void {
if (this.tray) {
this.tray.destroy()
this.tray = null
}
this.tray?.destroy()
this.tray = null
}
hasWindows (): boolean {

View File

@@ -5,7 +5,7 @@ export function parseArgs (argv: string[], cwd: string): any {
argv = argv.slice(1)
}
return require('yargs')
return require('yargs/yargs')(argv.slice(1))
.usage('terminus [command] [arguments]')
.command('open [directory]', 'open a shell in a directory', {
directory: { type: 'string', 'default': cwd },
@@ -41,5 +41,5 @@ export function parseArgs (argv: string[], cwd: string): any {
type: 'boolean',
})
.help('help')
.parse(argv.slice(1))
.parse()
}

View File

@@ -1,4 +1,5 @@
import './portable'
import 'source-map-support/register'
import './sentry'
import './lru'
import { app, ipcMain, Menu } from 'electron'

40
app/lib/pluginManager.ts Normal file
View File

@@ -0,0 +1,40 @@
import { promisify } from 'util'
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 (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])
}
}
export const pluginManager = new PluginManager()

View File

@@ -8,17 +8,15 @@ try {
appPath = path.dirname(require('electron').remote.app.getPath('exe'))
}
if (null != appPath) {
if (fs.existsSync(path.join(appPath, 'terminus-data'))) {
fs.renameSync(path.join(appPath, 'terminus-data'), path.join(appPath, 'data'))
}
const portableData = path.join(appPath, 'data')
if (fs.existsSync(portableData)) {
console.log('reset user data to ' + portableData)
try {
require('electron').app.setPath('userData', portableData)
} catch {
require('electron').remote.app.setPath('userData', portableData)
}
if (fs.existsSync(path.join(appPath, 'terminus-data'))) {
fs.renameSync(path.join(appPath, 'terminus-data'), path.join(appPath, 'data'))
}
const portableData = path.join(appPath, 'data')
if (fs.existsSync(portableData)) {
console.log('reset user data to ' + portableData)
try {
require('electron').app.setPath('userData', portableData)
} catch {
require('electron').remote.app.setPath('userData', portableData)
}
}

View File

@@ -9,6 +9,8 @@ import { BrowserWindow, app, ipcMain, Rectangle, Menu, screen, BrowserWindowCons
import ElectronConfig = require('electron-config')
import * as os from 'os'
import * as path from 'path'
import macOSRelease from 'macos-release'
import * as compareVersions from 'compare-versions'
import { parseArgs } from './cli'
import { loadConfig } from './config'
@@ -27,13 +29,15 @@ abstract class GlasstronWindow extends BrowserWindow {
abstract setBlur (_: boolean)
}
const macOSVibrancyType = compareVersions.compare(macOSRelease().version, '10.14', '>=') ? 'fullscreen-ui' : 'dark'
export class Window {
ready: Promise<void>
private visible = new Subject<boolean>()
private closed = new Subject<void>()
private window: GlasstronWindow
private window?: GlasstronWindow
private windowConfig: ElectronConfig
private windowBounds: Rectangle
private windowBounds?: Rectangle
private closing = false
private lastVibrancy: {enabled: boolean, type?: string} | null = null
private disableVibrancyWhileDragging = false
@@ -45,7 +49,7 @@ export class Window {
constructor (options?: WindowOptions) {
this.configStore = loadConfig()
options = options || {}
options = options ?? {}
this.windowConfig = new ElectronConfig({ name: 'window' })
this.windowBounds = this.windowConfig.get('windowBoundaries')
@@ -89,11 +93,15 @@ export class Window {
}
}
this.window = new glasstron.BrowserWindow(bwOptions)
if (process.platform === 'darwin') {
this.window = new BrowserWindow(bwOptions) as GlasstronWindow
} else {
this.window = new glasstron.BrowserWindow(bwOptions)
}
this.window.once('ready-to-show', () => {
if (process.platform === 'darwin') {
this.window.setVibrancy('window')
this.window.setVibrancy(macOSVibrancyType)
} else if (process.platform === 'win32' && (this.configStore.appearance || {}).vibrancy) {
this.setVibrancy(true)
}
@@ -149,7 +157,7 @@ export class Window {
this.window.setBackgroundColor(enabled ? '#00000000' : '#131d27')
this.window.setBlur(enabled)
} else {
this.window.setVibrancy(enabled ? 'dark' : null as any) // electron issue 20269
this.window.setVibrancy(enabled ? macOSVibrancyType : null)
}
}

View File

@@ -21,20 +21,20 @@
"@angular/platform-browser": "^9.1.9",
"@angular/platform-browser-dynamic": "^9.1.9",
"@ng-bootstrap/ng-bootstrap": "^6.1.0",
"@terminus-term/node-pty": "0.10.0-beta10",
"@terminus-term/node-pty": "0.10.0-beta11",
"electron-config": "2.0.0",
"electron-debug": "^3.0.1",
"electron-is-dev": "1.1.0",
"electron-promise-ipc": "^2.2.4",
"fontmanager-redux": "1.0.0",
"glasstron": "0.0.5",
"js-yaml": "3.14.0",
"keytar": "^7.2.0",
"mz": "^2.7.0",
"ngx-toastr": "^12.0.1",
"npm": "7.0.15",
"npm": "6",
"path": "0.12.7",
"rxjs": "^6.5.5",
"rxjs-compat": "^6.6.0",
"yargs": "^15.4.1",
"zone.js": "^0.11.3"
},
@@ -48,7 +48,8 @@
"devDependencies": {
"@types/mz": "0.0.32",
"@types/node": "14.14.14",
"node-abi": "2.19.3"
"node-abi": "2.19.3",
"source-map-support": "^0.5.19"
},
"peerDependencies": {
"terminus-community-color-schemes": "*",

View File

@@ -58,8 +58,8 @@ findPlugins().then(async plugins => {
window['safeModeReason'] = error
try {
await bootstrap(plugins, true)
} catch (error) {
console.error('Bootstrap failed:', error)
} catch (error2) {
console.error('Bootstrap failed:', error2)
}
}
})

View File

@@ -3,13 +3,13 @@ import * as path from 'path'
const nodeModule = require('module') // eslint-disable-line @typescript-eslint/no-var-requires
const nodeRequire = (global as any).require
function normalizePath (path: string): string {
function normalizePath (p: string): string {
const cygwinPrefix = '/cygdrive/'
if (path.startsWith(cygwinPrefix)) {
path = path.substring(cygwinPrefix.length).replace('/', '\\')
path = path[0] + ':' + path.substring(1)
if (p.startsWith(cygwinPrefix)) {
p = p.substring(cygwinPrefix.length).replace('/', '\\')
p = p[0] + ':' + p.substring(1)
}
return path
return p
}
global['module'].paths.map((x: string) => nodeModule.globalPaths.push(normalizePath(x)))
@@ -63,7 +63,6 @@ const builtinModules = [
'ngx-toastr',
'rxjs',
'rxjs/operators',
'rxjs-compat/Subject',
'terminus-core',
'terminus-settings',
'terminus-terminal',

View File

@@ -35,12 +35,15 @@ module.exports = {
externals: {
electron: 'commonjs electron',
'electron-config': 'commonjs electron-config',
'electron-promise-ipc': 'commonjs electron-promise-ipc',
'electron-vibrancy': 'commonjs electron-vibrancy',
fs: 'commonjs fs',
glasstron: 'commonjs glasstron',
mz: 'commonjs mz',
npm: 'commonjs npm',
path: 'commonjs path',
yargs: 'commonjs yargs',
util: 'commonjs util',
'source-map-support': 'commonjs source-map-support',
'windows-swca': 'commonjs windows-swca',
'windows-blurbehind': 'commonjs windows-blurbehind',
},
@@ -50,4 +53,6 @@ module.exports = {
'process.type': '"main"',
}),
],
// Ignore warnings due to yarg's dynamic module loading
ignoreWarnings: [/node_modules\/yargs/],
}

File diff suppressed because it is too large Load Diff

View File

@@ -6,8 +6,27 @@ npmRebuild: false
afterSign: "./build/mac/afterSignHook.js"
afterAllArtifactBuild: "./build/mac/afterBuildHook.js"
files:
- "**/*"
- '**/*'
- dist
- '!src'
- '!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}'
- '!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples,docs}'
- '!**/node_modules/@angular/common/locales'
- '!**/node_modules/@angular/compiler/src'
- '!**/node_modules/node-gyp'
- '!**/node_modules/**/*.d.ts'
- '!**/node_modules/**/*.map'
- '!**/node_modules/**/include/node'
- '!**/node_modules/.bin'
- '!**/node_modules/*/*/{esm5,fesm5,esm2015,fesm2015,_esm2015,_fesm2015}'
- '!**/*.{woff,ttf,otf,eot}'
- '!**/*.{iml,o,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,xproj}'
- '!.editorconfig'
- '!**/._*'
- '!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,.gitignore,.gitattributes}'
- '!**/{__pycache__,thumbs.db,.flowconfig,.idea,.vs,.nyc_output}'
- '!**/{appveyor.yml,.travis.yml,circle.yml}'
- '!**/{npm-debug.log,yarn.lock,.yarn-integrity,.yarn-metadata.json'
extraResources:
- builtin-plugins
- extras
@@ -22,6 +41,7 @@ nsis:
oneClick: false
artifactName: terminus-${version}-setup.${ext}
installerIcon: "./build/windows/icon.ico"
allowToChangeInstallationDirectory: true
mac:
category: public.app-category.video

View File

@@ -13,11 +13,12 @@
"@typescript-eslint/parser": "^4.11.0",
"apply-loader": "2.0.0",
"awesome-typescript-loader": "^5.2.1",
"compare-versions": "^3.6.0",
"core-js": "^3.8.1",
"cross-env": "7.0.2",
"css-loader": "3.4.2",
"electron": "^11.1.1",
"electron-builder": "22.10.3",
"electron-builder": "22.10.4",
"electron-download": "^4.1.1",
"electron-installer-snap": "^5.1.0",
"electron-notarize": "^1.0.0",
@@ -29,6 +30,7 @@
"html-loader": "0.5.5",
"json-loader": "0.5.7",
"lru-cache": "^6.0.0",
"macos-release": "^2.4.1",
"node-abi": "^2.19.3",
"node-gyp": "^7.1.2",
"node-sass": "^5.0.0",
@@ -45,7 +47,7 @@
"source-code-pro": "^2.30.2",
"source-sans-pro": "3.6.0",
"ssh2-streams": "^0.4.10",
"style-loader": "^1.3.0",
"style-loader": "^2.0.0",
"svg-inline-loader": "^0.8.2",
"to-string-loader": "1.1.6",
"tslib": "^2.0.3",

View File

@@ -8,7 +8,5 @@ export interface HotkeyDescription {
* must also provide the `hotkeys.foo` config options with the default values
*/
export abstract class HotkeyProvider {
hotkeys: HotkeyDescription[] = []
abstract provide (): Promise<HotkeyDescription[]>
}

View File

@@ -66,6 +66,10 @@ $side-tab-width: 200px;
.drag-space {
flex: auto;
}
&>.inset {
opacity: 0;
}
}
@@ -92,7 +96,7 @@ $side-tab-width: 200px;
color: #aaa;
border: none;
border-radius: 0;
align-items: center;
&.dropdown-toggle::after {
@@ -121,7 +125,6 @@ $side-tab-width: 200px;
width: 85px;
height: $tabs-height;
flex: none;
opacity: 0;
-webkit-app-region: drag;
}

View File

@@ -229,8 +229,8 @@ export class AppRootComponent {
buttons = buttons.concat(provider.provide())
})
return buttons
.filter(button => (button.weight || 0) > 0 === aboveZero)
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight || 0) - (b.weight || 0))
.filter(button => (button.weight ?? 0) > 0 === aboveZero)
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight ?? 0) - (b.weight ?? 0))
}
private updateVibrancy () {

View File

@@ -50,7 +50,7 @@ export class SelectorModalComponent<T> {
this.filteredOptions = this.options.filter(x => !x.freeInputPattern)
} else {
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
this.filteredOptions = this.options.filter(x => x.freeInputPattern || (x.name + (x.description || '')).toLowerCase().includes(f))
this.filteredOptions = this.options.filter(x => x.freeInputPattern ?? (x.name + (x.description ?? '')).toLowerCase().includes(f))
}
this.selectedIndex = Math.max(0, this.selectedIndex)
this.selectedIndex = Math.min(this.filteredOptions.length - 1, this.selectedIndex)
@@ -72,7 +72,7 @@ export class SelectorModalComponent<T> {
this.modalInstance.dismiss()
}
iconIsSVG (icon: string): boolean {
return icon?.startsWith('<')
iconIsSVG (icon?: string): boolean {
return icon?.startsWith('<') ?? false
}
}

View File

@@ -161,7 +161,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
_allFocusMode = false
/** @hidden */
private focusedTab: BaseTabComponent
private focusedTab: BaseTabComponent|null = null
private maximizedTab: BaseTabComponent|null = null
private hotkeysSubscription: Subscription
private viewRefs: Map<BaseTabComponent, EmbeddedViewRef<any>> = new Map()
@@ -211,7 +211,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
this.blurred$.subscribe(() => this.getAllTabs().forEach(x => x.emitBlurred()))
this.hotkeysSubscription = this.hotkeys.matchedHotkey.subscribe(hotkey => {
if (!this.hasFocus) {
if (!this.hasFocus || !this.focusedTab) {
return
}
switch (hotkey) {
@@ -280,7 +280,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
return this.root.getAllTabs()
}
getFocusedTab (): BaseTabComponent {
getFocusedTab (): BaseTabComponent|null {
return this.focusedTab
}
@@ -295,10 +295,8 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
x.emitBlurred()
}
}
if (tab) {
tab.emitFocused()
this.focusChanged.next(tab)
}
tab.emitFocused()
this.focusChanged.next(tab)
if (this.maximizedTab !== tab) {
this.maximizedTab = null
@@ -314,7 +312,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
/**
* Focuses the first available tab inside the given [[SplitContainer]]
*/
focusAnyIn (parent: BaseTabComponent | SplitContainer): void {
focusAnyIn (parent?: BaseTabComponent | SplitContainer): void {
if (!parent) {
return
}
@@ -331,7 +329,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
async addTab (tab: BaseTabComponent, relative: BaseTabComponent|null, side: SplitDirection): Promise<void> {
tab.parent = this
let target = (relative ? this.getParentOf(relative) : null) || this.root
let target = (relative ? this.getParentOf(relative) : null) ?? this.root
let insertIndex = relative ? target.children.indexOf(relative) : -1
if (
@@ -398,6 +396,10 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
* Moves focus in the given direction
*/
navigate (dir: SplitDirection): void {
if (!this.focusedTab) {
return
}
let rel: BaseTabComponent | SplitContainer = this.focusedTab
let parent = this.getParentOf(rel)
if (!parent) {
@@ -442,7 +444,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
* @returns the immediate parent of `tab`
*/
getParentOf (tab: BaseTabComponent | SplitContainer, root?: SplitContainer): SplitContainer|null {
root = root || this.root
root = root ?? this.root
for (const child of root.children) {
if (child instanceof SplitContainer) {
const r = this.getParentOf(tab, child)
@@ -469,7 +471,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
/** @hidden */
async getCurrentProcess (): Promise<BaseTabProcess|null> {
return (await Promise.all(this.getAllTabs().map(x => x.getCurrentProcess()))).find(x => !!x) || null
return (await Promise.all(this.getAllTabs().map(x => x.getCurrentProcess()))).find(x => !!x) ?? null
}
/** @hidden */
@@ -518,7 +520,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
private layoutInternal (root: SplitContainer, x: number, y: number, w: number, h: number) {
const size = root.orientation === 'v' ? h : w
const sizes = root.ratios.map(x => x * size)
const sizes = root.ratios.map(ratio => ratio * size)
root.x = x
root.y = y
@@ -598,7 +600,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
@Injectable()
export class SplitTabRecoveryProvider extends TabRecoveryProvider {
async recover (recoveryToken: RecoveryToken): Promise<RecoveredTab|null> {
if (recoveryToken && recoveryToken.type === 'app:split-tab') {
if (recoveryToken.type === 'app:split-tab') {
return {
type: SplitTabComponent,
options: { _recoveredState: recoveryToken },

View File

@@ -34,8 +34,8 @@ export class SplitTabSpannerComponent {
let current = start
const oldPosition: number = this.isVertical ? this.element.nativeElement.offsetTop : this.element.nativeElement.offsetLeft
const dragHandler = (e: MouseEvent) => {
current = this.isVertical ? e.pageY : e.pageX
const dragHandler = (dragEvent: MouseEvent) => {
current = this.isVertical ? dragEvent.pageY : dragEvent.pageX
const newPosition = oldPosition + (current - start)
if (this.isVertical) {
this.element.nativeElement.style.top = `${newPosition - this.marginOffset}px`

View File

@@ -26,10 +26,10 @@ export class StartPageComponent {
.map(provider => provider.provide())
.reduce((a, b) => a.concat(b))
.filter(x => !!x.click)
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight || 0) - (b.weight || 0))
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight ?? 0) - (b.weight ?? 0))
}
sanitizeIcon (icon: string): any {
return this.domSanitizer.bypassSecurityTrustHtml(icon || '')
sanitizeIcon (icon?: string): any {
return this.domSanitizer.bypassSecurityTrustHtml(icon ?? '')
}
}

View File

@@ -46,10 +46,10 @@ class CompletionObserver {
export class AppService {
tabs: BaseTabComponent[] = []
get activeTab (): BaseTabComponent { return this._activeTab }
get activeTab (): BaseTabComponent|null { return this._activeTab ?? null }
private lastTabIndex = 0
private _activeTab: BaseTabComponent
private _activeTab?: BaseTabComponent
private closedTabsStack: RecoveryToken[] = []
private activeTabChange = new Subject<BaseTabComponent>()
@@ -97,9 +97,7 @@ export class AppService {
}
}
hostApp.windowFocused$.subscribe(() => {
this._activeTab?.emitFocused()
})
hostApp.windowFocused$.subscribe(() => this._activeTab?.emitFocused())
this.tabClosed$.subscribe(async tab => {
const token = await tab.getRecoveryToken()
@@ -192,7 +190,7 @@ export class AppService {
this._activeTab.emitFocused()
return
}
if (this.tabs.includes(this._activeTab)) {
if (this._activeTab && this.tabs.includes(this._activeTab)) {
this.lastTabIndex = this.tabs.indexOf(this._activeTab)
} else {
this.lastTabIndex = 0
@@ -203,12 +201,10 @@ export class AppService {
}
this._activeTab = tab
this.activeTabChange.next(tab)
if (this._activeTab) {
setImmediate(() => {
this._activeTab.emitFocused()
})
this.hostApp.setTitle(this._activeTab.title)
}
setImmediate(() => {
this._activeTab?.emitFocused()
})
this.hostApp.setTitle(this._activeTab.title)
}
getParentTab (tab: BaseTabComponent): SplitTabComponent|null {
@@ -231,6 +227,9 @@ export class AppService {
}
nextTab (): void {
if (!this._activeTab) {
return
}
if (this.tabs.length > 1) {
const tabIndex = this.tabs.indexOf(this._activeTab)
if (tabIndex < this.tabs.length - 1) {
@@ -242,6 +241,9 @@ export class AppService {
}
previousTab (): void {
if (!this._activeTab) {
return
}
if (this.tabs.length > 1) {
const tabIndex = this.tabs.indexOf(this._activeTab)
if (tabIndex > 0) {
@@ -253,6 +255,9 @@ export class AppService {
}
moveSelectedTabLeft (): void {
if (!this._activeTab) {
return
}
if (this.tabs.length > 1) {
const tabIndex = this.tabs.indexOf(this._activeTab)
if (tabIndex > 0) {
@@ -264,6 +269,9 @@ export class AppService {
}
moveSelectedTabRight (): void {
if (!this._activeTab) {
return
}
if (this.tabs.length > 1) {
const tabIndex = this.tabs.indexOf(this._activeTab)
if (tabIndex < this.tabs.length - 1) {

View File

@@ -109,10 +109,7 @@ export class ConfigService {
) {
this.path = path.join(electron.app.getPath('userData'), 'config.yaml')
this.defaults = configProviders.map(provider => {
let defaults = {}
if (provider.platformDefaults) {
defaults = configMerge(defaults, provider.platformDefaults[hostApp.platform] || {})
}
let defaults = provider.platformDefaults[hostApp.platform] || {}
if (provider.defaults) {
defaults = configMerge(defaults, provider.defaults)
}

View File

@@ -26,6 +26,7 @@ export class DockingService {
let display = this.electron.screen.getAllDisplays()
.filter(x => x.id === this.config.store.appearance.dockScreen)[0]
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!display) {
display = this.getCurrentScreen()
}

View File

@@ -235,7 +235,7 @@ export class HostAppService {
* @param type `null`, or `fluent` when supported (Windowd only)
*/
setVibrancy (enable: boolean, type: string|null): void {
if (!isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)) {
if (this.platform === Platform.Windows && !isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)) {
type = null
}
document.body.classList.toggle('vibrant', enable)

View File

@@ -172,7 +172,7 @@ export class HotkeysService {
return (
await Promise.all(
this.config.enabledServices(this.hotkeyProviders)
.map(async x => x.provide ? x.provide() : x.hotkeys)
.map(async x => x.provide())
)
).reduce((a, b) => a.concat(b))
}
@@ -222,7 +222,7 @@ export class HotkeysService {
if (!(value instanceof Array)) {
continue
}
if (value) {
if (value.length > 0) {
value = value.map((item: string | string[]) => typeof item === 'string' ? [item] : item)
keys[key] = value
}

View File

@@ -54,9 +54,7 @@ export class Logger {
private doLog (level: string, ...args: any[]): void {
console[level](`%c[${this.name}]`, 'color: #aaa', ...args)
if (this.winstonLogger) {
this.winstonLogger[level](...args)
}
this.winstonLogger[level](...args)
}
}

View File

@@ -59,7 +59,7 @@ export class ShellIntegrationService {
}
async install (): Promise<void> {
const exe: string = process.env.PORTABLE_EXECUTABLE_FILE || this.electron.app.getPath('exe')
const exe: string = process.env.PORTABLE_EXECUTABLE_FILE ?? this.electron.app.getPath('exe')
if (this.hostApp.platform === Platform.macOS) {
for (const wf of this.automatorWorkflows) {
await exec(`cp -r "${this.automatorWorkflowsLocation}/${wf}" "${this.automatorWorkflowsDestination}"`)

View File

@@ -11,7 +11,7 @@ export class TabRecoveryService {
enabled = false
private constructor (
@Inject(TabRecoveryProvider) private tabRecoveryProviders: TabRecoveryProvider[],
@Inject(TabRecoveryProvider) private tabRecoveryProviders: TabRecoveryProvider[]|null,
private config: ConfigService,
log: LogService
) {
@@ -23,35 +23,28 @@ export class TabRecoveryService {
return
}
window.localStorage.tabsRecovery = JSON.stringify(
await Promise.all(
(await Promise.all(
tabs
.map(tab => {
let token = tab.getRecoveryToken()
if (token) {
token = token.then(r => {
if (r) {
r.tabTitle = tab.title
if (tab.color) {
r.tabColor = tab.color
}
}
return r
})
.map(async tab => tab.getRecoveryToken().then(r => {
if (r) {
r.tabTitle = tab.title
if (tab.color) {
r.tabColor = tab.color
}
}
return token
})
.filter(token => !!token)
)
return r
}))
)).filter(token => !!token)
)
}
async recoverTab (token: RecoveryToken): Promise<RecoveredTab|null> {
for (const provider of this.config.enabledServices(this.tabRecoveryProviders)) {
for (const provider of this.config.enabledServices(this.tabRecoveryProviders ?? [])) {
try {
const tab = await provider.recover(token)
if (tab !== null) {
tab.options = tab.options || {}
tab.options.color = token.tabColor || null
tab.options.color = token.tabColor ?? null
tab.options.title = token.tabTitle || ''
return tab
}

View File

@@ -22,7 +22,7 @@ export class TabsService {
const componentRef = componentFactory.create(this.injector)
const tab = componentRef.instance
tab.hostView = componentRef.hostView
Object.assign(tab, inputs || {})
Object.assign(tab, inputs ?? {})
return tab
}

View File

@@ -18,11 +18,11 @@ export class ThemesService {
}
findTheme (name: string): Theme|null {
return this.config.enabledServices(this.themes).find(x => x.name === name) || null
return this.config.enabledServices(this.themes).find(x => x.name === name) ?? null
}
findCurrentTheme (): Theme {
return this.findTheme(this.config.store.appearance.theme) || this.findTheme('Standard')!
return this.findTheme(this.config.store.appearance.theme) ?? this.findTheme('Standard')!
}
applyTheme (theme: Theme): void {

View File

@@ -33,6 +33,7 @@ export class TouchbarService {
app.tabOpened$.subscribe(tab => {
tab.titleChange$.subscribe(title => {
const segment = this.tabSegments[app.tabs.indexOf(tab)]
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (segment) {
segment.label = this.shortenTitle(title)
this.tabsSegmentedControl.segments = this.tabSegments
@@ -41,6 +42,7 @@ export class TouchbarService {
tab.activity$.subscribe(hasActivity => {
const showIcon = this.app.activeTab !== tab && hasActivity
const segment = this.tabSegments[app.tabs.indexOf(tab)]
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (segment) {
segment.icon = showIcon ? activityIcon : undefined
}
@@ -53,7 +55,7 @@ export class TouchbarService {
label: this.shortenTitle(tab.title),
}))
this.tabsSegmentedControl.segments = this.tabSegments
this.tabsSegmentedControl.selectedIndex = this.app.tabs.indexOf(this.app.activeTab)
this.tabsSegmentedControl.selectedIndex = this.app.activeTab ? this.app.tabs.indexOf(this.app.activeTab) : 0
}
update (): void {
@@ -66,14 +68,14 @@ export class TouchbarService {
buttons = buttons.concat(provider.provide())
})
buttons = buttons.filter(x => !!x.touchBarNSImage)
buttons.sort((a, b) => (a.weight || 0) - (b.weight || 0))
buttons.sort((a, b) => (a.weight ?? 0) - (b.weight ?? 0))
this.tabSegments = this.app.tabs.map(tab => ({
label: this.shortenTitle(tab.title),
}))
this.tabsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({
segments: this.tabSegments,
selectedIndex: this.app.tabs.indexOf(this.app.activeTab),
selectedIndex: this.app.activeTab ? this.app.tabs.indexOf(this.app.activeTab) : undefined,
change: (selectedIndex) => this.zone.run(() => {
this.app.selectTab(this.app.tabs[selectedIndex])
}),
@@ -102,13 +104,14 @@ export class TouchbarService {
private getButton (button: ToolbarButton): SegmentedControlSegment {
return {
label: button.touchBarNSImage ? undefined : this.shortenTitle(button.touchBarTitle || button.title),
label: button.touchBarNSImage ? undefined : this.shortenTitle(button.touchBarTitle ?? button.title),
icon: button.touchBarNSImage ? this.getCachedNSImage(button.touchBarNSImage) : undefined,
// click: () => this.zone.run(() => button.click()),
}
}
private getCachedNSImage (name: string) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!this.nsImageCache[name]) {
this.nsImageCache[name] = this.electron.nativeImage.createFromNamedImage(name, [0, 0, 1])
}

View File

@@ -113,7 +113,7 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
...items,
{
label: 'Rename',
click: () => this.zone.run(() => tabHeader?.showRenameTabModal()),
click: () => this.zone.run(() => tabHeader.showRenameTabModal()),
},
{
label: 'Duplicate',

View File

@@ -19,6 +19,7 @@
"devDependencies": {
"@types/semver": "^7.1.0",
"axios": "^0.19.0",
"electron-promise-ipc": "^2.2.4",
"mz": "^2.6.0",
"semver": "^7.1.1"
},

View File

@@ -22,10 +22,10 @@
button.btn.btn-primary.ml-2(
*ngIf='knownUpgrades[plugin.name]',
(click)='upgradePlugin(plugin)',
[disabled]='busy[plugin.name] != undefined'
[disabled]='busy.has(plugin.name)'
)
i.fas.fa-fw.fa-arrow-up(*ngIf='busy[plugin.name] != BusyState.Installing')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Installing')
i.fas.fa-fw.fa-arrow-up(*ngIf='busy.get(plugin.name) != BusyState.Installing')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
span Upgrade ({{knownUpgrades[plugin.name].version}})
button.btn.btn-link.text-primary.ml-2(
@@ -43,10 +43,10 @@
button.btn.btn-link.text-danger.ml-2(
(click)='uninstallPlugin(plugin)',
*ngIf='!plugin.isBuiltin',
[disabled]='busy[plugin.name] != undefined'
[disabled]='busy.has(plugin.name)'
)
i.fas.fa-fw.fa-trash(*ngIf='busy[plugin.name] != BusyState.Uninstalling')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Uninstalling')
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')
div
h3.mt-4 Available
@@ -69,10 +69,10 @@ div
.list-group-item.d-flex.align-items-center(*ngIf='!isAlreadyInstalled(plugin)')
button.btn.btn-primary.mr-3(
(click)='installPlugin(plugin)',
[disabled]='busy[plugin.name] != undefined'
[disabled]='busy.has(plugin.name)'
)
i.fas.fa-fw.fa-download(*ngIf='busy[plugin.name] != BusyState.Installing')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Installing')
i.fas.fa-fw.fa-download(*ngIf='busy.get(plugin.name) != BusyState.Installing')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
div((click)='showPluginInfo(plugin)')
div

View File

@@ -20,7 +20,7 @@ export class PluginsSettingsTabComponent {
@Input() availablePluginsQuery$ = new BehaviorSubject<string>('')
@Input() availablePluginsReady = false
@Input() knownUpgrades: Record<string, PluginInfo|null> = {}
@Input() busy: Record<string, BusyState> = {}
@Input() busy = new Map<string, BusyState>()
@Input() erroredPlugin: string
@Input() errorMessage: string
@@ -67,29 +67,29 @@ export class PluginsSettingsTabComponent {
}
async installPlugin (plugin: PluginInfo): Promise<void> {
this.busy[plugin.name] = BusyState.Installing
this.busy.set(plugin.name, BusyState.Installing)
try {
await this.pluginManager.installPlugin(plugin)
delete this.busy[plugin.name]
this.busy.delete(plugin.name)
this.config.requestRestart()
} catch (err) {
this.erroredPlugin = plugin.name
this.errorMessage = err
delete this.busy[plugin.name]
this.busy.delete(plugin.name)
throw err
}
}
async uninstallPlugin (plugin: PluginInfo): Promise<void> {
this.busy[plugin.name] = BusyState.Uninstalling
this.busy.set(plugin.name, BusyState.Uninstalling)
try {
await this.pluginManager.uninstallPlugin(plugin)
delete this.busy[plugin.name]
this.busy.delete(plugin.name)
this.config.requestRestart()
} catch (err) {
this.erroredPlugin = plugin.name
this.errorMessage = err
delete this.busy[plugin.name]
this.busy.delete(plugin.name)
throw err
}
}

View File

@@ -1,4 +1,5 @@
import axios from 'axios'
import promiseIpc from 'electron-promise-ipc'
import { Observable, from } from 'rxjs'
import { map } from 'rxjs/operators'
import { Injectable } from '@angular/core'
@@ -31,39 +32,15 @@ export class PluginManagerService {
userPluginsPath: string = (window as any).userPluginsPath
installedPlugins: PluginInfo[] = (window as any).installedPlugins
private npmReady: Promise<void>
private npm: any
private constructor (
log: LogService,
) {
this.logger = log.create('pluginManager')
}
async getNPM (): Promise<any> {
if (!this.npm) {
if (!this.npmReady) {
this.npmReady = new Promise(resolve => {
const npm = (global as any).require('npm')
npm.load({
prefix: this.userPluginsPath,
}, err => {
if (err) {
this.logger.error(err)
}
this.npm = npm
resolve()
})
})
}
await this.npmReady
}
return this.npm
}
listAvailable (query?: string): Observable<PluginInfo[]> {
return from(
axios.get(`https://www.npmjs.com/search?q=keywords%3A${KEYWORD}+${encodeURIComponent(query || '')}&from=0&size=1000`, {
axios.get(`https://www.npmjs.com/search?q=keywords%3A${KEYWORD}+${encodeURIComponent(query ?? '')}&from=0&size=1000`, {
headers: {
'x-spiferack': '1',
},
@@ -84,21 +61,23 @@ export class PluginManagerService {
}
async installPlugin (plugin: PluginInfo): Promise<void> {
(await this.getNPM()).commands.install([`${plugin.packageName}@${plugin.version}`], err => {
if (err) {
this.logger.error(err)
}
try {
await (promiseIpc as any).send('plugin-manager:install', this.userPluginsPath, plugin.packageName, plugin.version)
this.installedPlugins = this.installedPlugins.filter(x => x.packageName !== plugin.packageName)
this.installedPlugins.push(plugin)
})
} catch (err) {
this.logger.error(err)
throw err
}
}
async uninstallPlugin (plugin: PluginInfo): Promise<void> {
(await this.getNPM()).commands.remove([plugin.packageName], err => {
if (err) {
this.logger.error(err)
}
try {
await (promiseIpc as any).send('plugin-manager:uninstall', this.userPluginsPath, plugin.packageName)
this.installedPlugins = this.installedPlugins.filter(x => x.packageName !== plugin.packageName)
})
} catch (err) {
this.logger.error(err)
throw err
}
}
}

View File

@@ -46,8 +46,8 @@ module.exports = {
externals: [
'fs',
'net',
'npm',
'path',
'electron-promise-ipc',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,

View File

@@ -19,6 +19,14 @@ axios@^0.19.0:
dependencies:
follow-redirects "1.5.10"
call-bind@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce"
integrity sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==
dependencies:
function-bind "^1.1.1"
get-intrinsic "^1.0.0"
debug@=3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
@@ -26,6 +34,50 @@ debug@=3.1.0:
dependencies:
ms "2.0.0"
define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
dependencies:
object-keys "^1.0.12"
electron-promise-ipc@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/electron-promise-ipc/-/electron-promise-ipc-2.2.4.tgz#b82daf86ca6d0f0b8655937fdbe9a554590deeea"
integrity sha512-xCkFEeuru9l7H/+m1gpK4F1utexvTT7+n1PTquP2MVTpmBmpgFBlLqSXC7TqwpROkHRm9wGpaCJEx0djonnSEg==
dependencies:
is-electron-renderer "^2.0.1"
object.entries "^1.1.3"
serialize-error "^5.0.0"
uuid "^3.0.1"
es-abstract@^1.18.0-next.1:
version "1.18.0-next.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68"
integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==
dependencies:
es-to-primitive "^1.2.1"
function-bind "^1.1.1"
has "^1.0.3"
has-symbols "^1.0.1"
is-callable "^1.2.2"
is-negative-zero "^2.0.0"
is-regex "^1.1.1"
object-inspect "^1.8.0"
object-keys "^1.1.1"
object.assign "^4.1.1"
string.prototype.trimend "^1.0.1"
string.prototype.trimstart "^1.0.1"
es-to-primitive@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
dependencies:
is-callable "^1.1.4"
is-date-object "^1.0.1"
is-symbol "^1.0.2"
follow-redirects@1.5.10:
version "1.5.10"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
@@ -33,6 +85,66 @@ follow-redirects@1.5.10:
dependencies:
debug "=3.1.0"
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
get-intrinsic@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49"
integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==
dependencies:
function-bind "^1.1.1"
has "^1.0.3"
has-symbols "^1.0.1"
has-symbols@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
dependencies:
function-bind "^1.1.1"
is-callable@^1.1.4, is-callable@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9"
integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==
is-date-object@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
is-electron-renderer@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-electron-renderer/-/is-electron-renderer-2.0.1.tgz#a469d056f975697c58c98c6023eb0aa79af895a2"
integrity sha1-pGnQVvl1aXxYyYxgI+sKp5r4laI=
is-negative-zero@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==
is-regex@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9"
integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==
dependencies:
has-symbols "^1.0.1"
is-symbol@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==
dependencies:
has-symbols "^1.0.1"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -52,11 +164,64 @@ object-assign@^4.0.1:
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
object-inspect@^1.8.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
object-keys@^1.0.12, object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
object.assign@^4.1.1:
version "4.1.2"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940"
integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==
dependencies:
call-bind "^1.0.0"
define-properties "^1.1.3"
has-symbols "^1.0.1"
object-keys "^1.1.1"
object.entries@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6"
integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==
dependencies:
call-bind "^1.0.0"
define-properties "^1.1.3"
es-abstract "^1.18.0-next.1"
has "^1.0.3"
semver@^7.1.1:
version "7.3.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
serialize-error@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-5.0.0.tgz#a7ebbcdb03a5d71a6ed8461ffe0fc1a1afed62ac"
integrity sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==
dependencies:
type-fest "^0.8.0"
string.prototype.trimend@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b"
integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==
dependencies:
call-bind "^1.0.0"
define-properties "^1.1.3"
string.prototype.trimstart@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa"
integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==
dependencies:
call-bind "^1.0.0"
define-properties "^1.1.3"
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
@@ -70,3 +235,13 @@ thenify-all@^1.0.0:
integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
dependencies:
any-promise "^1.0.0"
type-fest@^0.8.0:
version "0.8.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
uuid@^3.0.1:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==

View File

@@ -44,7 +44,7 @@ export class SerialSession extends BaseSession {
constructor (public connection: SerialConnection) {
super()
this.scripts = connection.scripts || []
this.scripts = connection.scripts ?? []
}
async start (): Promise<void> {

View File

@@ -28,7 +28,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
weight: 5,
title: 'Serial connections',
touchBarNSImage: 'NSTouchBarOpenInBrowserTemplate',
click: async () => {
click: () => {
this.activate()
},
}]

View File

@@ -37,7 +37,7 @@ export class EditConnectionModalComponent {
}
async ngOnInit () {
this.connection.scripts = this.connection.scripts || []
this.connection.scripts = this.connection.scripts ?? []
this.foundPorts = await this.serial.listPorts()
}

View File

@@ -16,8 +16,8 @@ import { Subscription } from 'rxjs'
animations: BaseTerminalTabComponent.animations,
})
export class SerialTabComponent extends BaseTerminalTabComponent {
connection: SerialConnection
session: SerialSession
connection?: SerialConnection
session?: SerialSession
serialPort: any
private homeEndSubscription: Subscription
@@ -52,7 +52,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
super.ngOnInit()
setImmediate(() => {
this.setTitle(this.connection.name)
this.setTitle(this.connection!.name)
})
}
@@ -65,7 +65,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
this.session = this.injector.get(SerialService).createSession(this.connection)
this.session.serviceMessage$.subscribe(msg => {
this.write(`\r\n${colors.black.bgWhite(' serial ')} ${msg}\r\n`)
this.session.resize(this.size.columns, this.size.rows)
this.session?.resize(this.size.columns, this.size.rows)
})
this.attachSessionHandlers()
this.write(`Connecting to `)
@@ -108,7 +108,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
name: x.toString(), result: x,
})))
this.serialPort.update({ baudRate: rate })
this.connection.baudrate = rate
this.connection!.baudrate = rate
}
ngOnDestroy () {

View File

@@ -7,7 +7,7 @@ import { SerialTabComponent } from './components/serialTab.component'
@Injectable()
export class RecoveryProvider extends TabRecoveryProvider {
async recover (recoveryToken: RecoveryToken): Promise<RecoveredTab|null> {
if (recoveryToken?.type === 'app:serial-tab') {
if (recoveryToken.type === 'app:serial-tab') {
return {
type: SerialTabComponent,
options: {

View File

@@ -57,7 +57,6 @@ export class SerialService {
this.toastr.error(e.message)
reject(e)
}
})
return serial
}
@@ -125,10 +124,10 @@ export class SerialService {
{ connection }
) as SerialTabComponent
if (connection.color) {
(this.app.getParentTab(tab) || tab).color = connection.color
(this.app.getParentTab(tab) ?? tab).color = connection.color
}
setTimeout(() => {
this.app.activeTab.emitFocused()
this.app.activeTab?.emitFocused()
})
return tab
} catch (error) {

View File

@@ -10,7 +10,7 @@ import { HotkeyInputModalComponent } from './hotkeyInputModal.component'
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MultiHotkeyInputComponent {
@Input() model: string[][]
@Input() model: string[][] = []
@Output() modelChange = new EventEmitter()
constructor (
@@ -18,9 +18,6 @@ export class MultiHotkeyInputComponent {
) { }
ngOnInit (): void {
if (!this.model) {
this.model = []
}
if (typeof this.model === 'string') {
this.model = [this.model]
}

View File

@@ -24,7 +24,7 @@ export enum SSHAlgorithmType {
export interface SSHConnection {
name: string
host: string
port: number
port?: number
user: string
auth?: null|'password'|'publicKey'|'agent'|'keyboardInteractive'
password?: string
@@ -76,10 +76,10 @@ export class ForwardedPort {
})
} else if (this.type === PortForwardType.Dynamic) {
return new Promise((resolve, reject) => {
this.listener = socksv5.createServer((info, accept, reject) => {
this.listener = socksv5.createServer((info, acceptConnection, rejectConnection) => {
callback(
() => accept(true),
() => reject(),
() => acceptConnection(true),
() => rejectConnection(),
null,
null,
info.dstAddr,
@@ -112,7 +112,7 @@ export class ForwardedPort {
export class SSHSession extends BaseSession {
scripts?: LoginScript[]
shell: ClientChannel
shell?: ClientChannel
ssh: Client
forwardedPorts: ForwardedPort[] = []
logger: Logger
@@ -123,7 +123,7 @@ export class SSHSession extends BaseSession {
constructor (public connection: SSHConnection) {
super()
this.scripts = connection.scripts || []
this.scripts = connection.scripts ?? []
this.destroyed$.subscribe(() => {
for (const port of this.forwardedPorts) {
if (port.type === PortForwardType.Local) {
@@ -177,7 +177,7 @@ export class SSHSession extends BaseSession {
if (match) {
this.logger.info('Executing script: "' + cmd + '"')
this.shell.write(cmd + '\n')
this.shell!.write(cmd + '\n')
this.scripts = this.scripts.filter(x => x !== script)
} else {
if (script.optional) {
@@ -213,6 +213,7 @@ export class SSHSession extends BaseSession {
const socket = new Socket()
socket.connect(forward.targetPort, forward.targetAddress)
socket.on('error', e => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Could not forward the remote connection to ${forward.targetAddress}:${forward.targetPort}: ${e}`)
reject()
})
@@ -232,7 +233,7 @@ export class SSHSession extends BaseSession {
this.ssh.on('x11', (details, accept, reject) => {
this.logger.info(`Incoming X11 connection from ${details.srcIP}:${details.srcPort}`)
const displaySpec = process.env.DISPLAY || ':0'
const displaySpec = process.env.DISPLAY ?? ':0'
this.logger.debug(`Trying display ${displaySpec}`)
const xHost = displaySpec.split(':')[0]
const xDisplay = parseInt(displaySpec.split(':')[1].split('.')[0] || '0')
@@ -243,6 +244,7 @@ export class SSHSession extends BaseSession {
socket.connect(xPort, xHost)
}
socket.on('error', e => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Could not connect to the X server ${xHost}:${xPort}: ${e}`)
reject()
})
@@ -273,27 +275,25 @@ export class SSHSession extends BaseSession {
await fw.startLocalListener((accept, reject, sourceAddress, sourcePort, targetAddress, targetPort) => {
this.logger.info(`New connection on ${fw}`)
this.ssh.forwardOut(
sourceAddress || '127.0.0.1',
sourcePort || 0,
sourceAddress ?? '127.0.0.1',
sourcePort ?? 0,
targetAddress,
targetPort,
(err, stream) => {
if (err) {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote has rejected the forwarded connection to ${targetAddress}:${targetPort} via ${fw}: ${err}`)
reject()
return
}
if (stream) {
const socket = accept()
stream.pipe(socket)
socket.pipe(stream)
stream.on('close', () => {
socket.destroy()
})
socket.on('close', () => {
stream.close()
})
return reject()
}
const socket = accept()
stream.pipe(socket)
socket.pipe(stream)
stream.on('close', () => {
socket.destroy()
})
socket.on('close', () => {
stream.close()
})
}
)
}).then(() => {
@@ -308,6 +308,7 @@ export class SSHSession extends BaseSession {
await new Promise((resolve, reject) => {
this.ssh.forwardIn(fw.host, fw.port, err => {
if (err) {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote rejected port forwarding for ${fw}: ${err}`)
return reject(err)
}
@@ -345,7 +346,7 @@ export class SSHSession extends BaseSession {
kill (signal?: string): void {
if (this.shell) {
this.shell.signal(signal || 'TERM')
this.shell.signal(signal ?? 'TERM')
}
}
@@ -383,7 +384,7 @@ export class SSHSession extends BaseSession {
for (const script of this.scripts) {
if (!script.expect) {
console.log('Executing script:', script.send)
this.shell.write(script.send + '\n')
this.shell!.write(script.send + '\n')
this.scripts = this.scripts.filter(x => x !== script)
} else {
break

View File

@@ -28,7 +28,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
weight: 5,
title: 'SSH connections',
touchBarNSImage: 'NSTouchBarOpenInBrowserTemplate',
click: async () => {
click: () => {
this.activate()
},
}]

View File

@@ -47,11 +47,12 @@ export class EditConnectionModalComponent {
async ngOnInit () {
this.hasSavedPassword = !!await this.passwordStorage.loadPassword(this.connection)
this.connection.algorithms = this.connection.algorithms || {}
this.connection.scripts = this.connection.scripts || []
this.connection.auth = this.connection.auth || null
this.connection.algorithms = this.connection.algorithms ?? {}
this.connection.scripts = this.connection.scripts ?? []
this.connection.auth = this.connection.auth ?? null
for (const k of Object.values(SSHAlgorithmType)) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!this.connection.algorithms[k]) {
this.connection.algorithms[k] = this.defaultAlgorithms[k]
}
@@ -98,8 +99,8 @@ export class EditConnectionModalComponent {
save () {
for (const k of Object.values(SSHAlgorithmType)) {
this.connection.algorithms![k] = Object.entries(this.algorithms[k])
.filter(([_k, v]) => !!v)
.map(([k, _v]) => k)
.filter(([_, v]) => !!v)
.map(([key, _]) => key)
}
this.modalInstance.close(this.connection)
}

View File

@@ -127,14 +127,14 @@ export class SSHSettingsTabComponent {
this.childGroups = []
for (const connection of this.connections) {
connection.group = connection.group || null
connection.group = connection.group ?? null
let group = this.childGroups.find(x => x.name === connection.group)
if (!group) {
group = {
name: connection.group!,
connections: [],
}
this.childGroups.push(group!)
this.childGroups.push(group)
}
group.connections.push(connection)
}

View File

@@ -19,8 +19,8 @@ import { Subscription } from 'rxjs'
animations: BaseTerminalTabComponent.animations,
})
export class SSHTabComponent extends BaseTerminalTabComponent {
connection: SSHConnection
session: SSHSession
connection?: SSHConnection
session?: SSHSession
private sessionStack: SSHSession[] = []
private homeEndSubscription: Subscription
@@ -33,6 +33,10 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
}
ngOnInit (): void {
if (!this.connection) {
throw new Error('Connection not set')
}
this.logger = this.log.create('terminalTab')
this.enableDynamicTitle = !this.connection.disableDynamicTitle
@@ -58,7 +62,7 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
super.ngOnInit()
setImmediate(() => {
this.setTitle(this.connection.name)
this.setTitle(this.connection!.name)
})
}
@@ -72,7 +76,7 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
jumpSession.destroyed$.subscribe(() => session.destroy())
session.jumpStream = await new Promise((resolve, reject) => jumpSession.ssh.forwardOut(
'127.0.0.1', 0, session.connection.host, session.connection.port,
'127.0.0.1', 0, session.connection.host, session.connection.port ?? 22,
(err, stream) => {
if (err) {
jumpSession.emitServiceMessage(colors.bgRed.black(' X ') + ` Could not set up port forward on ${jumpConnection.name}`)
@@ -150,27 +154,27 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
showPortForwarding (): void {
const modal = this.ngbModal.open(SSHPortForwardingModalComponent).componentInstance as SSHPortForwardingModalComponent
modal.session = this.session
modal.session = this.session!
}
async reconnect (): Promise<void> {
this.session?.destroy()
await this.initializeSession()
this.session.releaseInitialDataBuffer()
this.session?.releaseInitialDataBuffer()
}
async canClose (): Promise<boolean> {
if (!this.session?.open) {
return true
}
if (!(this.connection.warnOnClose ?? this.config.store.ssh.warnOnClose)) {
if (!(this.connection?.warnOnClose ?? this.config.store.ssh.warnOnClose)) {
return true
}
return (await this.electron.showMessageBox(
this.hostApp.getWindow(),
{
type: 'warning',
message: `Disconnect from ${this.connection.host}?`,
message: `Disconnect from ${this.connection?.host}?`,
buttons: ['Cancel', 'Disconnect'],
defaultId: 1,
}

View File

@@ -7,7 +7,7 @@ import { SSHTabComponent } from './components/sshTab.component'
@Injectable()
export class RecoveryProvider extends TabRecoveryProvider {
async recover (recoveryToken: RecoveryToken): Promise<RecoveredTab|null> {
if (recoveryToken?.type === 'app:ssh-tab') {
if (recoveryToken.type === 'app:ssh-tab') {
return {
type: SSHTabComponent,
options: {

View File

@@ -98,7 +98,7 @@ export class SSHService {
}
}
const sshFormatKey = parsedKey!.toString('openssh')
const sshFormatKey = parsedKey.toString('openssh')
const temp = await openTemp()
fs.close(temp.fd)
await fs.writeFile(temp.path, sshFormatKey)
@@ -161,6 +161,7 @@ export class SSHService {
}
this.zone.run(() => {
if (connected) {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
this.toastr.error(error.toString())
} else {
reject(error)
@@ -209,6 +210,7 @@ export class SSHService {
if (await fs.exists(WINDOWS_OPENSSH_AGENT_PIPE)) {
agent = WINDOWS_OPENSSH_AGENT_PIPE
} else {
// eslint-disable-next-line @typescript-eslint/no-shadow
const pageantRunning = await new Promise<boolean>(resolve => {
windowsProcessTreeNative.getProcessList(list => { // eslint-disable-line block-scoped-var
resolve(list.some(x => x.name === 'pageant.exe'))
@@ -249,12 +251,12 @@ export class SSHService {
try {
ssh.connect({
host: session.connection.host,
port: session.connection.port || 22,
port: session.connection.port ?? 22,
username: session.connection.user,
password: session.connection.privateKey ? undefined : '',
privateKey: privateKey || undefined,
privateKey: privateKey ?? undefined,
tryKeyboard: true,
agent: agent || undefined,
agent: agent ?? undefined,
agentForward: session.connection.agentForward && !!agent,
keepaliveInterval: session.connection.keepaliveInterval,
keepaliveCountMax: session.connection.keepaliveCountMax,
@@ -284,7 +286,7 @@ export class SSHService {
} as any)
} catch (e) {
this.toastr.error(e.message)
reject(e)
return reject(e)
}
let keychainPasswordUsed = false
@@ -358,7 +360,7 @@ export class SSHService {
name: connection.group!,
connections: [],
}
groups.push(group!)
groups.push(group)
}
group.connections.push(connection)
}
@@ -398,12 +400,10 @@ export class SSHService {
{ connection }
) as SSHTabComponent
if (connection.color) {
(this.app.getParentTab(tab) || tab).color = connection.color
(this.app.getParentTab(tab) ?? tab).color = connection.color
}
setTimeout(() => {
this.app.activeTab?.emitFocused()
})
setTimeout(() => this.app.activeTab?.emitFocused())
return tab
} catch (error) {

View File

@@ -44,14 +44,14 @@ export class WinSCPContextMenu extends TabContextMenuItemProvider {
if (!this.getPath()) {
return []
}
if (!(tab instanceof SSHTabComponent)) {
if (!(tab instanceof SSHTabComponent) || !tab.connection) {
return []
}
return [
{
label: 'Launch WinSCP',
click: (): void => {
this.launchWinSCP(tab.connection)
this.launchWinSCP(tab.connection!)
},
},
]

View File

@@ -2,12 +2,7 @@
# yarn lockfile v1
"@types/node@*":
version "14.14.7"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.7.tgz#8ea1e8f8eae2430cf440564b98c6dfce1ec5945d"
integrity sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg==
"@types/node@14.14.14":
"@types/node@*", "@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==
@@ -20,9 +15,9 @@
"@types/node" "*"
"@types/ssh2@^0.5.35":
version "0.5.45"
resolved "https://registry.yarnpkg.com/@types/ssh2/-/ssh2-0.5.45.tgz#14e293ec2a4d4c8a5434a7989a676b87340aa870"
integrity sha512-SAQITTyO/jOoskSAw2T/9sveX4lhTzx7zdeYR0t04RMhZQrEIzvrAoCStSxYwvwZ5ofek1JWeW9x2yOK3GOUlg==
version "0.5.46"
resolved "https://registry.yarnpkg.com/@types/ssh2/-/ssh2-0.5.46.tgz#e12341a242aea0e98ac2dec89e039bf421fd3584"
integrity sha512-1pC8FHrMPYdkLoUOwTYYifnSEPzAFZRsp3JFC/vokQ+dRrVI+hDBwz0SNmQ3pL6h39OSZlPs0uCG7wKJkftnaA==
dependencies:
"@types/node" "*"
"@types/ssh2-streams" "*"

View File

@@ -35,8 +35,8 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
]),
])]
session: BaseSession
savedState: any
session?: BaseSession
savedState?: any
@Input() zoom = 0
@@ -51,7 +51,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
/** @hidden */
@HostBinding('class.top-padded') topPadded: boolean
frontend: Frontend
frontend?: Frontend
/** @hidden */
frontendIsReady = false
@@ -83,7 +83,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
protected terminalContainersService: TerminalFrontendService
protected toastr: ToastrServiceProxy
protected log: LogService
protected decorators: TerminalDecorator[]
protected decorators: TerminalDecorator[] = []
protected contextMenuProviders: TabContextMenuItemProvider[]
// Deps end
@@ -95,10 +95,29 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
private termContainerSubscriptions: Subscription[] = []
private allFocusModeSubscription: Subscription|null = null
get input$ (): Observable<Buffer> { return this.frontend.input$ }
get input$ (): Observable<Buffer> {
if (!this.frontend) {
throw new Error('Frontend not ready')
}
return this.frontend.input$
}
get output$ (): Observable<string> { return this.output }
get resize$ (): Observable<ResizeEvent> { return this.frontend.resize$ }
get alternateScreenActive$ (): Observable<boolean> { return this.frontend.alternateScreenActive$ }
get resize$ (): Observable<ResizeEvent> {
if (!this.frontend) {
throw new Error('Frontend not ready')
}
return this.frontend.resize$
}
get alternateScreenActive$ (): Observable<boolean> {
if (!this.frontend) {
throw new Error('Frontend not ready')
}
return this.frontend.alternateScreenActive$
}
get frontendReady$ (): Observable<void> { return this.frontendReady }
constructor (protected injector: Injector) {
@@ -119,7 +138,6 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
this.contextMenuProviders = injector.get<any>(TabContextMenuItemProvider, null, InjectFlags.Optional) as TabContextMenuItemProvider[]
this.logger = this.log.create('baseTerminalTab')
this.decorators = this.decorators || []
this.setTitle('Terminal')
this.hotkeysSubscription = this.hotkeys.matchedHotkey.subscribe(hotkey => {
@@ -128,7 +146,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
}
switch (hotkey) {
case 'ctrl-c':
if (this.frontend.getSelection()) {
if (this.frontend?.getSelection()) {
this.frontend.copySelection()
this.frontend.clearSelection()
this.toastr.info('Copied')
@@ -137,15 +155,15 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
}
break
case 'copy':
this.frontend.copySelection()
this.frontend.clearSelection()
this.frontend?.copySelection()
this.frontend?.clearSelection()
this.toastr.info('Copied')
break
case 'paste':
this.paste()
break
case 'clear':
this.frontend.clear()
this.frontend?.clear()
break
case 'zoom-in':
this.zoomIn()
@@ -201,7 +219,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
ngOnInit (): void {
this.focused$.subscribe(() => {
this.configure()
this.frontend.focus()
this.frontend?.focus()
})
this.frontend = this.terminalContainersService.getFrontend(this.session)
@@ -223,10 +241,10 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
})
setTimeout(() => {
this.session.resize(columns, rows)
this.session?.resize(columns, rows)
}, 1000)
this.session.releaseInitialDataBuffer()
this.session?.releaseInitialDataBuffer()
})
this.alternateScreenActive$.subscribe(x => {
@@ -242,12 +260,12 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
setImmediate(() => {
if (this.hasFocus) {
this.frontend.attach(this.content.nativeElement)
this.frontend.configure()
this.frontend!.attach(this.content.nativeElement)
this.frontend!.configure()
} else {
this.focused$.pipe(first()).subscribe(() => {
this.frontend.attach(this.content.nativeElement)
this.frontend.configure()
this.frontend!.attach(this.content.nativeElement)
this.frontend!.configure()
})
}
})
@@ -264,7 +282,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
this.frontend.bell$.subscribe(() => {
if (this.config.store.terminal.bell === 'visual') {
this.frontend.visualBell()
this.frontend?.visualBell()
}
if (this.config.store.terminal.bell === 'audible') {
this.bellPlayer.play()
@@ -295,9 +313,9 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
if (!(data instanceof Buffer)) {
data = Buffer.from(data, 'utf-8')
}
this.session.write(data)
this.session?.write(data)
if (this.config.store.terminal.scrollOnInput) {
this.frontend.scrollToBottom()
this.frontend?.scrollToBottom()
}
}
@@ -305,6 +323,10 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
* Feeds input into the terminal frontend
*/
write (data: string): void {
if (!this.frontend) {
throw new Error('Frontend not ready')
}
const percentageMatch = /(^|[^\d])(\d+(\.\d+)?)%([^\d]|$)/.exec(data)
if (!this.alternateScreenActive && percentageMatch) {
const percentage = percentageMatch[3] ? parseFloat(percentageMatch[2]) : parseInt(percentageMatch[2])
@@ -357,7 +379,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
* Applies the user settings to the terminal
*/
configure (): void {
this.frontend.configure()
this.frontend?.configure()
this.topPadded = this.hostApp.platform === Platform.macOS
&& this.config.store.appearance.frame === 'thin'
@@ -374,17 +396,17 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
zoomIn (): void {
this.zoom++
this.frontend.setZoom(this.zoom)
this.frontend?.setZoom(this.zoom)
}
zoomOut (): void {
this.zoom--
this.frontend.setZoom(this.zoom)
this.frontend?.setZoom(this.zoom)
}
resetZoom (): void {
this.zoom = 0
this.frontend.setZoom(this.zoom)
this.frontend?.setZoom(this.zoom)
}
focusAllPanes (): void {
@@ -394,13 +416,13 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
if (this.parent instanceof SplitTabComponent) {
this.parent._allFocusMode = true
this.parent.layout()
this.allFocusModeSubscription = this.frontend.input$.subscribe(data => {
this.allFocusModeSubscription = this.frontend?.input$.subscribe(data => {
for (const tab of (this.parent as SplitTabComponent).getAllTabs()) {
if (tab !== this && tab instanceof BaseTerminalTabComponent) {
tab.sendInput(data)
}
}
})
}) ?? null
}
}
@@ -418,7 +440,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
/** @hidden */
ngOnDestroy (): void {
this.frontend.detach(this.content.nativeElement)
this.frontend?.detach(this.content.nativeElement)
this.detachTermContainerHandlers()
this.config.enabledServices(this.decorators).forEach(decorator => {
try {
@@ -451,6 +473,10 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
protected attachTermContainerHandlers (): void {
this.detachTermContainerHandlers()
if (!this.frontend) {
throw new Error('Frontend not ready')
}
const maybeConfigure = () => {
if (this.hasFocus) {
setTimeout(() => this.configure(), 250)
@@ -464,8 +490,8 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
}
})),
this.focused$.subscribe(() => this.frontend.enableResizing = true),
this.blurred$.subscribe(() => this.frontend.enableResizing = false),
this.focused$.subscribe(() => this.frontend && (this.frontend.enableResizing = true)),
this.blurred$.subscribe(() => this.frontend && (this.frontend.enableResizing = false)),
this.frontend.mouseEvent$.subscribe(async event => {
if (event.type === 'mousedown') {
@@ -525,6 +551,10 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
}
protected attachSessionHandlers (destroyOnSessionClose = false): void {
if (!this.session) {
throw new Error('Session not set')
}
// this.session.output$.bufferTime(10).subscribe((datas) => {
this.session.output$.subscribe(data => {
if (this.enablePassthrough) {
@@ -537,7 +567,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
if (destroyOnSessionClose) {
this.sessionCloseSubscription = this.session.closed$.subscribe(() => {
this.frontend.destroy()
this.frontend?.destroy()
this.destroy()
})
}

View File

@@ -17,7 +17,7 @@ export abstract class TerminalDecorator {
* Make sure to call super()
*/
detach (terminal: BaseTerminalTabComponent): void {
for (const s of this.smartSubscriptions.get(terminal) || []) {
for (const s of this.smartSubscriptions.get(terminal) ?? []) {
s.unsubscribe()
}
this.smartSubscriptions.delete(terminal)
@@ -26,7 +26,10 @@ export abstract class TerminalDecorator {
/**
* Automatically cancel @subscription once detached from @terminal
*/
protected subscribeUntilDetached (terminal: BaseTerminalTabComponent, subscription: Subscription): void {
protected subscribeUntilDetached (terminal: BaseTerminalTabComponent, subscription?: Subscription): void {
if (!subscription) {
return
}
if (!this.smartSubscriptions.has(terminal)) {
this.smartSubscriptions.set(terminal, [])
}

View File

@@ -6,7 +6,7 @@ export interface ResizeEvent {
export interface SessionOptions {
name?: string
command: string
args: string[]
args?: string[]
cwd?: string
env?: Record<string, string>
width?: number

View File

@@ -93,11 +93,11 @@ export class ColorSchemeSettingsTabComponent {
}
getCurrentSchemeName () {
return (this.currentCustomScheme || this.currentStockScheme)?.name || 'Custom'
return (this.currentCustomScheme ?? this.currentStockScheme)?.name ?? 'Custom'
}
findMatchingScheme (scheme: TerminalColorScheme, schemes: TerminalColorScheme[]) {
return schemes.find(x => deepEqual(x, scheme)) || null
return schemes.find(x => deepEqual(x, scheme)) ?? null
}
colorsTrackBy (index) {

View File

@@ -18,8 +18,8 @@ export class EditProfileModalComponent {
}
ngOnInit () {
this.profile.sessionOptions.env = this.profile.sessionOptions.env || {}
this.profile.sessionOptions.args = this.profile.sessionOptions.args || []
this.profile.sessionOptions.env = this.profile.sessionOptions.env ?? {}
this.profile.sessionOptions.args = this.profile.sessionOptions.args ?? []
}
save () {

View File

@@ -60,14 +60,12 @@ export class ShellSettingsTabComponent {
properties: ['openDirectory', 'showHiddenFiles'],
}
)).filePaths
if (paths) {
this.config.store.terminal.workingDirectory = paths[0]
}
this.config.store.terminal.workingDirectory = paths[0]
}
newProfile (shell: Shell): void {
const profile: Profile = {
name: shell.name || '',
name: shell.name ?? '',
shell: shell.id,
sessionOptions: this.terminal.optionsFromShell(shell),
}

View File

@@ -53,7 +53,7 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
initializeSession (columns: number, rows: number): void {
this.sessions.addSession(
this.session,
this.session!,
Object.assign({}, this.sessionOptions, {
width: columns,
height: rows,
@@ -69,15 +69,15 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
type: 'app:terminal-tab',
sessionOptions: {
...this.sessionOptions,
cwd: cwd || this.sessionOptions.cwd,
cwd: cwd ?? this.sessionOptions.cwd,
},
savedState: this.frontend?.saveState(),
}
}
async getCurrentProcess (): Promise<BaseTabProcess|null> {
const children = await this.session.getChildProcesses()
if (!children.length) {
const children = await this.session?.getChildProcesses()
if (!children?.length) {
return null
}
return {
@@ -86,8 +86,8 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
}
async canClose (): Promise<boolean> {
const children = await this.session.getChildProcesses()
if (children.length === 0) {
const children = await this.session?.getChildProcesses()
if (!children?.length) {
return true
}
return (await this.electron.showMessageBox(
@@ -104,6 +104,6 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
ngOnDestroy (): void {
this.homeEndSubscription.unsubscribe()
super.ngOnDestroy()
this.session.destroy()
this.session?.destroy()
}
}

View File

@@ -18,7 +18,7 @@ export class DebugDecorator extends TerminalDecorator {
let sessionOutputBuffer = ''
const bufferLength = 8192
this.subscribeUntilDetached(terminal, terminal.session.output$.subscribe(data => {
this.subscribeUntilDetached(terminal, terminal.session!.output$.subscribe(data => {
sessionOutputBuffer += data
if (sessionOutputBuffer.length > bufferLength) {
sessionOutputBuffer = sessionOutputBuffer.substring(sessionOutputBuffer.length - bufferLength)
@@ -88,18 +88,18 @@ export class DebugDecorator extends TerminalDecorator {
}
private doSaveState (terminal: TerminalTabComponent) {
this.saveFile(terminal.frontend.saveState(), 'state.txt')
this.saveFile(terminal.frontend!.saveState(), 'state.txt')
}
private async doCopyState (terminal: TerminalTabComponent) {
const data = '```' + JSON.stringify(terminal.frontend.saveState()) + '```'
const data = '```' + JSON.stringify(terminal.frontend!.saveState()) + '```'
this.electron.clipboard.writeText(data)
}
private async doLoadState (terminal: TerminalTabComponent) {
const data = await this.loadFile()
if (data) {
terminal.frontend.restoreState(data)
terminal.frontend!.restoreState(data)
}
}
@@ -109,7 +109,7 @@ export class DebugDecorator extends TerminalDecorator {
if (data.startsWith('`')) {
data = data.substring(3, data.length - 3)
}
terminal.frontend.restoreState(JSON.parse(data))
terminal.frontend!.restoreState(JSON.parse(data))
}
}
@@ -125,7 +125,7 @@ export class DebugDecorator extends TerminalDecorator {
private async doLoadOutput (terminal: TerminalTabComponent) {
const data = await this.loadFile()
if (data) {
terminal.frontend.write(data)
terminal.frontend?.write(data)
}
}
@@ -135,7 +135,7 @@ export class DebugDecorator extends TerminalDecorator {
if (data.startsWith('`')) {
data = data.substring(3, data.length - 3)
}
terminal.frontend.write(JSON.parse(data))
terminal.frontend?.write(JSON.parse(data))
}
}
}

View File

@@ -7,10 +7,10 @@ import { TerminalTabComponent } from '../components/terminalTab.component'
export class PathDropDecorator extends TerminalDecorator {
attach (terminal: TerminalTabComponent): void {
setTimeout(() => {
this.subscribeUntilDetached(terminal, terminal.frontend.dragOver$.subscribe(event => {
this.subscribeUntilDetached(terminal, terminal.frontend?.dragOver$.subscribe(event => {
event.preventDefault()
}))
this.subscribeUntilDetached(terminal, terminal.frontend.drop$.subscribe(event => {
this.subscribeUntilDetached(terminal, terminal.frontend?.drop$.subscribe((event: DragEvent) => {
for (const file of event.dataTransfer!.files as any) {
this.injectPath(terminal, file.path)
}

View File

@@ -36,7 +36,7 @@ export class ZModemDecorator extends TerminalDecorator {
terminal.write(data)
}
},
sender: data => terminal.session.write(Buffer.from(data)),
sender: data => terminal.session!.write(Buffer.from(data)),
on_detect: async detection => {
try {
terminal.enablePassthrough = false
@@ -50,7 +50,7 @@ export class ZModemDecorator extends TerminalDecorator {
},
})
setTimeout(() => {
this.subscribeUntilDetached(terminal, terminal.session.binaryOutput$.subscribe(data => {
this.subscribeUntilDetached(terminal, terminal.session!.binaryOutput$.subscribe(data => {
const chunkSize = 1024
for (let i = 0; i <= Math.floor(data.length / chunkSize); i++) {
try {
@@ -153,6 +153,7 @@ export class ZModemDecorator extends TerminalDecorator {
this.cancelEvent.toPromise(),
])
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (canceled) {
this.showMessage(terminal, colors.bgRed.black(' Canceled ') + ' ' + details.name)
} else {
@@ -207,6 +208,7 @@ export class ZModemDecorator extends TerminalDecorator {
await xfer.end()
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (canceled) {
this.showMessage(terminal, colors.bgRed.black(' Canceled ') + ' ' + offer.name)
} else {

View File

@@ -33,7 +33,7 @@ export class XTermFrontend extends Frontend {
private search = new SearchAddon()
private fitAddon = new FitAddon()
private serializeAddon = new SerializeAddon()
private ligaturesAddon: LigaturesAddon
private ligaturesAddon?: LigaturesAddon
private opened = false
constructor () {
@@ -298,7 +298,7 @@ export class XTermFrontend extends Frontend {
html += this.getLineAsHTML(selection.startRow, selection.startColumn, selection.endColumn)
} else {
html += this.getLineAsHTML(selection.startRow, selection.startColumn, this.xterm.cols)
for (let y = selection.startRow! + 1; y < selection.endRow; y++) {
for (let y = selection.startRow + 1; y < selection.endRow; y++) {
html += this.getLineAsHTML(y, 0, this.xterm.cols)
}
html += this.getLineAsHTML(selection.endRow, 0, selection.endColumn)

View File

@@ -171,7 +171,7 @@ export default class TerminalModule { // eslint-disable-line @typescript-eslint/
argv = argv.slice(1)
}
if (require('yargs').parse(argv.slice(1))._[0] !== 'open'){
if (require('yargs/yargs')(argv.slice(1)).parse()._[0] !== 'open'){
app.ready$.subscribe(() => {
terminal.openTab()
})

View File

@@ -7,7 +7,7 @@ import { TerminalTabComponent } from './components/terminalTab.component'
@Injectable()
export class RecoveryProvider extends TabRecoveryProvider {
async recover (recoveryToken: RecoveryToken): Promise<RecoveredTab|null> {
if (recoveryToken?.type === 'app:terminal-tab') {
if (recoveryToken.type === 'app:terminal-tab') {
return {
type: TerminalTabComponent,
options: {

View File

@@ -102,7 +102,7 @@ export class Session extends BaseSession {
}
start (options: SessionOptions): void {
this.name = options.name || ''
this.name = options.name ?? ''
const env = {
...process.env,
@@ -113,7 +113,7 @@ export class Session extends BaseSession {
}
if (process.platform === 'darwin' && !process.env.LC_ALL) {
const locale = process.env.LC_CTYPE || 'en_US.UTF-8'
const locale = process.env.LC_CTYPE ?? 'en_US.UTF-8'
Object.assign(env, {
LANG: locale,
LC_ALL: locale,
@@ -124,17 +124,17 @@ export class Session extends BaseSession {
})
}
let cwd = options.cwd || process.env.HOME
let cwd = options.cwd ?? process.env.HOME
if (!fs.existsSync(cwd)) {
console.warn('Ignoring non-existent CWD:', cwd)
cwd = undefined
}
this.pty = nodePTY.spawn(options.command, options.args || [], {
this.pty = nodePTY.spawn(options.command, options.args ?? [], {
name: 'xterm-256color',
cols: options.width || 80,
rows: options.height || 30,
cols: options.width ?? 80,
rows: options.height ?? 30,
encoding: null,
cwd,
env: env,
@@ -142,7 +142,7 @@ export class Session extends BaseSession {
useConpty: (isWindowsBuild(WIN_BUILD_CONPTY_SUPPORTED) && this.config.store.terminal.useConPTY ? 1 : false) as any,
})
this.guessedCWD = cwd || null
this.guessedCWD = cwd ?? null
this.truePID = this.pty['pid']
@@ -181,7 +181,7 @@ export class Session extends BaseSession {
}
})
this.pauseAfterExit = options.pauseAfterExit || false
this.pauseAfterExit = options.pauseAfterExit ?? false
}
resize (columns: number, rows: number): void {
@@ -331,7 +331,7 @@ export class Session extends BaseSession {
/** @hidden */
@Injectable({ providedIn: 'root' })
export class SessionsService {
sessions: Record<string, BaseSession> = {}
sessions = new Map<string, BaseSession>()
logger: Logger
private lastID = 0
@@ -347,9 +347,9 @@ export class SessionsService {
options.name = `session-${this.lastID}`
session.start(options)
session.destroyed$.pipe(first()).subscribe(() => {
delete this.sessions[session.name]
this.sessions.delete(session.name)
})
this.sessions[session.name] = session
this.sessions.set(session.name, session)
return session
}
}

View File

@@ -38,6 +38,7 @@ export class TerminalService {
const shells = await this.shells$.toPromise()
return [
...this.config.store.terminal.profiles,
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
...skipDefault ? [] : shells.filter(x => includeHidden || !x.hidden).map(shell => ({
name: shell.name,
shell: shell.id,
@@ -52,16 +53,16 @@ export class TerminalService {
return slugify(profile.name, { remove: /[:.]/g }).toLowerCase()
}
async getProfileByID (id: string): Promise<Profile> {
async getProfileByID (id: string): Promise<Profile|null> {
const profiles = await this.getProfiles({ includeHidden: true })
return profiles.find(x => this.getProfileID(x) === id) || profiles[0]
return profiles.find(x => this.getProfileID(x) === id) ?? null
}
/**
* Launches a new terminal with a specific shell and CWD
* @param pause Wait for a keypress when the shell exits
*/
async openTab (profile?: Profile, cwd?: string|null, pause?: boolean): Promise<TerminalTabComponent> {
async openTab (profile?: Profile|null, cwd?: string|null, pause?: boolean): Promise<TerminalTabComponent> {
if (!profile) {
profile = await this.getProfileByID(this.config.store.terminal.profile)
if (!profile) {
@@ -69,7 +70,7 @@ export class TerminalService {
}
}
cwd = cwd || profile.sessionOptions.cwd
cwd = cwd ?? profile.sessionOptions.cwd
if (cwd && !fs.existsSync(cwd)) {
console.warn('Ignoring non-existent CWD:', cwd)
@@ -89,20 +90,19 @@ export class TerminalService {
}
}
}
cwd = cwd || this.config.store.terminal.workingDirectory
cwd = cwd || null
cwd = cwd ?? this.config.store.terminal.workingDirectory
}
this.logger.info(`Starting profile ${profile.name}`, profile)
const sessionOptions = {
...profile.sessionOptions,
pauseAfterExit: pause,
cwd: cwd || undefined,
cwd: cwd ?? undefined,
}
const tab = this.openTabWithOptions(sessionOptions)
if (profile?.color) {
(this.app.getParentTab(tab) || tab).color = profile.color
if (profile.color) {
(this.app.getParentTab(tab) ?? tab).color = profile.color
}
return tab
}
@@ -110,7 +110,7 @@ export class TerminalService {
optionsFromShell (shell: Shell): SessionOptions {
return {
command: shell.command,
args: shell.args || [],
args: shell.args ?? [],
env: shell.env,
}
}

View File

@@ -32,7 +32,7 @@ export class UACService {
}
const options = { ...sessionOptions }
options.args = [options.command, ...options.args]
options.args = [options.command, ...options.args ?? []]
options.command = helperPath
return options
}

View File

@@ -30,7 +30,7 @@ export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
const profile = {
sessionOptions: {
...tab.sessionOptions,
cwd: await tab.session.getWorkingDirectory() || tab.sessionOptions.cwd,
cwd: await tab.session?.getWorkingDirectory() ?? tab.sessionOptions.cwd,
},
name: tab.sessionOptions.command,
}
@@ -79,7 +79,7 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
click: () => this.zone.run(async () => {
let workingDirectory = this.config.store.terminal.workingDirectory
if (this.config.store.terminal.alwaysUseWorkingDirectory !== true && tab instanceof TerminalTabComponent) {
workingDirectory = await tab.session.getWorkingDirectory()
workingDirectory = await tab.session?.getWorkingDirectory()
}
await this.terminalService.openTab(profile, workingDirectory)
}),
@@ -150,7 +150,7 @@ export class CopyPasteContextMenu extends TabContextMenuItemProvider {
click: (): void => {
this.zone.run(() => {
setTimeout(() => {
tab.frontend.copySelection()
tab.frontend?.copySelection()
this.toastr.info('Copied')
})
})
@@ -174,7 +174,7 @@ export class LegacyContextMenu extends TabContextMenuItemProvider {
weight = 1
constructor (
@Optional() @Inject(TerminalContextMenuItemProvider) protected contextMenuProviders: TerminalContextMenuItemProvider[],
@Optional() @Inject(TerminalContextMenuItemProvider) protected contextMenuProviders: TerminalContextMenuItemProvider[]|null,
) {
super()
}

View File

@@ -74,4 +74,6 @@ module.exports = {
'ngx-toastr',
/^terminus-/,
],
// Ignore warnings due to yarg's dynamic module loading
ignoreWarnings: [/node_modules\/yargs/],
}

347
yarn.lock
View File

@@ -52,6 +52,17 @@
global-agent "^2.0.2"
global-tunnel-ng "^2.7.1"
"@electron/universal@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.0.4.tgz#231ac246c39d45b80e159bd21c3f9027dcaa10f5"
integrity sha512-ajZoumi4XwqwmZe8YVhu4XGkZBCPyWZsVCQONPTIe9TUlleSN+dic3YpXlaWcilx/HOzTdldTKtabNTeI0gDoA==
dependencies:
"@malept/cross-spawn-promise" "^1.1.0"
asar "^3.0.3"
debug "^4.3.1"
dir-compare "^2.4.0"
fs-extra "^9.0.1"
"@eslint/eslintrc@^0.2.2":
version "0.2.2"
resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz"
@@ -383,9 +394,9 @@
resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz"
integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
"@types/yargs@^15.0.11":
"@types/yargs@^15.0.12":
version "15.0.12"
resolved "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.12.tgz"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.12.tgz#6234ce3e3e3fa32c5db301a170f96a599c960d74"
integrity sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw==
dependencies:
"@types/yargs-parser" "*"
@@ -678,9 +689,9 @@ acorn@^8.0.4:
integrity sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==
agent-base@4, agent-base@^4.0.1, agent-base@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/agent-base/-/agent-base-4.1.0.tgz"
integrity sha1-IOF0Ac1Js8B2v1akvGxbQ2/6jVU=
version "4.3.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
dependencies:
es6-promisify "^5.0.0"
@@ -803,26 +814,27 @@ ansistyles@~0.1.3:
resolved "https://registry.npmjs.org/ansistyles/-/ansistyles-0.1.3.tgz"
integrity sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk=
app-builder-bin@3.5.10:
version "3.5.10"
resolved "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.5.10.tgz"
integrity sha512-Jd+GW68lR0NeetgZDo47PdWBEPdnD+p0jEa7XaxjRC8u6Oo/wgJsfKUkORRgr2NpkD19IFKN50P6JYy04XHFLQ==
app-builder-bin@3.5.12:
version "3.5.12"
resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.12.tgz#bbe174972cc1f481f73d6d92ad47a8b4c7eb4530"
integrity sha512-lQARM2AielmFoBeIo6LZigAe+58Wwe07ZWkt+wVeDxzyieNmeWjlvz/V5dKzinydwdHd+CNswN86sww46yijjA==
app-builder-lib@22.10.3:
version "22.10.3"
resolved "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.10.3.tgz"
integrity sha512-PBHTTGxV1uLVHWKQfw92plrfMo/utH0FVe8v2dFmT/CYKw9u7XuOC0xE8YslUxXmaiG6TuOJaQrII4fXN5VBpQ==
app-builder-lib@22.10.4:
version "22.10.4"
resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.10.4.tgz#3fc70821b76beb9c8279d9de22960ef2174da153"
integrity sha512-q7B1cr8Ry4a7o08EKShLfwsnIVf5By7YhVwcoqgEwPKxtoj1qF0kB4wyBP79rJylYi0Zj2cSkJJ/gD/ef9xhoQ==
dependencies:
"7zip-bin" "~5.0.3"
"@develar/schema-utils" "~2.6.5"
"@electron/universal" "1.0.4"
async-exit-hook "^2.0.1"
bluebird-lst "^1.0.9"
builder-util "22.10.3"
builder-util "22.10.4"
builder-util-runtime "8.7.3"
chromium-pickle-js "^0.2.0"
debug "^4.3.2"
debug "^4.3.1"
ejs "^3.1.5"
electron-publish "22.10.3"
electron-publish "22.10.4"
fs-extra "^9.0.1"
hosted-git-info "^3.0.7"
is-ci "^2.0.0"
@@ -938,7 +950,7 @@ asap@~2.0.3:
resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz"
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
asar@^3.0.0:
asar@^3.0.0, asar@^3.0.3:
version "3.0.3"
resolved "https://registry.npmjs.org/asar/-/asar-3.0.3.tgz"
integrity sha512-k7zd+KoR+n8pl71PvgElcoKHrVNiSXtw7odKbyNpmgKe7EGRF9Pnu3uLOukD37EvavKwVFxOUpqXTIZC5B5Pmw==
@@ -1076,7 +1088,7 @@ babylon@^6.18.0:
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
base64-js@^1.2.3, base64-js@^1.3.1:
@@ -1200,7 +1212,7 @@ boxen@^4.2.0:
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
@@ -1240,11 +1252,34 @@ browserslist@^4.14.5:
escalade "^3.1.1"
node-releases "^1.1.67"
buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
buffer-alloc@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
dependencies:
buffer-alloc-unsafe "^1.1.0"
buffer-fill "^1.0.0"
buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz"
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
buffer-equal@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe"
integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74=
buffer-fill@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
buffer-from@^1.0.0:
version "1.1.1"
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz"
@@ -1266,19 +1301,19 @@ builder-util-runtime@8.7.3:
debug "^4.3.2"
sax "^1.2.4"
builder-util@22.10.3:
version "22.10.3"
resolved "https://registry.npmjs.org/builder-util/-/builder-util-22.10.3.tgz"
integrity sha512-I9mh78wZaggIF4QkBzMPKhfgGDameyx9TN6Zikl8SKQHiKQNCUzMPUcRXCyCot6iTT8B8blwOM3GhhuU06yv1g==
builder-util@22.10.4:
version "22.10.4"
resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.10.4.tgz#54e8be83dd0dec28073d866ff087cee8e7ce6cf6"
integrity sha512-XdcbFG3otEkNRKxW2wS1npNviCb/IrzusEQ55lMB+6YEHxBOfTbf8vnPt0pDumfwmxls9xczABU+mfqN/W4uDw==
dependencies:
"7zip-bin" "~5.0.3"
"@types/debug" "^4.1.5"
"@types/fs-extra" "^9.0.5"
app-builder-bin "3.5.10"
app-builder-bin "3.5.12"
bluebird-lst "^1.0.9"
builder-util-runtime "8.7.3"
chalk "^4.1.0"
debug "^4.3.2"
debug "^4.3.1"
fs-extra "^9.0.1"
is-ci "^2.0.0"
js-yaml "^3.14.1"
@@ -1481,12 +1516,7 @@ character-parser@^2.1.1:
dependencies:
is-regex "^1.0.3"
chownr@^1.0.1, chownr@~1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz"
integrity sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=
chownr@^1.1.1:
chownr@^1.0.1, chownr@^1.1.1:
version "1.1.4"
resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
@@ -1496,6 +1526,11 @@ chownr@^2.0.0:
resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz"
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
chownr@~1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz"
integrity sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=
chrome-trace-event@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz"
@@ -1677,6 +1712,11 @@ colorette@^1.2.1:
resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz"
integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
colors@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
colors@^1.3.3:
version "1.4.0"
resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz"
@@ -1719,6 +1759,13 @@ commander@2.17.x:
resolved "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz"
integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
commander@2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=
dependencies:
graceful-readlink ">= 1.0.0"
commander@^2.20.0, commander@^2.9.0:
version "2.20.3"
resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
@@ -1739,6 +1786,11 @@ commander@~2.19.0:
resolved "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz"
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
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-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz"
@@ -1746,7 +1798,7 @@ component-emitter@^1.2.1:
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
concat-stream@^1.5.0, concat-stream@^1.5.2:
@@ -2006,20 +2058,27 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
debug@2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.4.1, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
debug@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2:
debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2:
version "4.3.2"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz"
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
dependencies:
ms "2.1.2"
debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.4.1, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
debug@^3.0.0, debug@^3.2.6:
version "3.2.7"
resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
@@ -2145,6 +2204,16 @@ dezalgo@^1.0.0, dezalgo@~1.0.3:
asap "^2.0.0"
wrappy "1"
dir-compare@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-2.4.0.tgz#785c41dc5f645b34343a4eafc50b79bac7f11631"
integrity sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA==
dependencies:
buffer-equal "1.0.0"
colors "1.0.3"
commander "2.9.0"
minimatch "3.0.4"
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
@@ -2152,13 +2221,13 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"
dmg-builder@22.10.3:
version "22.10.3"
resolved "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.10.3.tgz"
integrity sha512-OB0etdtZJrvx85ah1aoTv5zJ9CXlsepLs9VT6ax6FXxH9aGxJU38AuB8065OPTrj+btMuHQDd0kBVlcs4/BwpA==
dmg-builder@22.10.4:
version "22.10.4"
resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.10.4.tgz#8dab30754346791eb728091359558fd4a8dbb45f"
integrity sha512-+28HZgKAuyCQnQwLSAwkHUqtMB/egHF5ACUABCB4Nev02/ZfjFPUTF/WloTaEbue34zLLUGxPXh+BJF8Xw26ow==
dependencies:
app-builder-lib "22.10.3"
builder-util "22.10.3"
app-builder-lib "22.10.4"
builder-util "22.10.4"
fs-extra "^9.0.1"
iconv-lite "^0.6.2"
js-yaml "^3.14.1"
@@ -2265,18 +2334,18 @@ ejs@^3.1.5:
dependencies:
jake "^10.6.1"
electron-builder@22.10.3:
version "22.10.3"
resolved "https://registry.npmjs.org/electron-builder/-/electron-builder-22.10.3.tgz"
integrity sha512-TNKmeYWrnATD/BBkpmNF03+wAA3+K8DZ6d/F1ipAKCbqeILp4agnr5nrngz+xpl7Y83lhelC1moU4utHNWYhzw==
electron-builder@22.10.4:
version "22.10.4"
resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.10.4.tgz#e1f400cf41ebb632fbf79aa86c5e0ab1ea1ed7e5"
integrity sha512-V+JtiizJd3kt24TT+0OHG7+oPAzjhhjmQVn9G6OC2WE7VBJxrDuD6lMVRgo6WlU8uvDCh7fTRUsdh0Tnu0GeQA==
dependencies:
"@types/yargs" "^15.0.11"
app-builder-lib "22.10.3"
"@types/yargs" "^15.0.12"
app-builder-lib "22.10.4"
bluebird-lst "^1.0.9"
builder-util "22.10.3"
builder-util "22.10.4"
builder-util-runtime "8.7.3"
chalk "^4.1.0"
dmg-builder "22.10.3"
dmg-builder "22.10.4"
fs-extra "^9.0.1"
is-ci "^2.0.0"
lazy-val "^1.0.4"
@@ -2376,19 +2445,19 @@ electron-notarize@^1.0.0:
debug "^4.1.1"
fs-extra "^9.0.1"
electron-publish@22.10.3:
version "22.10.3"
resolved "https://registry.npmjs.org/electron-publish/-/electron-publish-22.10.3.tgz"
integrity sha512-NGcgDp0xT92NPB5lGckroz2n5h8Ud53SShmwZoVtCp1W+VOSWn5CVPnXDquzf7pMcZRfo8qoMZrlvUeOlY4oIg==
electron-publish@22.10.4:
version "22.10.4"
resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.10.4.tgz#944b00aa6a7746c31ce900ffd8106d243326dca8"
integrity sha512-cjVM0+9DQoV4TWfH8lVWoelJ89O2i5yDARVp5GCMHrB43XEU0Nr5eKYysgsbOSnZk5W8z1vfGpFWHj+AeAEDYg==
dependencies:
"@types/fs-extra" "^9.0.5"
bluebird-lst "^1.0.9"
builder-util "22.10.3"
builder-util "22.10.4"
builder-util-runtime "8.7.3"
chalk "^4.1.0"
fs-extra "^9.0.1"
lazy-val "^1.0.4"
mime "^2.4.6"
mime "^2.4.7"
electron-rebuild@^2.3.4:
version "2.3.4"
@@ -2461,16 +2530,9 @@ end-of-stream@1.0.0:
dependencies:
once "~1.3.0"
end-of-stream@^1.0.0:
version "1.4.0"
resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz"
integrity sha1-epDYM+/abPpurA9JSduw+tOmMgY=
dependencies:
once "^1.4.0"
end-of-stream@^1.1.0:
end-of-stream@^1.0.0, end-of-stream@^1.1.0:
version "1.4.4"
resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
dependencies:
once "^1.4.0"
@@ -2591,13 +2653,13 @@ es6-iterator@~2.0.3:
es6-symbol "^3.1.1"
es6-promise@^4.0.3:
version "4.1.1"
resolved "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz"
integrity sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==
version "4.2.8"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
es6-promisify@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz"
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
dependencies:
es6-promise "^4.0.3"
@@ -3116,6 +3178,11 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
fs-constants@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs-extra@^4.0.1:
version "4.0.3"
resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz"
@@ -3179,7 +3246,7 @@ fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.10:
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
fstream-ignore@^1.0.0:
@@ -3200,9 +3267,9 @@ fstream-npm@~1.2.1:
inherits "2"
fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.11:
version "1.0.11"
resolved "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz"
integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=
version "1.0.12"
resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045"
integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==
dependencies:
graceful-fs "^4.1.2"
inherits "~2.0.0"
@@ -3464,6 +3531,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0,
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
"graceful-readlink@>= 1.0.0":
version "1.0.1"
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
handlebars@^4.7.6:
version "4.7.6"
resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz"
@@ -3659,12 +3731,12 @@ http-cache-semantics@^4.0.0:
integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
http-proxy-agent@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.0.0.tgz"
integrity sha1-RkgqLwUjpNYIJVFwn0acs+SoX/Q=
version "2.1.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==
dependencies:
agent-base "4"
debug "2"
debug "3.1.0"
http-signature@~1.1.0:
version "1.1.1"
@@ -3821,22 +3893,17 @@ indexes-of@^1.0.1:
inflight@^1.0.4, inflight@~1.0.6:
version "1.0.6"
resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
inherits@^2.0.1, inherits@~2.0.0:
version "2.0.3"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
ini@1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
@@ -4737,6 +4804,11 @@ lzma-native@^6.0.1:
readable-stream "^2.3.5"
rimraf "^2.7.1"
macos-release@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.4.1.tgz#64033d0ec6a5e6375155a74b1a1eba8e509820ac"
integrity sha512-H/QHeBIN1fIGJX517pvK8IEK53yQOW7YcEI55oYtgjDdoCQQz7eJS94qt5kNrscReEyuD/JcdFCm2XBEcGOITg==
make-dir@^1.0.0:
version "1.3.0"
resolved "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz"
@@ -4898,7 +4970,7 @@ mime-types@~2.1.7:
dependencies:
mime-db "~1.27.0"
mime@^2.4.4, mime@^2.4.6:
mime@^2.4.4, mime@^2.4.7:
version "2.4.7"
resolved "https://registry.npmjs.org/mime/-/mime-2.4.7.tgz"
integrity sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA==
@@ -4918,21 +4990,16 @@ mimic-response@^3.1.0:
resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz"
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
version "3.0.4"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
dependencies:
brace-expansion "^1.1.7"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
@@ -4989,14 +5056,7 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
"mkdirp@>=0.5 0", mkdirp@~0.5.0, mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
dependencies:
minimist "0.0.8"
mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5:
"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1:
version "0.5.5"
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@@ -5381,9 +5441,9 @@ npm-run-path@^4.0.0:
path-key "^3.0.0"
npm-user-validate@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-1.0.0.tgz"
integrity sha1-jOyg9c6gTU6TUZ73LQVXp1Ei6VE=
version "1.0.1"
resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.1.tgz#31428fc5475fe8416023f178c0ab47935ad8c561"
integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw==
npm@5.1.0:
version "5.1.0"
@@ -5588,7 +5648,7 @@ object.values@^1.1.1:
once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0, once@~1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
dependencies:
wrappy "1"
@@ -5865,7 +5925,7 @@ path-exists@^4.0.0:
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
path-is-inside@^1.0.1, path-is-inside@~1.0.2:
@@ -6315,9 +6375,9 @@ pug@^2.0.0-rc.2, pug@^2.0.4:
pug-strip-comments "^1.0.4"
pump@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz"
integrity sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=
version "1.0.3"
resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954"
integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
@@ -6491,7 +6551,7 @@ read@1, read@~1.0.1, read@~1.0.7:
dependencies:
mute-stream "~0.0.4"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@~2.3.2:
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.2:
version "2.3.7"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@@ -6778,14 +6838,7 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
rimraf@2, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@~2.6.1:
version "2.6.1"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz"
integrity sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=
dependencies:
glob "^7.0.5"
rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1:
rimraf@2, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1:
version "2.7.1"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
@@ -6799,6 +6852,13 @@ rimraf@^3.0.0, rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
rimraf@~2.6.1:
version "2.6.1"
resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz"
integrity sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=
dependencies:
glob "^7.0.5"
roarr@^2.15.3:
version "2.15.4"
resolved "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz"
@@ -6878,7 +6938,7 @@ sax@^1.2.4:
resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.5, schema-utils@^2.7.0:
schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.5:
version "2.7.1"
resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz"
integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==
@@ -7384,9 +7444,9 @@ string_decoder@~1.1.1:
safe-buffer "~5.1.0"
stringstream@~0.0.4:
version "0.0.5"
resolved "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz"
integrity sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=
version "0.0.6"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72"
integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
version "3.0.1"
@@ -7455,13 +7515,13 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
style-loader@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz"
integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==
style-loader@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c"
integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==
dependencies:
loader-utils "^2.0.0"
schema-utils "^2.7.0"
schema-utils "^3.0.0"
sumchecker@^2.0.2:
version "2.0.2"
@@ -7543,9 +7603,9 @@ tapable@^2.0.0, tapable@^2.1.1:
integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==
tar-fs@^1.15.3:
version "1.15.3"
resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-1.15.3.tgz"
integrity sha1-7M+TXpQUk9gVECjmNuUc5MPKfyA=
version "1.16.3"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509"
integrity sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==
dependencies:
chownr "^1.0.1"
mkdirp "^0.5.1"
@@ -7553,13 +7613,16 @@ tar-fs@^1.15.3:
tar-stream "^1.1.2"
tar-stream@^1.1.2, tar-stream@^1.5.4:
version "1.5.4"
resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz"
integrity sha1-NlSc8E7RrumyowwBQyUiONr5QBY=
version "1.6.2"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555"
integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==
dependencies:
bl "^1.0.0"
buffer-alloc "^1.2.0"
end-of-stream "^1.0.0"
readable-stream "^2.0.0"
fs-constants "^1.0.0"
readable-stream "^2.3.0"
to-buffer "^1.1.1"
xtend "^4.0.0"
tar@^2.0.0, tar@~2.2.1:
@@ -7708,6 +7771,11 @@ tmp@^0.2.0:
dependencies:
rimraf "^3.0.0"
to-buffer@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80"
integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==
to-fast-properties@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz"
@@ -8414,7 +8482,7 @@ wrap-ansi@^7.0.0:
wrappy@1, wrappy@~1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
write-file-atomic@^2.0.0, write-file-atomic@^2.3.0:
@@ -8470,11 +8538,16 @@ xmldom@0.1.x:
resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz"
integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==
"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1:
"xtend@>=4.0.0 <4.1.0-0", xtend@~4.0.1:
version "4.0.1"
resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz"
integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=
xtend@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
xtend@~2.1.1:
version "2.1.2"
resolved "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz"