Compare commits

...

217 Commits

Author SHA1 Message Date
Eugene Pankov
f6d4a51239 proper xdg category 2021-03-14 11:51:27 +01:00
Eugene Pankov
36f77c5b63 added hex serial input/output modes 2021-03-14 11:34:58 +01:00
Eugene Pankov
3676b90c9f build fix 2021-03-13 22:09:05 +01:00
Eugene Pankov
c4204167cd make tab close button not take up extra space - fixes #3502 2021-03-13 22:08:20 +01:00
Eugene Pankov
604d7c464f fixed cycling tab reordering via hotkeys - fixes #3510 2021-03-13 21:43:36 +01:00
Eugene Pankov
e42bd11725 made progress detection optional - fixes #3472 2021-03-13 21:38:03 +01:00
Eugene Pankov
864932d663 settings ui tweak 2021-03-13 21:30:22 +01:00
Eugene Pankov
9e68c735dc added scrolling to typeahead - fixes #1178 2021-03-13 21:28:21 +01:00
Eugene Pankov
be43f8b50d disallow disabling core plugins - fixes #1990 2021-03-13 21:25:25 +01:00
Eugene Pankov
c290633e7e detect user@domain style usernames in ssh quick connect - fixes #3026 2021-03-13 21:02:49 +01:00
Eugene Pankov
d03211631a fixed #2600 2021-03-13 20:09:45 +01:00
Eugene Pankov
ca27c05f0f bumped electron 2021-03-13 20:06:42 +01:00
Eugene Pankov
62a21b03ea duplicate tab title and color when duplicating a tab - fixes #3588 2021-03-13 20:06:37 +01:00
Eugene Pankov
6236ee95c3 Update app.module.ts 2021-03-10 22:25:02 +01:00
Eugene Pankov
836014c270 shorter notification for copying 2021-03-10 22:08:11 +01:00
Eugene Pankov
0bf870738e option to disable dynamic tab title in profiles - fixes #3574 2021-03-10 21:36:12 +01:00
Eugene Pankov
7c1697b9cb Revert "Bump electron-is-dev from 1.2.0 to 2.0.0 in /app"
This reverts commit a241144827.
2021-03-10 21:17:42 +01:00
Eugene Pankov
c800dd6e44 Merge branch 'master' of github.com:Eugeny/terminus 2021-03-10 20:54:44 +01:00
Eugene
68e9a1f66b Merge pull request #3320 from Eugeny/dependabot/npm_and_yarn/terminus-core/ngx-perfect-scrollbar-10.1.0
Bump ngx-perfect-scrollbar from 8.0.0 to 10.1.0 in /terminus-core
2021-03-10 20:54:36 +01:00
Eugene Pankov
f925d63fb0 Merge branch 'master' of github.com:Eugeny/terminus 2021-03-10 20:51:53 +01:00
Eugene Pankov
e79fc13de9 bumped plugins 2021-03-10 20:51:50 +01:00
Eugene Pankov
0c963dcbcc expose sessionChanged$ 2021-03-10 20:51:44 +01:00
Eugene
b7b672ce9b Merge pull request #3548 from Eugeny/dependabot/npm_and_yarn/electron-builder-22.10.5
Bump electron-builder from 22.10.4 to 22.10.5
2021-03-10 20:50:33 +01:00
Eugene
4c8bb45d01 Merge pull request #3544 from Eugeny/dependabot/npm_and_yarn/graceful-fs-4.2.6 2021-03-10 20:49:11 +01:00
Eugene
d4f8a88451 Merge pull request #3525 from Eugeny/dependabot/npm_and_yarn/terminus-core/core-js-3.9.1 2021-03-10 20:49:01 +01:00
dependabot-preview[bot]
fac8fafa36 Bump electron-builder from 22.10.4 to 22.10.5
Bumps [electron-builder](https://github.com/electron-userland/electron-builder) from 22.10.4 to 22.10.5.
- [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.4...v22.10.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 19:48:54 +00:00
dependabot-preview[bot]
bc854fcfff Bump graceful-fs from 4.2.4 to 4.2.6
Bumps [graceful-fs](https://github.com/isaacs/node-graceful-fs) from 4.2.4 to 4.2.6.
- [Release notes](https://github.com/isaacs/node-graceful-fs/releases)
- [Commits](https://github.com/isaacs/node-graceful-fs/compare/v4.2.4...v4.2.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 19:48:51 +00:00
Eugene
ebc83b8064 Merge pull request #3375 from Eugeny/dependabot/npm_and_yarn/app/ngx-toastr-13.2.0 2021-03-10 20:48:50 +01:00
dependabot-preview[bot]
6757deab67 Bump core-js from 3.8.2 to 3.9.1 in /terminus-core
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.8.2 to 3.9.1.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.9.1/packages/core-js)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 19:48:28 +00:00
dependabot-preview[bot]
fe68d9a34e Bump ngx-toastr from 12.1.0 to 13.2.0 in /app
Bumps [ngx-toastr](https://github.com/scttcper/ngx-toastr) from 12.1.0 to 13.2.0.
- [Release notes](https://github.com/scttcper/ngx-toastr/releases)
- [Commits](https://github.com/scttcper/ngx-toastr/compare/v12.1.0...v13.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 19:48:26 +00:00
Eugene
2840ae2aa7 Merge pull request #3546 from Eugeny/dependabot/npm_and_yarn/pug-3.0.2
Bump pug from 3.0.1 to 3.0.2
2021-03-10 20:47:19 +01:00
Eugene
b275f5311d Merge pull request #3530 from Eugeny/dependabot/npm_and_yarn/core-js-3.9.1
Bump core-js from 3.8.3 to 3.9.1
2021-03-10 20:47:09 +01:00
Eugene
4e084cdc93 Merge pull request #3559 from Eugeny/dependabot/npm_and_yarn/app/node-abi-2.21.0
Bump node-abi from 2.20.0 to 2.21.0 in /app
2021-03-10 20:46:47 +01:00
Eugene
910b207160 Merge pull request #3572 from Eugeny/dependabot/npm_and_yarn/html-loader-2.1.2
Bump html-loader from 1.3.2 to 2.1.2
2021-03-10 20:46:23 +01:00
Eugene
f54ff37010 Merge pull request #3560 from Eugeny/dependabot/npm_and_yarn/typescript-eslint/parser-4.17.0
Bump @typescript-eslint/parser from 4.14.1 to 4.17.0
2021-03-10 20:42:50 +01:00
Eugene
03d9d46a8c Merge pull request #3423 from Eugeny/dependabot/npm_and_yarn/webpack-cli-4.5.0
Bump webpack-cli from 4.4.0 to 4.5.0
2021-03-10 20:42:41 +01:00
Eugene
7111f35268 Merge pull request #3550 from Eugeny/dependabot/npm_and_yarn/sentry/electron-2.4.0
Bump @sentry/electron from 2.2.0 to 2.4.0
2021-03-10 20:42:12 +01:00
Eugene
44427ac3b6 Merge pull request #3568 from Eugeny/dependabot/npm_and_yarn/terminus-terminal/xterm-4.11.0
Bump xterm from 4.10.0 to 4.11.0 in /terminus-terminal
2021-03-10 20:42:04 +01:00
Eugene
8816910e43 Merge pull request #3567 from Eugeny/dependabot/npm_and_yarn/terminus-terminal/xterm-addon-serialize-0.5.0
Bump xterm-addon-serialize from 0.4.0 to 0.5.0 in /terminus-terminal
2021-03-10 20:41:01 +01:00
Eugene
31464ee37a Merge pull request #3566 from Eugeny/dependabot/npm_and_yarn/terminus-terminal/xterm-addon-webgl-0.10.0
Bump xterm-addon-webgl from 0.9.0 to 0.10.0 in /terminus-terminal
2021-03-10 20:40:54 +01:00
dependabot-preview[bot]
4bdb72021b Bump html-loader from 1.3.2 to 2.1.2
Bumps [html-loader](https://github.com/webpack-contrib/html-loader) from 1.3.2 to 2.1.2.
- [Release notes](https://github.com/webpack-contrib/html-loader/releases)
- [Changelog](https://github.com/webpack-contrib/html-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/html-loader/compare/v1.3.2...v2.1.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 04:21:47 +00:00
dependabot-preview[bot]
7d5e70c718 Bump xterm from 4.10.0 to 4.11.0 in /terminus-terminal
Bumps [xterm](https://github.com/xtermjs/xterm.js) from 4.10.0 to 4.11.0.
- [Release notes](https://github.com/xtermjs/xterm.js/releases)
- [Commits](https://github.com/xtermjs/xterm.js/compare/4.10.0...4.11.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 04:18:43 +00:00
dependabot-preview[bot]
6af92c9f95 Bump xterm-addon-serialize from 0.4.0 to 0.5.0 in /terminus-terminal
Bumps xterm-addon-serialize from 0.4.0 to 0.5.0.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 04:18:16 +00:00
dependabot-preview[bot]
4a8fe78b07 Bump xterm-addon-webgl from 0.9.0 to 0.10.0 in /terminus-terminal
Bumps [xterm-addon-webgl](https://github.com/xtermjs/xterm.js) from 0.9.0 to 0.10.0.
- [Release notes](https://github.com/xtermjs/xterm.js/releases)
- [Commits](https://github.com/xtermjs/xterm.js/compare/0.9...0.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 04:17:54 +00:00
dependabot-preview[bot]
1aa6bc3c10 Bump @typescript-eslint/parser from 4.14.1 to 4.17.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.14.1 to 4.17.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.17.0/packages/parser)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-09 04:18:01 +00:00
dependabot-preview[bot]
93d74bf3cb Bump node-abi from 2.20.0 to 2.21.0 in /app
Bumps [node-abi](https://github.com/lgeiger/node-abi) from 2.20.0 to 2.21.0.
- [Release notes](https://github.com/lgeiger/node-abi/releases)
- [Commits](https://github.com/lgeiger/node-abi/compare/v2.20.0...v2.21.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-08 04:21:17 +00:00
Eugene
9e16ef5a57 Merge pull request #3555 from Eugeny/all-contributors/add-iamchating 2021-03-05 17:18:41 +03:00
allcontributors[bot]
741c77506c docs: update .all-contributorsrc [skip ci] 2021-03-05 14:17:23 +00:00
allcontributors[bot]
507cc16190 docs: update README.md [skip ci] 2021-03-05 14:17:22 +00:00
Eugene
bfeb353858 Merge pull request #3554 from iamchating/master
FIX: #3520
2021-03-05 17:17:06 +03:00
Tan, Tian
806bfef8bf FIX: #3520 2021-03-05 21:19:43 +08:00
Eugene Pankov
975b5a117d build typings before docs 2021-03-04 09:42:46 +01:00
dependabot-preview[bot]
46e4832a66 Bump @sentry/electron from 2.2.0 to 2.4.0
Bumps [@sentry/electron](https://github.com/getsentry/sentry-electron) from 2.2.0 to 2.4.0.
- [Release notes](https://github.com/getsentry/sentry-electron/releases)
- [Changelog](https://github.com/getsentry/sentry-electron/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-electron/compare/2.2.0...2.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-04 04:22:48 +00:00
dependabot-preview[bot]
6ab7093cc6 Bump pug from 3.0.1 to 3.0.2
Bumps [pug](https://github.com/pugjs/pug) from 3.0.1 to 3.0.2.
- [Release notes](https://github.com/pugjs/pug/releases)
- [Commits](https://github.com/pugjs/pug/compare/pug@3.0.1...pug@3.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-04 04:20:52 +00:00
dependabot-preview[bot]
00cc2474cc Bump core-js from 3.8.3 to 3.9.1
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.8.3 to 3.9.1.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.9.1/packages/core-js)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:42:25 +00:00
dependabot-preview[bot]
4e4d02041a Bump webpack-cli from 4.4.0 to 4.5.0
Bumps [webpack-cli](https://github.com/webpack/webpack-cli) from 4.4.0 to 4.5.0.
- [Release notes](https://github.com/webpack/webpack-cli/releases)
- [Changelog](https://github.com/webpack/webpack-cli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-cli/compare/webpack-cli@4.4.0...webpack-cli@4.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:41:22 +00:00
Eugene
09ac506dd3 Merge pull request #3504 from Eugeny/dependabot/npm_and_yarn/terminus-settings/utils-decorators-1.8.1
Bump utils-decorators from 1.8.0 to 1.8.1 in /terminus-settings
2021-03-03 23:40:26 +03:00
Eugene
769ce6bc0b Merge pull request #3527 from Eugeny/dependabot/npm_and_yarn/app/rxjs-6.6.6
Bump rxjs from 6.6.3 to 6.6.6 in /app
2021-03-03 23:40:14 +03:00
Eugene
26605124c1 Merge pull request #3172 from Eugeny/dependabot/npm_and_yarn/terminus-plugin-manager/semver-7.3.4
Bump semver from 7.2.2 to 7.3.4 in /terminus-plugin-manager
2021-03-03 23:40:07 +03:00
Eugene
7465c32645 Merge pull request #3380 from Eugeny/dependabot/npm_and_yarn/tslib-2.1.0
Bump tslib from 2.0.3 to 2.1.0
2021-03-03 23:39:56 +03:00
Eugene
846ac62a7f Merge pull request #3541 from Eugeny/dependabot/npm_and_yarn/pug-code-gen-2.0.3
Bump pug-code-gen from 2.0.2 to 2.0.3
2021-03-03 23:39:49 +03:00
Eugene
eae2c5ee16 Merge pull request #3529 from Eugeny/dependabot/npm_and_yarn/typescript-3.9.9
Bump typescript from 3.9.7 to 3.9.9
2021-03-03 23:39:05 +03:00
Eugene
4fd89105e5 Merge pull request #3483 from Eugeny/dependabot/npm_and_yarn/terminus-ssh/types/node-14.14.31
Bump @types/node from 14.14.14 to 14.14.31 in /terminus-ssh
2021-03-03 23:38:56 +03:00
dependabot[bot]
87c1bef16e Bump pug-code-gen from 2.0.2 to 2.0.3
Bumps [pug-code-gen](https://github.com/pugjs/pug) from 2.0.2 to 2.0.3.
- [Release notes](https://github.com/pugjs/pug/releases)
- [Commits](https://github.com/pugjs/pug/compare/pug-code-gen@2.0.2...pug@2.0.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-03 20:38:54 +00:00
Eugene
eed35c2613 Merge pull request #3484 from Eugeny/dependabot/npm_and_yarn/app/types/node-14.14.31
Bump @types/node from 14.14.14 to 14.14.31 in /app
2021-03-03 23:38:44 +03:00
dependabot-preview[bot]
678f2f7a85 Bump @types/node from 14.14.14 to 14.14.31 in /app
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.14 to 14.14.31.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:37:35 +00:00
Eugene
0b1bacaf0d Merge pull request #3542 from Eugeny/dependabot/npm_and_yarn/pug-3.0.1
[Security] Bump pug from 3.0.0 to 3.0.1
2021-03-03 23:37:31 +03:00
dependabot-preview[bot]
98b5a27382 Bump @types/node from 14.14.14 to 14.14.31 in /terminus-ssh
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.14 to 14.14.31.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:37:11 +00:00
dependabot-preview[bot]
76a81b9402 Bump typescript from 3.9.7 to 3.9.9
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 3.9.7 to 3.9.9.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v3.9.7...v3.9.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:36:37 +00:00
dependabot-preview[bot]
634b221aa3 Bump tslib from 2.0.3 to 2.1.0
Bumps [tslib](https://github.com/Microsoft/tslib) from 2.0.3 to 2.1.0.
- [Release notes](https://github.com/Microsoft/tslib/releases)
- [Commits](https://github.com/Microsoft/tslib/compare/2.0.3...2.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:36:17 +00:00
dependabot-preview[bot]
ffcb3e72c2 [Security] Bump pug from 3.0.0 to 3.0.1
Bumps [pug](https://github.com/pugjs/pug) from 3.0.0 to 3.0.1. **This update includes a security fix.**
- [Release notes](https://github.com/pugjs/pug/releases)
- [Commits](https://github.com/pugjs/pug/compare/pug@3.0.0...pug@3.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:36:17 +00:00
dependabot-preview[bot]
b4b7bdeb16 Bump semver from 7.2.2 to 7.3.4 in /terminus-plugin-manager
Bumps [semver](https://github.com/npm/node-semver) from 7.2.2 to 7.3.4.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/master/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v7.2.2...v7.3.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:36:04 +00:00
Eugene
21daa4aa18 Merge pull request #3486 from Eugeny/dependabot/npm_and_yarn/types/node-14.14.31
Bump @types/node from 14.14.14 to 14.14.31
2021-03-03 23:35:51 +03:00
Eugene
867dbcddcc Merge pull request #3482 from Eugeny/dependabot/npm_and_yarn/terminus-terminal/slugify-1.4.7
Bump slugify from 1.4.6 to 1.4.7 in /terminus-terminal
2021-03-03 23:35:08 +03:00
Eugene
b906dbd8d6 Merge pull request #3189 from Eugeny/dependabot/npm_and_yarn/terminus-core/uuid-8.3.2
Bump uuid from 8.2.0 to 8.3.2 in /terminus-core
2021-03-03 23:34:59 +03:00
Eugene
e5c7d0649f Merge pull request #3347 from Eugeny/dependabot/npm_and_yarn/terminus-ssh/run-script-os-1.1.5
Bump run-script-os from 1.1.3 to 1.1.5 in /terminus-ssh
2021-03-03 23:34:48 +03:00
Eugene
55286bc7e7 Merge pull request #3429 from Eugeny/dependabot/npm_and_yarn/sass-loader-11.0.1
Bump sass-loader from 10.1.1 to 11.0.1
2021-03-03 23:34:40 +03:00
Eugene Pankov
359e41f884 Merge branch 'dependabot/npm_and_yarn/typedoc-0.20.28' 2021-03-03 21:33:49 +01:00
Eugene Pankov
cc93578ada typedoc fixes 2021-03-03 21:33:37 +01:00
dependabot-preview[bot]
2e54fa317c Bump @types/node from 14.14.14 to 14.14.31
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.14 to 14.14.31.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:26:55 +00:00
dependabot-preview[bot]
c3bd725ce8 Bump ngx-perfect-scrollbar from 8.0.0 to 10.1.0 in /terminus-core
Bumps [ngx-perfect-scrollbar](https://github.com/zefoy/ngx-perfect-scrollbar) from 8.0.0 to 10.1.0.
- [Release notes](https://github.com/zefoy/ngx-perfect-scrollbar/releases)
- [Commits](https://github.com/zefoy/ngx-perfect-scrollbar/compare/v8.0.0...v10.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:25:49 +00:00
Eugene
18f69c5527 Merge pull request #3485 from Eugeny/dependabot/npm_and_yarn/app/serialport-9.0.7
Bump serialport from 9.0.4 to 9.0.7 in /app
2021-03-03 23:24:38 +03:00
Eugene
0102a2a61b Merge pull request #3301 from Eugeny/dependabot/npm_and_yarn/terminus-core/types/js-yaml-4.0.0
Bump @types/js-yaml from 3.12.5 to 4.0.0 in /terminus-core
2021-03-03 23:24:31 +03:00
Eugene
1de709561c Merge pull request #3381 from Eugeny/dependabot/npm_and_yarn/types/js-yaml-4.0.0
Bump @types/js-yaml from 3.12.5 to 4.0.0
2021-03-03 23:24:26 +03:00
Eugene
9f985ee8f0 Merge pull request #3287 from Eugeny/dependabot/npm_and_yarn/terminus-core/js-yaml-4.0.0
Bump js-yaml from 3.14.0 to 4.0.0 in /terminus-core
2021-03-03 23:24:20 +03:00
Eugene
1a35ed3c73 Merge pull request #3528 from Eugeny/dependabot/npm_and_yarn/app/electron-is-dev-2.0.0
Bump electron-is-dev from 1.2.0 to 2.0.0 in /app
2021-03-03 23:23:53 +03:00
dependabot-preview[bot]
a241144827 Bump electron-is-dev from 1.2.0 to 2.0.0 in /app
Bumps [electron-is-dev](https://github.com/sindresorhus/electron-is-dev) from 1.2.0 to 2.0.0.
- [Release notes](https://github.com/sindresorhus/electron-is-dev/releases)
- [Commits](https://github.com/sindresorhus/electron-is-dev/compare/v1.2.0...v2.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:04:32 +00:00
dependabot-preview[bot]
18e341f886 Bump js-yaml from 3.14.0 to 4.0.0 in /terminus-core
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.14.0 to 4.0.0.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.14.0...4.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:03:52 +00:00
Eugene
3182d4428d Merge pull request #3321 from Eugeny/dependabot/npm_and_yarn/app/glasstron-0.0.7
Bump glasstron from 0.0.6 to 0.0.7 in /app
2021-03-03 23:02:28 +03:00
Eugene
6dfcb9422a Merge pull request #3379 from Eugeny/dependabot/npm_and_yarn/fortawesome/fontawesome-free-5.15.2
Bump @fortawesome/fontawesome-free from 5.15.1 to 5.15.2
2021-03-03 22:59:20 +03:00
Eugene Pankov
ad5993b94f bumepd node-abi 2021-03-03 20:58:33 +01:00
Eugene Pankov
eb9826fb2a macos: only query default shell once 2021-03-02 22:55:06 +01:00
Eugene Pankov
1c81baa6f2 added docking space adjustment - fixes #3524 2021-03-02 22:53:26 +01:00
Eugene Pankov
e07c5db0a8 let themes specify macos titlebar buttons offset - fixes #3507 2021-03-02 22:41:17 +01:00
Eugene Pankov
b93989d02b remove titlebar padding in fullscreen - fixes #3532 2021-03-02 22:12:15 +01:00
Eugene Pankov
15bfde6077 Update linux.yml 2021-03-02 22:01:42 +01:00
Eugene Pankov
4243e79a11 patch node-abi in linux builds 2021-03-02 21:58:15 +01:00
Eugene Pankov
eb49001614 node-abi patches 2021-03-02 15:58:36 +01:00
Eugene
3aaa670400 Merge pull request #3535 from Eugeny/all-contributors/add-clarkwang 2021-03-02 13:03:25 +03:00
allcontributors[bot]
5371b2d1a6 docs: update .all-contributorsrc [skip ci] 2021-03-02 09:13:12 +00:00
allcontributors[bot]
e46281a9a7 docs: update README.md [skip ci] 2021-03-02 09:13:11 +00:00
Eugene
9d4aa179a0 Merge pull request #3534 from clarkwang/hotkeys-for-tab-11-20
fixes #3500: add hotkey support for Tabs 11~20
2021-03-02 12:12:59 +03:00
Clark Wang
20118afd1f fixes #3500: add hotkey support for Tabs 11~20 2021-03-02 16:57:40 +08:00
dependabot-preview[bot]
b29daac3c6 Bump @types/js-yaml from 3.12.5 to 4.0.0
Bumps [@types/js-yaml](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/js-yaml) from 3.12.5 to 4.0.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/js-yaml)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 08:56:51 +00:00
dependabot-preview[bot]
8ba9e8b210 Bump @types/js-yaml from 3.12.5 to 4.0.0 in /terminus-core
Bumps [@types/js-yaml](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/js-yaml) from 3.12.5 to 4.0.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/js-yaml)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 08:55:39 +00:00
Eugene
f3f3edfbb6 Merge pull request #3526 from Eugeny/dependabot/npm_and_yarn/terminus-core/electron-updater-4.3.8
Bump electron-updater from 4.3.5 to 4.3.8 in /terminus-core
2021-03-02 11:54:23 +03:00
Eugene Pankov
472cb18a16 Merge branch 'master' of github.com:Eugeny/terminus 2021-03-02 09:52:51 +01:00
Eugene Pankov
7c8d8ebc81 ui tweaks 2021-03-02 09:52:48 +01:00
Eugene Pankov
18fc0fa886 bumped electron to stable 2021-03-02 09:52:41 +01:00
dependabot-preview[bot]
5a90c246b9 Bump rxjs from 6.6.3 to 6.6.6 in /app
Bumps [rxjs](https://github.com/reactivex/rxjs) from 6.6.3 to 6.6.6.
- [Release notes](https://github.com/reactivex/rxjs/releases)
- [Changelog](https://github.com/ReactiveX/rxjs/blob/6.6.6/CHANGELOG.md)
- [Commits](https://github.com/reactivex/rxjs/compare/6.6.3...6.6.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 04:16:46 +00:00
dependabot-preview[bot]
9bc31556f2 Bump electron-updater from 4.3.5 to 4.3.8 in /terminus-core
Bumps [electron-updater](https://github.com/electron-userland/electron-builder) from 4.3.5 to 4.3.8.
- [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/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 04:16:22 +00:00
dependabot-preview[bot]
2c81491825 Bump @fortawesome/fontawesome-free from 5.15.1 to 5.15.2
Bumps [@fortawesome/fontawesome-free](https://github.com/FortAwesome/Font-Awesome) from 5.15.1 to 5.15.2.
- [Release notes](https://github.com/FortAwesome/Font-Awesome/releases)
- [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/master/CHANGELOG.md)
- [Commits](https://github.com/FortAwesome/Font-Awesome/compare/5.15.1...5.15.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-01 20:16:43 +00:00
dependabot-preview[bot]
9ed18d965c Bump glasstron from 0.0.6 to 0.0.7 in /app
Bumps [glasstron](https://github.com/AryToNeX/Glasstron) from 0.0.6 to 0.0.7.
- [Release notes](https://github.com/AryToNeX/Glasstron/releases)
- [Commits](https://github.com/AryToNeX/Glasstron/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-01 20:15:11 +00:00
Eugene
b4f76847bf Merge pull request #3425 from Eugeny/dependabot/npm_and_yarn/electron-rebuild-2.3.5
Bump electron-rebuild from 2.3.4 to 2.3.5
2021-03-01 23:03:26 +03:00
Eugene
b9bcb14dd7 Merge pull request #3466 from Eugeny/dependabot/npm_and_yarn/app/keytar-7.4.0
Bump keytar from 7.3.0 to 7.4.0 in /app
2021-03-01 23:03:05 +03:00
Eugene
ee3e17981b Merge pull request #3503 from Eugeny/dependabot/npm_and_yarn/app/zone.js-0.11.4
Bump zone.js from 0.11.3 to 0.11.4 in /app
2021-03-01 23:02:37 +03:00
Eugene
415d833ae6 Merge pull request #3515 from Eugeny/dependabot/npm_and_yarn/sentry/cli-1.63.0
Bump @sentry/cli from 1.61.0 to 1.63.0
2021-03-01 23:02:13 +03:00
Eugene Pankov
ed9117670e split fpm options 2021-02-28 12:34:49 +01:00
Eugene Pankov
0ecd47346d Merge branch 'master' of github.com:Eugeny/terminus 2021-02-28 12:15:27 +01:00
Eugene Pankov
bc0024ec06 disable packaging build-id links - fixes #3523 2021-02-28 12:15:25 +01:00
dependabot-preview[bot]
bdec20f7c7 Bump @sentry/cli from 1.61.0 to 1.63.0
Bumps [@sentry/cli](https://github.com/getsentry/sentry-cli) from 1.61.0 to 1.63.0.
- [Release notes](https://github.com/getsentry/sentry-cli/releases)
- [Changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-cli/compare/1.61.0...1.63.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-26 04:22:23 +00:00
dependabot-preview[bot]
45ebe3caf9 Bump utils-decorators from 1.8.0 to 1.8.1 in /terminus-settings
Bumps [utils-decorators](https://github.com/vlio20/utils-decorators) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/vlio20/utils-decorators/releases)
- [Commits](https://github.com/vlio20/utils-decorators/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-24 04:17:51 +00:00
dependabot-preview[bot]
7315bc8d8b Bump zone.js from 0.11.3 to 0.11.4 in /app
Bumps [zone.js](https://github.com/angular/angular/tree/HEAD/packages/zone.js) from 0.11.3 to 0.11.4.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/master/packages/zone.js/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/zone.js-0.11.4/packages/zone.js)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-24 04:17:15 +00:00
Eugene
a969dc1ea4 use yarn in HACKING.md 2021-02-23 13:51:48 +01:00
dependabot-preview[bot]
2733dc69be Bump typedoc from 0.18.0 to 0.20.28
Bumps [typedoc](https://github.com/TypeStrong/TypeDoc) from 0.18.0 to 0.20.28.
- [Release notes](https://github.com/TypeStrong/TypeDoc/releases)
- [Commits](https://github.com/TypeStrong/TypeDoc/compare/v0.18.0...v0.20.28)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-23 04:24:34 +00:00
Eugene Pankov
bb86848cd3 Merge branch 'master' of github.com:Eugeny/terminus 2021-02-22 11:22:25 +01:00
Eugene
e844ad6063 Merge pull request #3491 from Eugeny/all-contributors/add-VectorKappa 2021-02-22 12:58:48 +03:00
allcontributors[bot]
a096a691cc docs: update .all-contributorsrc [skip ci] 2021-02-22 09:58:08 +00:00
allcontributors[bot]
a28e25e96a docs: update README.md [skip ci] 2021-02-22 09:58:07 +00:00
Eugene
a09ce13709 Merge pull request #3489 from VectorKappa/master
Add Nord theme
2021-02-22 12:57:28 +03:00
VectorKappa
123d8ceb5f Add Nord theme 2021-02-22 09:34:36 +01:00
dependabot-preview[bot]
c0155c8d4e Bump serialport from 9.0.4 to 9.0.7 in /app
Bumps [serialport](https://github.com/serialport/node-serialport) from 9.0.4 to 9.0.7.
- [Release notes](https://github.com/serialport/node-serialport/releases)
- [Changelog](https://github.com/serialport/node-serialport/blob/master/CHANGELOG.md)
- [Commits](https://github.com/serialport/node-serialport/compare/@serialport/bindings@9.0.4...v9.0.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-22 04:18:38 +00:00
dependabot-preview[bot]
fcda35b02e Bump slugify from 1.4.6 to 1.4.7 in /terminus-terminal
Bumps [slugify](https://github.com/simov/slugify) from 1.4.6 to 1.4.7.
- [Release notes](https://github.com/simov/slugify/releases)
- [Commits](https://github.com/simov/slugify/compare/v1.4.6...v1.4.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-22 04:16:20 +00:00
Eugene Pankov
9d6a1031da more responsive css editing 2021-02-20 19:53:27 +01:00
Eugene Pankov
c119d3283e fixed #3464 2021-02-20 19:43:21 +01:00
dependabot-preview[bot]
3667fb45ee Bump keytar from 7.3.0 to 7.4.0 in /app
Bumps [keytar](https://github.com/atom/node-keytar) from 7.3.0 to 7.4.0.
- [Release notes](https://github.com/atom/node-keytar/releases)
- [Commits](https://github.com/atom/node-keytar/compare/v7.3.0...v7.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-16 04:16:55 +00:00
Eugene Pankov
92d34343f1 fixed missing serial settings tab 2021-02-15 16:08:55 +01:00
Eugene Pankov
8afad944b7 Merge branch 'master' of https://github.com/Eugeny/terminus 2021-02-14 13:07:56 +01:00
Eugene Pankov
707d077eb2 fixed winpty input - fixes #3397 2021-02-13 15:05:29 +01:00
Eugene Pankov
92eabab509 cleanup 2021-02-13 14:53:19 +01:00
Eugene Pankov
888cfc6548 fixed windows build 2021-02-13 14:10:56 +01:00
Eugene Pankov
9cb10c3e21 tweaked plugins ui 2021-02-13 13:53:25 +01:00
Eugene Pankov
661d5af9ba casing 2021-02-13 13:40:05 +01:00
Eugene Pankov
26429bf209 removed toolbar buttons from touchbar 2021-02-13 13:25:46 +01:00
Eugene Pankov
4779c41f48 bumped electron 2021-02-13 13:16:55 +01:00
Eugene Pankov
b11eda8653 bumped electron 2021-02-13 13:04:41 +01:00
Eugene Pankov
23bff8750c added static/dynamic tab size setting - fixes #3426 2021-02-13 12:55:55 +01:00
Eugene Pankov
aab1ae3ceb reconnect hotkey - fixes #3344 2021-02-13 12:49:07 +01:00
Eugene Pankov
9b5b5a9d00 re-fixed session restarting 2021-02-13 12:47:21 +01:00
Eugene Pankov
9c87cf3f3a fixed tabs on side with compact theme 2021-02-13 12:42:23 +01:00
Eugene Pankov
a8c7134218 fixed SSH reconnection behaviour - fixed #3446, fixed #3442 2021-02-13 12:42:15 +01:00
Eugene Pankov
9734830a74 web demo fixes 2021-02-13 12:14:14 +01:00
Eugene Pankov
5fa056751d bumped angular 2021-02-13 12:14:09 +01:00
Eugene Pankov
6fdccd0a02 cleanup webpack configs 2021-02-13 12:11:38 +01:00
dependabot-preview[bot]
41ee7b7bbf Bump sass-loader from 10.1.1 to 11.0.1
Bumps [sass-loader](https://github.com/webpack-contrib/sass-loader) from 10.1.1 to 11.0.1.
- [Release notes](https://github.com/webpack-contrib/sass-loader/releases)
- [Changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/sass-loader/compare/v10.1.1...v11.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-09 04:22:04 +00:00
dependabot-preview[bot]
a755fdaa4e Bump electron-rebuild from 2.3.4 to 2.3.5
Bumps [electron-rebuild](https://github.com/electron/electron-rebuild) from 2.3.4 to 2.3.5.
- [Release notes](https://github.com/electron/electron-rebuild/releases)
- [Changelog](https://github.com/electron/electron-rebuild/blob/master/.releaserc.json)
- [Commits](https://github.com/electron/electron-rebuild/compare/v2.3.4...v2.3.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-08 04:25:07 +00:00
Eugene
1149d68d1c Merge pull request #3243 from Eugeny/dependabot/npm_and_yarn/https-proxy-agent-2.2.4
[Security] Bump https-proxy-agent from 2.0.0 to 2.2.4
2021-02-07 16:33:41 +01:00
Eugene
1d92a3f89d Merge pull request #3242 from Eugeny/dependabot/npm_and_yarn/tar-2.2.2
[Security] Bump tar from 2.2.1 to 2.2.2
2021-02-07 16:33:25 +01:00
Eugene
3557345d70 Merge pull request #3222 from Eugeny/dependabot/npm_and_yarn/terminus-plugin-manager/axios-0.21.1
[Security] Bump axios from 0.19.2 to 0.21.1 in /terminus-plugin-manager
2021-02-07 16:33:06 +01:00
Eugene
86ebdd92b4 Merge pull request #3221 from Eugeny/dependabot/npm_and_yarn/terminus-core/axios-0.21.1
[Security] Bump axios from 0.19.2 to 0.21.1 in /terminus-core
2021-02-07 16:32:59 +01:00
Eugene
4764ec8249 Merge pull request #3239 from Eugeny/dependabot/npm_and_yarn/tough-cookie-2.3.4
[Security] Bump tough-cookie from 2.3.2 to 2.3.4
2021-02-07 16:32:49 +01:00
Eugene Pankov
b1752bd0b4 updated cwd settings UI 2021-02-07 13:44:17 +01:00
Eugene Pankov
1e697a952a upgraded xterm.js 2021-02-07 13:44:08 +01:00
Eugene Pankov
6bad2a2167 cache dscl output 2021-02-07 13:43:58 +01:00
Eugene Pankov
61a46e3b4a lint 2021-02-07 13:15:24 +01:00
Eugene Pankov
cba90cec0a better error messages for X11 forwarding issues 2021-02-07 12:49:34 +01:00
Eugene Pankov
7583d92747 set terminus to use built-in graphics by default - fixes #657 2021-02-07 12:49:22 +01:00
Eugene Pankov
e2b99d71ad lint 2021-02-06 17:47:17 +01:00
dependabot-preview[bot]
c829daac41 [Security] Bump tar from 2.2.1 to 2.2.2
Bumps [tar](https://github.com/npm/node-tar) from 2.2.1 to 2.2.2. **This update includes a security fix.**
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/master/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v2.2.1...v2.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-06 15:47:12 +00:00
Eugene Pankov
aac38fa190 CWD detection on windows where possible 2021-02-06 16:45:38 +01:00
Eugene Pankov
7098622c8f bumped electron 2021-02-06 11:20:34 +01:00
Eugene Pankov
8695003c74 lint 2021-02-01 11:40:49 +01:00
Eugene Pankov
43a27a7b7c serial newline modes 2021-01-31 20:07:26 +01:00
Eugene Pankov
dd2d2ce20d Update tsconfig.json 2021-01-31 19:33:33 +01:00
Eugene Pankov
73574374f0 readline input mode for serial terminals - #3099, #2661 2021-01-31 19:33:30 +01:00
Eugene Pankov
5bd1bfd565 better editor ts support 2021-01-31 18:20:58 +01:00
Eugene Pankov
0611afa8b5 better session handlers behaviour, added serial auto-reconnection logic - #3099 2021-01-31 18:20:39 +01:00
Eugene Pankov
91c9e8affd bumped angular 2021-01-28 22:01:42 +01:00
Eugene Pankov
322ffc5847 margin fix 2021-01-28 21:55:29 +01:00
Eugene Pankov
21084b5d24 bumped js-yaml 2021-01-28 21:52:11 +01:00
dependabot-preview[bot]
4c840a0db1 [Security] Bump https-proxy-agent from 2.0.0 to 2.2.4
Bumps [https-proxy-agent](https://github.com/TooTallNate/node-https-proxy-agent) from 2.0.0 to 2.2.4. **This update includes security fixes.**
- [Release notes](https://github.com/TooTallNate/node-https-proxy-agent/releases)
- [Commits](https://github.com/TooTallNate/node-https-proxy-agent/compare/2.0.0...2.2.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-28 20:48:14 +00:00
dependabot-preview[bot]
3b69172f62 Bump uuid from 8.2.0 to 8.3.2 in /terminus-core
Bumps [uuid](https://github.com/uuidjs/uuid) from 8.2.0 to 8.3.2.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v8.2.0...v8.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-28 20:48:05 +00:00
Eugene Pankov
e0efb4073a bumped eslint 2021-01-28 21:46:31 +01:00
Eugene Pankov
c42b62afe6 bumped deps 2021-01-28 21:11:53 +01:00
Eugene Pankov
e2b11c83d5 fixed cli args handling 2021-01-28 21:11:47 +01:00
Eugene Pankov
891fa5770a Update electron-builder.yml 2021-01-28 18:45:09 +01:00
Eugene Pankov
6b395cc2b3 fixed windows native module import 2021-01-28 18:20:45 +01:00
Eugene Pankov
448a1a094f fixed macOS native module builds 2021-01-27 00:26:48 +01:00
Eugene Pankov
788dd61a13 exclude native modules from app.asar and sign them 2021-01-26 15:29:18 +01:00
Eugene Pankov
467684d9ab Update api.ts 2021-01-25 21:35:00 +01:00
Eugene Pankov
5069070040 added a 'copy current path' hotkey and context menu item - fixes #2586 2021-01-25 17:30:44 +01:00
Eugene Pankov
ecf5297bc3 Merge branch 'master' of github.com:Eugeny/terminus 2021-01-24 19:27:42 +01:00
Eugene Pankov
78bd90ac55 fixed window re-focusing on linux 2021-01-24 19:27:36 +01:00
Eugene Pankov
712589eb93 fixed #1510 2021-01-24 19:06:51 +01:00
Eugene Pankov
f103e71285 better handling of CLI args - fixes #1436 2021-01-24 19:06:41 +01:00
Eugene Pankov
0cf883cc4a bumped electron 2021-01-24 13:58:47 +01:00
Eugene Pankov
2b0ad0d558 ssh: 15s default keepalive interval 2021-01-24 13:33:54 +01:00
Eugene Pankov
67bacb9dd3 ssh: better session close and reconnect behaviours - fixes #3351, fixes #3010, fixes #3276, fixes #3074, fixes #2825, fixes #3285 2021-01-24 13:28:59 +01:00
Eugene Pankov
d0a597634d ssh: fixed clearing jump host in connection settings 2021-01-24 13:08:07 +01:00
Eugene Pankov
322014c409 Merge branch 'master' of github.com:Eugeny/terminus 2021-01-24 12:43:02 +01:00
Eugene Pankov
c751a8725b rollback node-pty to pre-napi state 2021-01-24 12:42:59 +01:00
Eugene Pankov
5417efe558 ssh: blacklist broken kex algorithms 2021-01-24 11:26:43 +01:00
Eugene
bf356fcd19 Merge pull request #3362 from mi544/readme-fix
Removes unnecessary asterisks from README
2021-01-22 09:37:05 +01:00
Maksim Verkhoturov
10ee66b9dd removes unnecessary asterisks 2021-01-21 15:45:37 -07:00
dependabot-preview[bot]
6545a2fda6 Bump run-script-os from 1.1.3 to 1.1.5 in /terminus-ssh
Bumps [run-script-os](https://github.com/charlesguse/run-script-os) from 1.1.3 to 1.1.5.
- [Release notes](https://github.com/charlesguse/run-script-os/releases)
- [Commits](https://github.com/charlesguse/run-script-os/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-18 04:31:15 +00:00
Eugene
763da0d80c Merge pull request #3310 from Eugeny/dependabot/npm_and_yarn/app/npm-6.14.11
Bump npm from 6.14.10 to 6.14.11 in /app
2021-01-15 15:12:16 +01:00
Eugene
8d46bb2181 Merge pull request #3290 from Eugeny/dependabot/npm_and_yarn/terminus-core/core-js-3.8.2
Bump core-js from 3.7.0 to 3.8.2 in /terminus-core
2021-01-15 15:12:05 +01:00
Eugene Pankov
fe936c7726 fixed #3333 - duplicate color schemes 2021-01-14 09:48:58 +01:00
Eugene Pankov
2f3e32990a Update macos.yml 2021-01-13 13:52:23 +01:00
Eugene Pankov
22344f8d54 Update macos.yml 2021-01-13 10:50:34 +01:00
Eugene Pankov
f6d37a39f4 Update macos.yml 2021-01-12 18:20:17 +01:00
dependabot-preview[bot]
0e4c60ad4b Bump npm from 6.14.10 to 6.14.11 in /app
Bumps [npm](https://github.com/npm/cli) from 6.14.10 to 6.14.11.
- [Release notes](https://github.com/npm/cli/releases)
- [Changelog](https://github.com/npm/cli/blob/v6.14.11/CHANGELOG.md)
- [Commits](https://github.com/npm/cli/compare/v6.14.10...v6.14.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-12 17:01:34 +00:00
dependabot-preview[bot]
e8c2171d8f Bump core-js from 3.7.0 to 3.8.2 in /terminus-core
Bumps [core-js](https://github.com/zloirock/core-js) from 3.7.0 to 3.8.2.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/compare/v3.7.0...v3.8.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-12 17:01:01 +00:00
Eugene Pankov
f7a5be2c67 downgraded electron 2021-01-12 17:59:13 +01:00
dependabot-preview[bot]
ceb638e08d [Security] Bump tough-cookie from 2.3.2 to 2.3.4
Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 2.3.2 to 2.3.4. **This update includes security fixes.**
- [Release notes](https://github.com/salesforce/tough-cookie/releases)
- [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md)
- [Commits](https://github.com/salesforce/tough-cookie/compare/v2.3.2...v2.3.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-02 09:43:15 +00:00
dependabot-preview[bot]
040098050d Bump axios from 0.19.2 to 0.21.1 in /terminus-plugin-manager
Bumps [axios](https://github.com/axios/axios) from 0.19.2 to 0.21.1.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v0.21.1/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.19.2...v0.21.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-02 09:43:10 +00:00
dependabot-preview[bot]
00de7c148f Bump axios from 0.19.2 to 0.21.1 in /terminus-core
Bumps [axios](https://github.com/axios/axios) from 0.19.2 to 0.21.1.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v0.21.1/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.19.2...v0.21.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-02 09:43:06 +00:00
114 changed files with 2805 additions and 1996 deletions

View File

@@ -343,6 +343,33 @@
"contributions": [ "contributions": [
"code" "code"
] ]
},
{
"login": "VectorKappa",
"name": "Piotr Patalong",
"avatar_url": "https://avatars.githubusercontent.com/u/29167842?v=4",
"profile": "http://patalong.pl",
"contributions": [
"design"
]
},
{
"login": "clarkwang",
"name": "Clark Wang",
"avatar_url": "https://avatars.githubusercontent.com/u/157076?v=4",
"profile": "https://github.com/clarkwang",
"contributions": [
"code"
]
},
{
"login": "iamchating",
"name": "iamchating",
"avatar_url": "https://avatars.githubusercontent.com/u/7088153?v=4",
"profile": "https://github.com/iamchating",
"contributions": [
"code"
]
} }
], ],
"contributorsPerLine": 7, "contributorsPerLine": 7,

View File

@@ -1,6 +1,8 @@
parser: '@typescript-eslint/parser' parser: '@typescript-eslint/parser'
parserOptions: parserOptions:
project: tsconfig.json project:
- tsconfig.json
- '*/tsconfig.typings.json'
extends: extends:
- 'plugin:@typescript-eslint/all' - 'plugin:@typescript-eslint/all'
plugins: plugins:
@@ -37,6 +39,7 @@ rules:
'@typescript-eslint/no-misused-promises': off '@typescript-eslint/no-misused-promises': off
'@typescript-eslint/typedef': off '@typescript-eslint/typedef': off
'@typescript-eslint/consistent-type-imports': off '@typescript-eslint/consistent-type-imports': off
'@typescript-eslint/sort-type-union-intersection-members': off
'@typescript-eslint/no-use-before-define': '@typescript-eslint/no-use-before-define':
- error - error
- classes: false - classes: false
@@ -81,7 +84,8 @@ rules:
argsIgnorePattern: ^_ argsIgnorePattern: ^_
no-undef: error no-undef: error
no-var: error no-var: error
object-curly-spacing: object-curly-spacing: off
'@typescript-eslint/object-curly-spacing':
- error - error
- always - always
quote-props: quote-props:

View File

@@ -23,6 +23,7 @@ jobs:
cd .. cd ..
rm app/node_modules/.yarn-integrity rm app/node_modules/.yarn-integrity
yarn yarn
yarn run build:typings
yarn run docs yarn run docs
rsync -e "ssh -o StrictHostKeyChecking=no" -arv docs/api/ root@ajenti.org:/srv/terminus-docs/ rsync -e "ssh -o StrictHostKeyChecking=no" -arv docs/api/ root@ajenti.org:/srv/terminus-docs/

View File

@@ -21,6 +21,10 @@ jobs:
cd .. cd ..
rm app/node_modules/.yarn-integrity rm app/node_modules/.yarn-integrity
yarn yarn
./node_modules/.bin/patch-package
cd app
../node_modules/.bin/patch-package
cd ..
- name: Build native deps - name: Build native deps
run: scripts/build-native.js run: scripts/build-native.js

View File

@@ -26,6 +26,10 @@ jobs:
cd .. cd ..
rm app/node_modules/.yarn-integrity rm app/node_modules/.yarn-integrity
yarn yarn
./node_modules/.bin/patch-package
cd app
../node_modules/.bin/patch-package
cd ..
- name: Build native deps - name: Build native deps
run: scripts/build-native.js run: scripts/build-native.js

View File

@@ -10,27 +10,25 @@ First, install the dependencies:
``` ```
# macOS/Linux: # macOS/Linux:
npm install yarn
./scripts/install-deps.js
./scripts/build-native.js ./scripts/build-native.js
# Windows: # Windows:
npm -g install windows-build-tools npm -g install windows-build-tools
npm install yarn
node scripts\install-deps.js
node scripts\build-native.js node scripts\build-native.js
``` ```
Now, check if your build is working: Now, check if your build is working:
``` ```
npm run build yarn run build
``` ```
Start Terminus with Start Terminus with
``` ```
npm start yarn start
``` ```
# Project layout # Project layout

View File

@@ -1,4 +1,4 @@
****![](https://github.com/Eugeny/terminus/raw/master/docs/readme.png) ![](https://github.com/Eugeny/terminus/raw/master/docs/readme.png)
<p align="center"> <p align="center">
@@ -121,6 +121,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<tr> <tr>
<td align="center"><a href="https://github.com/TakuroOnoda"><img src="https://avatars0.githubusercontent.com/u/1407926?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Takuro Onoda</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=TakuroOnoda" title="Code">💻</a></td> <td align="center"><a href="https://github.com/TakuroOnoda"><img src="https://avatars0.githubusercontent.com/u/1407926?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Takuro Onoda</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=TakuroOnoda" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/frauhottelmann"><img src="https://avatars2.githubusercontent.com/u/902705?v=4?s=100" width="100px;" alt=""/><br /><sub><b>frauhottelmann</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=frauhottelmann" title="Code">💻</a></td> <td align="center"><a href="https://github.com/frauhottelmann"><img src="https://avatars2.githubusercontent.com/u/902705?v=4?s=100" width="100px;" alt=""/><br /><sub><b>frauhottelmann</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=frauhottelmann" title="Code">💻</a></td>
<td align="center"><a href="http://patalong.pl"><img src="https://avatars.githubusercontent.com/u/29167842?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Piotr Patalong</b></sub></a><br /><a href="#design-VectorKappa" title="Design">🎨</a></td>
<td align="center"><a href="https://github.com/clarkwang"><img src="https://avatars.githubusercontent.com/u/157076?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Clark Wang</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=clarkwang" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/iamchating"><img src="https://avatars.githubusercontent.com/u/7088153?v=4?s=100" width="100px;" alt=""/><br /><sub><b>iamchating</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=iamchating" title="Code">💻</a></td>
</tr> </tr>
</table> </table>

View File

@@ -75,7 +75,7 @@ export class Application {
} }
onGlobalHotkey (): void { onGlobalHotkey (): void {
if (this.windows.some(x => x.isFocused())) { if (this.windows.some(x => x.isFocused() && x.isVisible())) {
for (const window of this.windows) { for (const window of this.windows) {
window.hide() window.hide()
} }
@@ -147,7 +147,7 @@ export class Application {
handleSecondInstance (argv: string[], cwd: string): void { handleSecondInstance (argv: string[], cwd: string): void {
this.presentAllWindows() this.presentAllWindows()
this.windows[this.windows.length - 1].handleSecondInstance(argv, cwd) this.windows[this.windows.length - 1].passCliArguments(argv, cwd, true)
} }
private setupMenu () { private setupMenu () {

View File

@@ -6,7 +6,7 @@ import { app } from 'electron'
export function loadConfig (): any { export function loadConfig (): any {
const configPath = path.join(app.getPath('userData'), 'config.yaml') const configPath = path.join(app.getPath('userData'), 'config.yaml')
if (fs.existsSync(configPath)) { if (fs.existsSync(configPath)) {
return yaml.safeLoad(fs.readFileSync(configPath, 'utf8')) return yaml.load(fs.readFileSync(configPath, 'utf8'))
} else { } else {
return {} return {}
} }

View File

@@ -53,7 +53,7 @@ if (argv.d) {
}) })
} }
app.on('ready', () => { app.on('ready', async () => {
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
app.dock.setMenu(Menu.buildFromTemplate([ app.dock.setMenu(Menu.buildFromTemplate([
{ {
@@ -65,5 +65,8 @@ app.on('ready', () => {
])) ]))
} }
application.init() application.init()
application.newWindow({ hidden: argv.hidden })
const window = await application.newWindow({ hidden: argv.hidden })
await window.ready
window.passCliArguments(process.argv, process.cwd(), false)
}) })

View File

@@ -65,6 +65,7 @@ export class Window {
enableRemoteModule: true, enableRemoteModule: true,
contextIsolation: false, contextIsolation: false,
}, },
maximizable: true,
frame: false, frame: false,
show: false, show: false,
backgroundColor: '#00000000', backgroundColor: '#00000000',
@@ -87,7 +88,7 @@ export class Window {
bwOptions.frame = true bwOptions.frame = true
} else { } else {
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
bwOptions.titleBarStyle = 'hiddenInset' bwOptions.titleBarStyle = 'hidden'
} }
} }
@@ -190,6 +191,10 @@ export class Window {
return this.window.isFocused() return this.window.isFocused()
} }
isVisible (): boolean {
return this.window.isVisible()
}
hide (): void { hide (): void {
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
// Lose focus // Lose focus
@@ -225,8 +230,8 @@ export class Window {
} }
} }
handleSecondInstance (argv: string[], cwd: string): void { passCliArguments (argv: string[], cwd: string, secondInstance: boolean): void {
this.send('host:second-instance', parseArgs(argv, cwd), cwd) this.send('cli', parseArgs(argv, cwd), cwd, secondInstance)
} }
private setupWindowManagement () { private setupWindowManagement () {

View File

@@ -1,6 +1,7 @@
{ {
"name": "terminus", "name": "terminus",
"description": "A terminal for a modern age", "description": "A terminal for a modern age",
"private": true,
"repository": "https://github.com/eugeny/terminus", "repository": "https://github.com/eugeny/terminus",
"author": { "author": {
"name": "Eugene Pankov", "name": "Eugene Pankov",
@@ -13,42 +14,43 @@
"watch": "webpack --progress --color --watch" "watch": "webpack --progress --color --watch"
}, },
"dependencies": { "dependencies": {
"@angular/animations": "^9.1.9", "@angular/animations": "^11.1.1",
"@angular/common": "^9.1.11", "@angular/common": "^11.1.1",
"@angular/compiler": "^9.1.9", "@angular/compiler": "^11.1.1",
"@angular/core": "^9.1.9", "@angular/core": "^11.1.1",
"@angular/forms": "^9.1.11", "@angular/forms": "^11.1.1",
"@angular/platform-browser": "^9.1.9", "@angular/platform-browser": "^11.1.1",
"@angular/platform-browser-dynamic": "^9.1.9", "@angular/platform-browser-dynamic": "^11.1.1",
"@ng-bootstrap/ng-bootstrap": "^6.1.0", "@ng-bootstrap/ng-bootstrap": "^6.1.0",
"@terminus-term/node-pty": "0.10.0-beta11", "@terminus-term/node-pty": "0.10.0-terminus.3",
"electron-config": "2.0.0", "electron-config": "2.0.0",
"electron-debug": "^3.0.1", "electron-debug": "^3.2.0",
"electron-is-dev": "1.1.0", "electron-is-dev": "1.2.0",
"electron-promise-ipc": "^2.2.4", "electron-promise-ipc": "^2.2.4",
"fontmanager-redux": "1.0.0", "fontmanager-redux": "1.0.0",
"glasstron": "0.0.6", "glasstron": "0.0.7",
"js-yaml": "3.14.0", "js-yaml": "4.0.0",
"keytar": "^7.2.0", "keytar": "^7.4.0",
"mz": "^2.7.0", "mz": "^2.7.0",
"ngx-toastr": "^12.0.1", "native-process-working-directory": "^1.0.2",
"ngx-toastr": "^13.2.0",
"npm": "6", "npm": "6",
"path": "0.12.7", "path": "0.12.7",
"rxjs": "^6.5.5", "rxjs": "^6.6.6",
"yargs": "^15.4.1", "yargs": "^15.4.1",
"zone.js": "^0.11.3" "zone.js": "^0.11.4"
}, },
"optionalDependencies": { "optionalDependencies": {
"macos-native-processlist": "^2.0.0", "macos-native-processlist": "^2.0.0",
"serialport": "^9.0.4", "serialport": "^9.0.7",
"windows-blurbehind": "^1.0.1", "windows-blurbehind": "^1.0.1",
"windows-native-registry": "^3.0.0", "windows-native-registry": "^3.0.0",
"windows-process-tree": "^0.2.4" "windows-process-tree": "^0.2.4"
}, },
"devDependencies": { "devDependencies": {
"@types/mz": "0.0.32", "@types/mz": "0.0.32",
"@types/node": "14.14.14", "@types/node": "14.14.31",
"node-abi": "2.19.3", "node-abi": "^2.21.0",
"source-map-support": "^0.5.19" "source-map-support": "^0.5.19"
}, },
"peerDependencies": { "peerDependencies": {
@@ -59,5 +61,8 @@
"terminus-settings": "*", "terminus-settings": "*",
"terminus-ssh": "*", "terminus-ssh": "*",
"terminus-terminal": "*" "terminus-terminal": "*"
},
"resolutions": {
"*/node-abi": "^2.20.0"
} }
} }

View File

@@ -13,7 +13,7 @@ export function getRootModule (plugins: any[]) {
positionClass: 'toast-bottom-center', positionClass: 'toast-bottom-center',
toastClass: 'toast', toastClass: 'toast',
preventDuplicates: true, preventDuplicates: true,
extendedTimeOut: 5000, extendedTimeOut: 1000,
}), }),
] ]
const bootstrap = [ const bootstrap = [

View File

@@ -95,3 +95,12 @@ input[type=range] {
&::-moz-range-track { @include track(); } &::-moz-range-track { @include track(); }
&::-ms-track { @include track(); } &::-ms-track { @include track(); }
} }
a[ngbdropdownitem] {
cursor: pointer;
}
ngb-typeahead-window {
max-height: 60vh;
overflow: auto;
}

View File

@@ -2,14 +2,16 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding: 20px; padding: 20px 0 50px;
.toast { .toast {
box-shadow: 0 1px 0 rgba(0,0,0,.25); box-shadow: 0 1px 0 rgba(0,0,0,.25);
padding: 10px; padding: 7px 12px;
background-image: none; background-image: none;
width: auto; width: auto;
flex-basis: auto; flex-basis: auto;
border-radius: 0.5rem;
font-size: 0.75rem;
&.toast-error { &.toast-error {
background-color: #BD362F; background-color: #BD362F;

View File

@@ -2,40 +2,54 @@
# yarn lockfile v1 # yarn lockfile v1
"@angular/animations@^9.1.9": "@angular/animations@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/animations/-/animations-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-11.2.0.tgz#383438758c61d98f43c5ea1078d8388eb8784387"
integrity sha512-ane1eeQmsP7fcAiLgRhle7YIDgE88WDMMvzqJYhSxwLzXNF/hwqNeskmNcjo8bLt9h/yTIjrCQbycLCHJfU8UQ== integrity sha512-orYrBPNAsF8VpvuOaXTtPltwK2nsje5R8sWJnRC2dh1RCRdyIqHwmRIU0Mi6qLMiEaLNrFPGEMyQ9gB+sC/vYg==
dependencies:
tslib "^2.0.0"
"@angular/common@^9.1.11": "@angular/common@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/common/-/common-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/common/-/common-11.2.0.tgz#90d602c0e33bb95a4d0c4c597f08255d78ed580f"
integrity sha512-QACUhJWlly/nfHUmjopVS1p6ayxxa/NqjyftdCeBJaoyM2YohqWixP/n/keu1K/srJ96aFpUNsZQgmgoRv5SOQ== integrity sha512-wsWI5F6Y2DNxne2D5uk8e9U/vn95UYZLMNBW+QXI9U/I9kDSXoa8yEvNcn1x0XfNXBMst5pi4iSF5M8mIck1eg==
dependencies:
tslib "^2.0.0"
"@angular/compiler@^9.1.9": "@angular/compiler@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/compiler/-/compiler-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-11.2.0.tgz#130bee57dd1daa1326d37bef4b63c02aa7309cc2"
integrity sha512-9MLB1Xx7odKuxDoybVwiOB1ZEUZpL8FurYm4RVuW39ntsUt0IMC9Hb8UagZLTAWhaWSHydkD/KBQVVobGqd0lA== integrity sha512-EW6LM/kUYhQkuFqGt03c/eRKZAYr0LLEdMOn//j1uIh+wSq9KLffBGpky6b63xdfWxsXi8OucXUOydTQBckNEQ==
dependencies:
tslib "^2.0.0"
"@angular/core@^9.1.9": "@angular/core@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/core/-/core-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/core/-/core-11.2.0.tgz#309ae61d55b21fca0b644a6571109741d64b2467"
integrity sha512-mBm24Q9GjkAsxMAzqQ86U1078+yTEpr0+syMEruUtJ0HUH6Fzn3J+6xTLb+BVcGb9RkCkFaV9T5mcn6ZM0f++g== integrity sha512-jnbnJTW2GwfkRoXG8J4zs5FMcahMZwo6jrZGe9FiXjCYG9cLEuOXy4h99Z1s/o0vc/VXyWgym7SmeEgv+urf8g==
dependencies:
tslib "^2.0.0"
"@angular/forms@^9.1.11": "@angular/forms@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/forms/-/forms-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-11.2.0.tgz#8ba7a98efdd464a4a6b901ba1f220162dd80c1ed"
integrity sha512-soGVZmPq2bzkxvtTyeJB8p3ejzm4xxt+43hJw6Ag8NxpwUFPVa30oJge3JV+u8Y4yBtl5SbOZ4bBX3EkMxLcGQ== integrity sha512-FgIG9ou27FbmyFv0n6pF95cQEz412/+iyY9OSlDnezD/7yU4fwk4NNPgP6Z/b1k7ClLYxP/YKC00WVhi1i8HdA==
dependencies:
tslib "^2.0.0"
"@angular/platform-browser-dynamic@^9.1.9": "@angular/platform-browser-dynamic@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-11.2.0.tgz#647fe6d8dfa7651d38564240cbf75f97f11754b7"
integrity sha512-jCeHyAZ4Nap1/FOqAlKEg9UxQaSkHrxnQr6hYtWwC4ZDVUn3zLWQf6J+mbeYNOXN5yQxEiIqqhORYeOCLLqf1w== integrity sha512-bBCtgtL87mvDT0K3HNBS19UC0BzIJUTGnYKJS9IugyfTEqlldB4juMmh/3FPjk30kxxJ8IB/ydaN2uVhBAxPVQ==
dependencies:
tslib "^2.0.0"
"@angular/platform-browser@^9.1.9": "@angular/platform-browser@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-11.2.0.tgz#d1bbafd394ebfb600043060ec2d8543763041403"
integrity sha512-F3iTz1zNbtrs7KFKUxbj8qmTsd/fiuTNcpBExjE5TtatRiE6J8vNvN1+Z/1FgPe0UXBSdTzSwZ8/RxWKw20RMw== integrity sha512-xd3O4svQ95BN/KpzQUFkSWfvwiCURuLJhLlDkxzLA58ElA0qodHOjQmQz/1vRFh/nXQQoWg8z9ixbmcRGzWTow==
dependencies:
tslib "^2.0.0"
"@iarna/cli@^1.2.0": "@iarna/cli@^1.2.0":
version "1.2.0" version "1.2.0"
@@ -51,78 +65,83 @@
resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-6.2.0.tgz#0506d612ca6002bd8fa398d006fa2641013e11d4" resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-6.2.0.tgz#0506d612ca6002bd8fa398d006fa2641013e11d4"
integrity sha512-wqwhnJFyEwvzWQJjXrEt+7oBTSvu2qPbdYvUFYhDVzOJLWB5M7YEhDAkMrfHQJ0pZNBMGr580FqYue+XiURY0Q== integrity sha512-wqwhnJFyEwvzWQJjXrEt+7oBTSvu2qPbdYvUFYhDVzOJLWB5M7YEhDAkMrfHQJ0pZNBMGr580FqYue+XiURY0Q==
"@serialport/binding-abstract@^9.0.2": "@serialport/binding-abstract@^9.0.7":
version "9.0.2" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/binding-abstract/-/binding-abstract-9.0.2.tgz" resolved "https://registry.yarnpkg.com/@serialport/binding-abstract/-/binding-abstract-9.0.7.tgz#d2c7ecea0f100bdf20187bfc0d34ba90f5504e1e"
integrity sha512-kyMX6usn+VLpidt0YsDq5JwztIan9TPCX6skr0XcalOxI8I7w+/2qVZJzjgo2fSqDnPRcU2jMWTytwzEXFODvQ== integrity sha512-g1ncCMIG9rMsxo/28ObYmXZcHThlvtZygsCANmyMUuFS7SwXY4+PhcEnt2+ZcMkEDNRiOklT+ngtIVx5GGpt/A==
dependencies: dependencies:
debug "^4.1.1" debug "^4.3.1"
"@serialport/binding-mock@^9.0.2": "@serialport/binding-mock@^9.0.7":
version "9.0.2" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-9.0.2.tgz" resolved "https://registry.yarnpkg.com/@serialport/binding-mock/-/binding-mock-9.0.7.tgz#2fda427adc113320461f33f7426dfca73e8ad1de"
integrity sha512-HfrvJ/LXULHk8w63CGxwDNiDidFgDX8BnadY+cgVS6yHMHikbhLCLjCmUKsKBWaGKRqOznl0w+iUl7TMi1lkXQ== integrity sha512-aR8H+htZwwZZkVb1MdbnNvGWw8eXVRqQ2qPhkbKyx0N/LY5aVIgCgT98Kt1YylLsG7SzNG+Jbhd4wzwEuPVT5Q==
dependencies: dependencies:
"@serialport/binding-abstract" "^9.0.2" "@serialport/binding-abstract" "^9.0.7"
debug "^4.1.1" debug "^4.3.1"
"@serialport/bindings@^9.0.4": "@serialport/bindings@^9.0.7":
version "9.0.4" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/bindings/-/bindings-9.0.4.tgz" resolved "https://registry.yarnpkg.com/@serialport/bindings/-/bindings-9.0.7.tgz#8f53fb56eb866d5a1021a19ced1ddc20a60916d7"
integrity sha512-6dlE1vm5c1xk667f1Zm7D+msbHJ9jdnUr9l8DResKpj2iCBzbCNsW+yCYq26WxzXWc1L2HUaS3/aL+k0wm5amg== integrity sha512-cNWaxnEbbpLoSJ6GMb0ZeCpaciczm8XRE4jgBqe/BflWZb+wyiTYIocbsySxpS40WT3kJ0sNTFag77uSmQ6ftg==
dependencies: dependencies:
"@serialport/binding-abstract" "^9.0.2" "@serialport/binding-abstract" "^9.0.7"
"@serialport/parser-readline" "^9.0.1" "@serialport/parser-readline" "^9.0.7"
bindings "^1.5.0" bindings "^1.5.0"
debug "^4.3.1" debug "^4.3.1"
nan "^2.14.2" nan "^2.14.2"
prebuild-install "^6.0.0" prebuild-install "^6.0.1"
"@serialport/parser-byte-length@^9.0.1": "@serialport/parser-byte-length@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-byte-length/-/parser-byte-length-9.0.7.tgz#9e362bba70eeffcd2eb0804afeca4bb1dee59d5f"
integrity sha512-1Ikv4lgCNw8OMf35yCpgzjHwkpgBEkhBuXFXIdWZk+ixaHFLlAtp03QxGPZBmzHMK58WDmEQoBHC1V5BkkAKSQ== integrity sha512-evf7oOOSBMBn2AZZbgBFMRIyEzlsyQkhqaPm7IBCPTxMDXRf4tKkFYJHYZB0/6d1W4eI0meH079UqmSsh/uoDA==
"@serialport/parser-cctalk@^9.0.1": "@serialport/parser-cctalk@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-cctalk/-/parser-cctalk-9.0.7.tgz#fa0e1539f067aced22a5ef7d64fdac14f1a6a4d3"
integrity sha512-GtMda2DeJ+23bNqOc79JYV06dax2n3FLLFM3zA7nfReCOi98QbuDj4TUbFESMOnp4DB0oMO0GYHCR9gHOedTkg== integrity sha512-ert5jhMkeiTfr44TkbdySC09J8UwAsf/RxBucVN5Mz5enG509RggnkfFi4mfj3UCG2vZ7qsmM6gtZ62DshY02Q==
"@serialport/parser-delimiter@^9.0.1": "@serialport/parser-delimiter@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-delimiter/-/parser-delimiter-9.0.7.tgz#7bef2447d4282dd00dc659719b310edeb30ff294"
integrity sha512-+oaSl5zEu47OlrRiF5p5tn2qgGqYuhVcE+NI+Pv4E1xsNB/A0fFxxMv/8XUw466CRLEJ5IESIB9qbFvKE6ltaQ== integrity sha512-Vb2NPeXPZ/28M4m5x4OAHFd8jRAeddNCgvL+Q+H/hqFPY1w47JcMLchC7pigRW8Cnt1fklmzfwdNQ8Fb+kMkxQ==
"@serialport/parser-readline@^9.0.1": "@serialport/parser-inter-byte-timeout@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-9.0.7.tgz#55b315b49d8ad37f981ba69bb9443f25c96aec17"
integrity sha512-38058gxvyfgdeLpg3aUyD98NuWkVB9yyTLpcSdeQ3GYiupivwH6Tdy/SKPmxlHIw3Ml2qil5MR2mtW2fLPB5CQ== integrity sha512-lUZ3cwgUluBvJ1jf+0LQsqoiPYAokDO6+fRCw9HCfnrF/OS60Gm4rxuyo2uQIueqZkJ7NIFP+ibKsULrA47AEA==
"@serialport/parser-readline@^9.0.7":
version "9.0.7"
resolved "https://registry.yarnpkg.com/@serialport/parser-readline/-/parser-readline-9.0.7.tgz#8b096028170fb2644bcf0f997d534a344cfd00e6"
integrity sha512-ydoLbgVQQPxWrwbe3Fhh4XnZexbkEQAC6M/qgRTzjnKvTjrD61CJNxLc3vyDaAPI9bJIhTiI7eTX3JB5jJv8Hg==
dependencies: dependencies:
"@serialport/parser-delimiter" "^9.0.1" "@serialport/parser-delimiter" "^9.0.7"
"@serialport/parser-ready@^9.0.1": "@serialport/parser-ready@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-ready/-/parser-ready-9.0.7.tgz#d9eb9801c6003fdb1450c557f3e256a188a9f3be"
integrity sha512-lgzGkVJaaV1rJVx26WwI2UKyPxc0vu1rsOeldzA3VVbF+ABrblUQA06+cRPpT6k96GY+X4+1fB1rWuPpt8HbgQ== integrity sha512-3qYhI4cNUPAYqVYvdwV57Y+PVRl4dJf1fPBtMoWtwDgwopsAXTR93WCs49WuUq9JCyNW+8Hrfqv8x8eNAD5Dqg==
"@serialport/parser-regex@^9.0.1": "@serialport/parser-regex@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-regex/-/parser-regex-9.0.7.tgz#d8a02e3a169faa2f6604e8293832cc676b865f48"
integrity sha512-BHTV+Lkl+J8hSecFtDRENaR4fgA6tw44J+dmA1vEKEyum0iDN4bihbu8yvztYyo4PhBGUKDfm/PnD5EkJm0dPA== integrity sha512-5XF+FXbhqQ/5bVKM4NaGs1m+E9KjfmeCx/obwsKaUZognQF67jwoTfjJJWNP/21jKfxdl8XoCYjZjASl3XKRAw==
"@serialport/stream@^9.0.2": "@serialport/stream@^9.0.7":
version "9.0.2" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/stream/-/stream-9.0.2.tgz" resolved "https://registry.yarnpkg.com/@serialport/stream/-/stream-9.0.7.tgz#0bf023eb0233a714fcc5a86de09e381e466d9882"
integrity sha512-0RkVe+gvwZu/PPfbb7ExQ+euGoCTGKD/B8TQ5fuhe+eKk1sh73RwjKmu9gp6veSNqx9Zljnh1dF6mhdEKWZpSA== integrity sha512-c/h7HPAeFiryD9iTGlaSvPqHFHSZ0NMQHxC4rcmKS2Vu3qJuEtkBdTLABwsMp7iWEiSnI4KC3s7bHapaXP06FQ==
dependencies: dependencies:
debug "^4.1.1" debug "^4.3.1"
"@terminus-term/node-pty@0.10.0-beta11": "@terminus-term/node-pty@0.10.0-terminus.3":
version "0.10.0-beta11" version "0.10.0-terminus.3"
resolved "https://registry.yarnpkg.com/@terminus-term/node-pty/-/node-pty-0.10.0-beta11.tgz#9e83041bc0644f17a4329c41a13d09575653c544" resolved "https://registry.yarnpkg.com/@terminus-term/node-pty/-/node-pty-0.10.0-terminus.3.tgz#9dbd64d52afda5079e66265a89d313fe42affab7"
integrity sha512-ZrplD84UNV8qpCNpsG8DAo8fmoRP1Ynb9QsApIleCJjbeNvUP2ZAeR6wo0aV9B7Zqjvq5O4hoUSayIDGtORH+A== integrity sha512-HvIOts22dnoBXhRfLiK9DyPasuixYVgEUvgqZmOr0B0Ki9tF8e074oYPUtzLRll6Y553QiUzTWhriCS99MChNQ==
dependencies: dependencies:
node-addon-api "^3.0.2" nan "^2.14.0"
"@types/mz@0.0.32": "@types/mz@0.0.32":
version "0.0.32" version "0.0.32"
@@ -131,10 +150,10 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/node@*", "@types/node@14.14.14": "@types/node@*", "@types/node@14.14.31":
version "14.14.14" version "14.14.31"
resolved "https://registry.npmjs.org/@types/node/-/node-14.14.14.tgz" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
integrity sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ== integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
JSONStream@^1.3.4, JSONStream@^1.3.5: JSONStream@^1.3.4, JSONStream@^1.3.5:
version "1.3.5" version "1.3.5"
@@ -259,12 +278,10 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0" delegates "^1.0.0"
readable-stream "^2.0.6" readable-stream "^2.0.6"
argparse@^1.0.7: argparse@^2.0.1:
version "1.0.10" version "2.0.1"
resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
dependencies:
sprintf-js "~1.0.2"
asap@^2.0.0: asap@^2.0.0:
version "2.0.6" version "2.0.6"
@@ -709,7 +726,7 @@ debug@^3.1.0:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: debug@^4.0.1, debug@^4.3.1:
version "4.3.1" version "4.3.1"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz" resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
@@ -837,10 +854,10 @@ electron-config@2.0.0:
dependencies: dependencies:
conf "^1.0.0" conf "^1.0.0"
electron-debug@^3.0.1: electron-debug@^3.2.0:
version "3.1.0" version "3.2.0"
resolved "https://registry.npmjs.org/electron-debug/-/electron-debug-3.1.0.tgz" resolved "https://registry.yarnpkg.com/electron-debug/-/electron-debug-3.2.0.tgz#46a15b555c3b11872218c65ea01d058aa0814920"
integrity sha512-SWEqLj4MgfV3tGuO5eBLQ5/Nr6M+KPxsnE0bUJZvQebGJus6RAcdmvd7L+l0Ji31h2mmrN23l2tHFtCa2FvurA== integrity sha512-7xZh+LfUvJ52M9rn6N+tPuDw6oRAjxUj9SoxAZfJ0hVCXhZCsdkrSt7TgXOiWiEOBgEV8qwUIO/ScxllsPS7ow==
dependencies: dependencies:
electron-is-dev "^1.1.0" electron-is-dev "^1.1.0"
electron-localshortcut "^3.1.0" electron-localshortcut "^3.1.0"
@@ -850,7 +867,12 @@ electron-is-accelerator@^0.1.0:
resolved "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz" resolved "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz"
integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns= integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=
electron-is-dev@1.1.0, electron-is-dev@^1.1.0: electron-is-dev@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-1.2.0.tgz#2e5cea0a1b3ccf1c86f577cee77363ef55deb05e"
integrity sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==
electron-is-dev@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.1.0.tgz" resolved "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.1.0.tgz"
integrity sha512-Z1qA/1oHNowGtSBIcWk0pcLEqYT/j+13xUw/MYOrBUOL4X7VN0i0KCTf5SqyvMPmW5pSPKbo28wkxMxzZ20YnQ== integrity sha512-Z1qA/1oHNowGtSBIcWk0pcLEqYT/j+13xUw/MYOrBUOL4X7VN0i0KCTf5SqyvMPmW5pSPKbo28wkxMxzZ20YnQ==
@@ -972,11 +994,6 @@ escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
execa@^0.7.0: execa@^0.7.0:
version "0.7.0" version "0.7.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
@@ -1217,10 +1234,10 @@ github-from-package@0.0.0:
resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz" resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz"
integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=
glasstron@0.0.6: glasstron@0.0.7:
version "0.0.6" version "0.0.7"
resolved "https://registry.yarnpkg.com/glasstron/-/glasstron-0.0.6.tgz#1438899cd49a1cda1999290be2165310b759fd62" resolved "https://registry.yarnpkg.com/glasstron/-/glasstron-0.0.7.tgz#d0f3e8344351bbcb89a39323282b4ddb06b03ba0"
integrity sha512-WBE1zH3ZcYhLlfKATfKzuN05Anno2WYlVfImWteU5RM+gqdFLHGIxxM3VR16JvFF5oIYah01MBGQ2+3xTq44iQ== integrity sha512-zeqfC0E153yBKWHB8ZBA5rT1o1dCCQcPECBryzWLX3uy6VTX3CUcy7kjk/4BlVztEIbpV2plEetpOxSAOe5cqw==
dependencies: dependencies:
node-addon-api "^3.0.0" node-addon-api "^3.0.0"
x11 "^2.3.0" x11 "^2.3.0"
@@ -1405,7 +1422,7 @@ inherits@2.0.3:
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: ini@^1.3.4, ini@^1.3.5, ini@^1.3.8, ini@~1.3.0:
version "1.3.8" version "1.3.8"
resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
@@ -1581,13 +1598,12 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
js-yaml@3.14.0: js-yaml@4.0.0:
version "3.14.0" version "4.0.0"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f"
integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==
dependencies: dependencies:
argparse "^1.0.7" argparse "^2.0.1"
esprima "^4.0.0"
jsbn@~0.1.0: jsbn@~0.1.0:
version "0.1.1" version "0.1.1"
@@ -1644,10 +1660,10 @@ keyboardevents-areequal@^0.2.1:
resolved "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz" resolved "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz"
integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw== integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==
keytar@^7.2.0: keytar@^7.4.0:
version "7.3.0" version "7.4.0"
resolved "https://registry.npmjs.org/keytar/-/keytar-7.3.0.tgz" resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.4.0.tgz#0a508d64850ca05aa3ba4127818037d13ca3219f"
integrity sha512-t8YD0ETO5AeRxCaaN4N/hzj3JusIH0ugjVooE724+ozaVG9+l16Mau62T+U8tEhCv7SozY/g69BWF1U+o47qJg== integrity sha512-nELmc35YjSE4ZNSFaID/743CgDt/MdV4JLX7rRewAh9mKvU72RtF3uJMY0MdMpwdDYZhmD8FSdRCD1J97lEyVg==
dependencies: dependencies:
node-addon-api "^3.0.0" node-addon-api "^3.0.0"
prebuild-install "^6.0.0" prebuild-install "^6.0.0"
@@ -2073,7 +2089,7 @@ mz@^2.7.0:
object-assign "^4.0.1" object-assign "^4.0.1"
thenify-all "^1.0.0" thenify-all "^1.0.0"
nan@^2.13.2, nan@^2.14.2: nan@^2.13.2, nan@^2.14.0, nan@^2.14.2:
version "2.14.2" version "2.14.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
@@ -2083,17 +2099,24 @@ napi-build-utils@^1.0.1:
resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz" resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz"
integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
ngx-toastr@^12.0.1: native-process-working-directory@^1.0.2:
version "12.1.0" version "1.0.2"
resolved "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-12.1.0.tgz" resolved "https://registry.yarnpkg.com/native-process-working-directory/-/native-process-working-directory-1.0.2.tgz#7843e2fa1490f53cf8d2c7d1913de8b275e8b89a"
integrity sha512-rytCRBhvuudj614Kfj9GoIVQDrFuLvHSMP1YrMwTmR1SNkNJZOpGKmaSDCCBrNDkSrGouzMWBlFbl1UDBBsiqw== integrity sha512-3a67QQV8r3YMUTSOgvtMOCjPDgCpb/8xjv93L8Cqb8bv3hOKsWis4/+8HCu3bgj8ADQV75SCYFSsAGM5G0cXmQ==
dependencies: dependencies:
tslib "^1.10.0" node-addon-api "^3.1.0"
node-abi@2.19.3, node-abi@^2.7.0: ngx-toastr@^13.2.0:
version "2.19.3" version "13.2.0"
resolved "https://registry.npmjs.org/node-abi/-/node-abi-2.19.3.tgz" resolved "https://registry.yarnpkg.com/ngx-toastr/-/ngx-toastr-13.2.0.tgz#3ef047c977a7d0fb67fed9338b8f5add3c87b356"
integrity sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg== integrity sha512-XU+wACX5hxwOJ4BtPMAUExQmYbjfvH3C/R4vcC9QK/dX2Zw+2w9tS9m4W6TUFyR92xZ/tGLBtsqRdrDRn3fJCw==
dependencies:
tslib "^2.0.0"
node-abi@^2.20.0, node-abi@^2.21.0, node-abi@^2.7.0:
version "2.21.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.21.0.tgz#c2dc9ebad6f4f53d6ea9b531e7b8faad81041d48"
integrity sha512-smhrivuPqEM3H5LmnY3KU6HfYv0u4QklgAxfFyRNujKUzbUcYZ+Jc2EhukB9SRcD2VpqhxM7n/MIcp1Ua1/JMg==
dependencies: dependencies:
semver "^5.4.1" semver "^5.4.1"
@@ -2102,7 +2125,7 @@ node-addon-api@3.0.0:
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz" resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz"
integrity sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg== integrity sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==
node-addon-api@^3.0.0, node-addon-api@^3.0.2: node-addon-api@^3.0.0, node-addon-api@^3.0.2, node-addon-api@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz" resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz"
integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==
@@ -2270,9 +2293,9 @@ npm-user-validate@^1.0.1:
integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw== integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw==
npm@6: npm@6:
version "6.14.10" version "6.14.11"
resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.10.tgz#f45c8e4244294ba793770f2ab0e9ce2d0b93fd29" resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.11.tgz#e0b5598d7b9a42d275e61d8bd28cd7eee0074a3b"
integrity sha512-FT23Qy/JMA+qxEYReMOr1MY7642fKn8Onn+72LASPi872Owvmw0svm+/DXTHOC3yO9CheEO+EslyXEpdBdRtIA== integrity sha512-1Zh7LjuIoEhIyjkBflSSGzfjuPQwDlghNloppjruOH5bmj9midT9qcNT0tRUZRR04shU9ekrxNy9+UTBrqeBpQ==
dependencies: dependencies:
JSONStream "^1.3.5" JSONStream "^1.3.5"
abbrev "~1.1.1" abbrev "~1.1.1"
@@ -2309,7 +2332,7 @@ npm@6:
infer-owner "^1.0.4" infer-owner "^1.0.4"
inflight "~1.0.6" inflight "~1.0.6"
inherits "^2.0.4" inherits "^2.0.4"
ini "^1.3.5" ini "^1.3.8"
init-package-json "^1.10.3" init-package-json "^1.10.3"
is-cidr "^3.0.0" is-cidr "^3.0.0"
json-parse-better-errors "^1.0.2" json-parse-better-errors "^1.0.2"
@@ -2693,6 +2716,27 @@ prebuild-install@^6.0.0:
tunnel-agent "^0.6.0" tunnel-agent "^0.6.0"
which-pm-runs "^1.0.0" which-pm-runs "^1.0.0"
prebuild-install@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.0.1.tgz#5902172f7a40eb67305b96c2a695db32636ee26d"
integrity sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ==
dependencies:
detect-libc "^1.0.3"
expand-template "^2.0.3"
github-from-package "0.0.0"
minimist "^1.2.3"
mkdirp-classic "^0.5.3"
napi-build-utils "^1.0.1"
node-abi "^2.7.0"
noop-logger "^0.1.1"
npmlog "^4.0.1"
pump "^3.0.0"
rc "^1.2.7"
simple-get "^3.0.3"
tar-fs "^2.0.0"
tunnel-agent "^0.6.0"
which-pm-runs "^1.0.0"
prepend-http@^1.0.1: prepend-http@^1.0.1:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
@@ -3018,23 +3062,23 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies: dependencies:
aproba "^1.1.1" aproba "^1.1.1"
rxjs@^6.5.5: rxjs@^6.6.6:
version "6.6.3" version "6.6.6"
resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70"
integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== integrity sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==
dependencies: dependencies:
tslib "^1.9.0" tslib "^1.9.0"
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.2.0:
version "5.2.1" version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
"safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz"
@@ -3059,21 +3103,22 @@ serialize-error@^5.0.0:
dependencies: dependencies:
type-fest "^0.8.0" type-fest "^0.8.0"
serialport@^9.0.4: serialport@^9.0.7:
version "9.0.4" version "9.0.7"
resolved "https://registry.npmjs.org/serialport/-/serialport-9.0.4.tgz" resolved "https://registry.yarnpkg.com/serialport/-/serialport-9.0.7.tgz#bd116a70bd7acbfd587491acd3ee03e02a0df71c"
integrity sha512-Wtl6sxciHKNdJKW8jUZm+f5KRXt0J0UP25ksM8N31l08KTdAhZ5MmKNUFpoO/YYG6TvHFOu+07PUX35m+TUw7g== integrity sha512-NeDfVks3JAJ7s8cXDopx1iUUgC/7TaltE7iQGiSewIWMZaK7oStiz3VJzcuKgor7F+U/y6zbAnj4i6eHq0on+g==
dependencies: dependencies:
"@serialport/binding-mock" "^9.0.2" "@serialport/binding-mock" "^9.0.7"
"@serialport/bindings" "^9.0.4" "@serialport/bindings" "^9.0.7"
"@serialport/parser-byte-length" "^9.0.1" "@serialport/parser-byte-length" "^9.0.7"
"@serialport/parser-cctalk" "^9.0.1" "@serialport/parser-cctalk" "^9.0.7"
"@serialport/parser-delimiter" "^9.0.1" "@serialport/parser-delimiter" "^9.0.7"
"@serialport/parser-readline" "^9.0.1" "@serialport/parser-inter-byte-timeout" "^9.0.7"
"@serialport/parser-ready" "^9.0.1" "@serialport/parser-readline" "^9.0.7"
"@serialport/parser-regex" "^9.0.1" "@serialport/parser-ready" "^9.0.7"
"@serialport/stream" "^9.0.2" "@serialport/parser-regex" "^9.0.7"
debug "^4.1.1" "@serialport/stream" "^9.0.7"
debug "^4.3.1"
set-blocking@^2.0.0, set-blocking@~2.0.0: set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0" version "2.0.0"
@@ -3201,11 +3246,6 @@ split-on-first@^1.0.0:
resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
sshpk@^1.7.0: sshpk@^1.7.0:
version "1.16.1" version "1.16.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz"
@@ -3463,15 +3503,15 @@ tough-cookie@~2.5.0:
psl "^1.1.28" psl "^1.1.28"
punycode "^2.1.1" punycode "^2.1.1"
tslib@^1.10.0, tslib@^1.9.0: tslib@^1.9.0:
version "1.14.1" version "1.14.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.0.0: tslib@^2.0.0:
version "2.0.3" version "2.1.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
tunnel-agent@^0.6.0: tunnel-agent@^0.6.0:
version "0.6.0" version "0.6.0"
@@ -3836,9 +3876,9 @@ yargs@^8.0.2:
y18n "^3.2.1" y18n "^3.2.1"
yargs-parser "^7.0.0" yargs-parser "^7.0.0"
zone.js@^0.11.3: zone.js@^0.11.4:
version "0.11.3" version "0.11.4"
resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.3.tgz#255a6313174731cc014d63233ef04fd9858da375" resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.4.tgz#0f70dcf6aba80f698af5735cbb257969396e8025"
integrity sha512-Y4hTHoh4VcxU5BDGAqEoOnOiyT254w6CiHtpQxAJUSMZPyVgdbKf+5R7Mwz6xsPhMIeBXk5rTopRZDpjssTCUg== integrity sha512-DDh2Ab+A/B+9mJyajPjHFPWfYU1H+pdun4wnnk0OcQTNjem1XQSZ2CDW+rfZEUDjv5M19SBqAkjZi0x5wuB5Qw==
dependencies: dependencies:
tslib "^2.0.0" tslib "^2.0.0"

View File

@@ -8,8 +8,9 @@ afterAllArtifactBuild: "./build/mac/afterBuildHook.js"
files: files:
- '**/*' - '**/*'
- dist - dist
- '!lib'
- '!src' - '!src'
- '!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}' - '!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme,node.lib}'
- '!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples,docs}' - '!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples,docs}'
- '!**/node_modules/@angular/common/locales' - '!**/node_modules/@angular/common/locales'
- '!**/node_modules/@angular/compiler/src' - '!**/node_modules/@angular/compiler/src'
@@ -62,7 +63,7 @@ mac:
NSRemovableVolumesUsageDescription: 'A subprocess requests access to files on a removable volume.' NSRemovableVolumesUsageDescription: 'A subprocess requests access to files on a removable volume.'
linux: linux:
category: Utilities category: Utility
icon: "./build/icons" icon: "./build/icons"
artifactName: terminus-${version}-linux.${ext} artifactName: terminus-${version}-linux.${ext}
executableArgs: executableArgs:
@@ -87,3 +88,6 @@ rpm:
depends: depends:
- screen - screen
- gnome-keyring - gnome-keyring
fpm:
- '--rpm-rpmbuild-define'
- '_build_id_links none'

View File

@@ -1,33 +1,34 @@
{ {
"devDependencies": { "devDependencies": {
"@fortawesome/fontawesome-free": "^5.13.0", "@fortawesome/fontawesome-free": "^5.15.2",
"@sentry/cli": "^1.61.0", "@sentry/cli": "^1.63.0",
"@sentry/electron": "^2.0.4", "@sentry/electron": "^2.4.0",
"@terminus-term/to-string-loader": "1.1.7-beta.1",
"@types/electron-config": "^3.2.2", "@types/electron-config": "^3.2.2",
"@types/electron-debug": "^2.1.0", "@types/electron-debug": "^2.1.0",
"@types/fs-extra": "^8.1.1", "@types/fs-extra": "^8.1.1",
"@types/js-yaml": "^3.12.5", "@types/js-yaml": "^4.0.0",
"@types/node": "14.14.14", "@types/node": "14.14.31",
"@types/webpack-env": "^1.16.0", "@types/webpack-env": "^1.16.0",
"@typescript-eslint/eslint-plugin": "^4.11.0", "@typescript-eslint/eslint-plugin": "^4.14.1",
"@typescript-eslint/parser": "^4.11.0", "@typescript-eslint/parser": "^4.17.0",
"apply-loader": "2.0.0", "apply-loader": "2.0.0",
"awesome-typescript-loader": "^5.2.1", "awesome-typescript-loader": "^5.2.1",
"compare-versions": "^3.6.0", "compare-versions": "^3.6.0",
"core-js": "^3.8.1", "core-js": "^3.9.1",
"cross-env": "7.0.2", "cross-env": "7.0.3",
"css-loader": "3.4.2", "css-loader": "5.0.1",
"electron": "^11.1.1", "electron": "12.0.1",
"electron-builder": "22.10.4", "electron-builder": "22.10.5",
"electron-download": "^4.1.1", "electron-download": "^4.1.1",
"electron-installer-snap": "^5.1.0", "electron-installer-snap": "^5.1.0",
"electron-notarize": "^1.0.0", "electron-notarize": "^1.0.0",
"electron-rebuild": "^2.3.4", "electron-rebuild": "^2.3.5",
"eslint": "^7.6.0", "eslint": "^7.18.0",
"eslint-plugin-import": "^2.21.1", "eslint-plugin-import": "^2.21.1",
"file-loader": "^5.1.0", "file-loader": "^6.2.0",
"graceful-fs": "^4.2.4", "graceful-fs": "^4.2.6",
"html-loader": "0.5.5", "html-loader": "2.1.2",
"json-loader": "0.5.7", "json-loader": "0.5.7",
"lru-cache": "^6.0.0", "lru-cache": "^6.0.0",
"macos-release": "^2.4.1", "macos-release": "^2.4.1",
@@ -36,31 +37,31 @@
"node-sass": "^5.0.0", "node-sass": "^5.0.0",
"npmlog": "4.1.2", "npmlog": "4.1.2",
"npx": "^10.2.2", "npx": "^10.2.2",
"pug": "^2.0.4", "patch-package": "^6.2.2",
"pug": "^3.0.2",
"pug-html-loader": "1.1.5", "pug-html-loader": "1.1.5",
"pug-lint": "^2.6.0", "pug-lint": "^2.6.0",
"pug-loader": "^2.4.0", "pug-loader": "^2.4.0",
"pug-static-loader": "2.0.0", "pug-static-loader": "2.0.0",
"raw-loader": "4.0.1", "raw-loader": "4.0.2",
"sass-loader": "^10.1.0", "sass-loader": "^11.0.1",
"shelljs": "0.8.4", "shelljs": "0.8.4",
"source-code-pro": "^2.30.2", "source-code-pro": "^2.30.2",
"source-sans-pro": "3.6.0", "source-sans-pro": "3.6.0",
"ssh2-streams": "^0.4.10", "ssh2-streams": "^0.4.10",
"style-loader": "^2.0.0", "style-loader": "^2.0.0",
"svg-inline-loader": "^0.8.2", "svg-inline-loader": "^0.8.2",
"to-string-loader": "1.1.6", "tslib": "^2.1.0",
"tslib": "^2.0.3", "typedoc": "^0.20.28",
"typedoc": "^0.18.0", "typescript": "^3.9.9",
"typescript": "^3.9.7", "url-loader": "^4.1.1",
"url-loader": "^3.0.0", "val-loader": "3.0.0",
"val-loader": "2.1.1", "webpack": "^5.18.0",
"webpack": "^5.11.0", "webpack-cli": "^4.5.0",
"webpack-cli": "^4.2.0",
"yaml-loader": "0.6.0" "yaml-loader": "0.6.0"
}, },
"resolutions": { "resolutions": {
"*/node-abi": "^2.19.3", "*/node-abi": "^2.20.0",
"**/graceful-fs": "^4.2.4" "**/graceful-fs": "^4.2.4"
}, },
"scripts": { "scripts": {
@@ -70,11 +71,9 @@
"start": "cross-env TERMINUS_DEV=1 electron app --debug", "start": "cross-env TERMINUS_DEV=1 electron app --debug",
"start:prod": "electron app --debug", "start:prod": "electron app --debug",
"prod": "cross-env TERMINUS_DEV=1 electron app", "prod": "cross-env TERMINUS_DEV=1 electron app",
"docs": "typedoc --out docs/api terminus-core/src && typedoc --out docs/api/terminal --tsconfig terminus-terminal/tsconfig.typings.json terminus-terminal/src && typedoc --out docs/api/settings --tsconfig terminus-settings/tsconfig.typings.json terminus-settings/src", "docs": "typedoc --out docs/api --tsconfig terminus-core/src/tsconfig.typings.json terminus-core/src/index.ts && typedoc --out docs/api/terminal --tsconfig terminus-terminal/tsconfig.typings.json terminus-terminal/src/index.ts && typedoc --out docs/api/settings --tsconfig terminus-settings/tsconfig.typings.json terminus-settings/src/index.ts",
"lint": "eslint --ext ts */src */lib", "lint": "eslint --ext ts */src */lib",
"postinstall": "node ./scripts/install-deps.js" "postinstall": "node ./scripts/install-deps.js"
}, },
"repository": "eugeny/terminus", "private": true
"author": "Eugene Pankov",
"license": "MIT"
} }

View File

@@ -1,8 +1,6 @@
#!/usr/bin/env node #!/usr/bin/env node
const builder = require('electron-builder').build const builder = require('electron-builder').build
const vars = require('./vars') const vars = require('./vars')
const fs = require('fs')
const signHook = require('../build/mac/afterSignHook')
const isTag = (process.env.GITHUB_REF || '').startsWith('refs/tags/') const isTag = (process.env.GITHUB_REF || '').startsWith('refs/tags/')
@@ -16,6 +14,7 @@ builder({
extraMetadata: { extraMetadata: {
version: vars.version, version: vars.version,
}, },
npmRebuild: process.env.ARCH !== 'arm64',
}, },
publish: isTag ? 'always' : 'onTag', publish: isTag ? 'always' : 'onTag',
}).catch(e => { }).catch(e => {

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-community-color-schemes", "name": "terminus-community-color-schemes",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Community color schemes for Terminus", "description": "Community color schemes for Terminus",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"

View File

@@ -0,0 +1,42 @@
!
!
*.foreground: #d8dee9
*.background: #2e3440
*.cursorColor: #d8dee9
!
! Black
*.color0: #3b4252
*.color8: #373e4d
!
! Red
*.color1: #bf616a
*.color9: #94545d
!
! Green
*.color2: #a3be8c
*.color10: #809575
!
! Yellow
*.color3: #ebcb8b
*.color11: #b29e75
!
! Blue
*.color4: #81a1c1
*.color12: #68809a
!
! Magenta
*.color5: #b48ead
*.color13: #8c738c
!
! Cyan
*.color6: #88c0d0
*.color14: #6d96a5
!
! White
*.color7: #e5e9f0
*.color15: #aeb3bb
!
! Bold, Italic, Underline
*.colorBD: #a5abb6
!*.colorIT:
!*.colorUL:

View File

@@ -1,14 +1,14 @@
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { TerminalColorSchemeProvider, TerminalColorScheme } from 'terminus-terminal' import { TerminalColorSchemeProvider, TerminalColorScheme } from 'terminus-terminal'
const schemeContents = require.context('../schemes/', true, /.*/) const schemeContents = require.context('../schemes/', false, /.*/)
@Injectable() @Injectable()
export class ColorSchemes extends TerminalColorSchemeProvider { export class ColorSchemes extends TerminalColorSchemeProvider {
async getSchemes (): Promise<TerminalColorScheme[]> { async getSchemes (): Promise<TerminalColorScheme[]> {
const schemes: TerminalColorScheme[] = [] const schemes: TerminalColorScheme[] = []
schemeContents.keys().forEach(schemeFile => { schemeContents.keys().filter(x => !x.startsWith('./')).forEach(schemeFile => {
const lines = (schemeContents(schemeFile).default as string).split('\n') const lines = (schemeContents(schemeFile).default as string).split('\n')
// process #define variables // process #define variables

View File

@@ -1,51 +1,6 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'community-color-schemes',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname, module.exports.module.rules.push({ test: /[\\\/]schemes[\\\/]/, use: 'raw-loader' })
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-community-color-schemes:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /[\\\/]schemes[\\\/]/, use: "raw-loader" },
],
},
externals: [
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
/^terminus-/,
],
}

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-core", "name": "terminus-core",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Terminus core", "description": "Terminus core",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -17,18 +17,18 @@
"author": "Eugene Pankov", "author": "Eugene Pankov",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/js-yaml": "^3.9.0", "@types/js-yaml": "^4.0.0",
"@types/shell-escape": "^0.2.0", "@types/shell-escape": "^0.2.0",
"@types/winston": "^2.3.6", "@types/winston": "^2.3.6",
"axios": "^0.19.0", "axios": "^0.21.1",
"bootstrap": "^4.1.3", "bootstrap": "^4.1.3",
"core-js": "^3.1.2", "core-js": "^3.1.2",
"deepmerge": "^4.1.1", "deepmerge": "^4.1.1",
"electron-updater": "^4.0.6", "electron-updater": "^4.0.6",
"js-yaml": "^3.9.0", "js-yaml": "^4.0.0",
"mixpanel": "^0.10.2", "mixpanel": "^0.10.2",
"ng2-dnd": "^5.0.2", "ng2-dnd": "^5.0.2",
"ngx-perfect-scrollbar": "^8.0.0", "ngx-perfect-scrollbar": "^10.1.0",
"readable-stream": "2.3.7", "readable-stream": "2.3.7",
"shell-escape": "^0.2.0", "shell-escape": "^0.2.0",
"uuid": "^8.0.0", "uuid": "^8.0.0",

View File

@@ -17,6 +17,7 @@ export { Logger, LogService } from '../services/log.service'
export { HomeBaseService } from '../services/homeBase.service' export { HomeBaseService } from '../services/homeBase.service'
export { HotkeysService } from '../services/hotkeys.service' export { HotkeysService } from '../services/hotkeys.service'
export { HostAppService, Platform } from '../services/hostApp.service' export { HostAppService, Platform } from '../services/hostApp.service'
export { NotificationsService } from '../services/notifications.service'
export { ShellIntegrationService } from '../services/shellIntegration.service' export { ShellIntegrationService } from '../services/shellIntegration.service'
export { ThemesService } from '../services/themes.service' export { ThemesService } from '../services/themes.service'
export { TabsService } from '../services/tabs.service' export { TabsService } from '../services/tabs.service'

View File

@@ -10,4 +10,7 @@ export abstract class Theme {
css: string css: string
terminalBackground: string terminalBackground: string
macOSWindowButtonsInsetX?: number
macOSWindowButtonsInsetY?: number
} }

View File

@@ -1,6 +1,6 @@
title-bar( title-bar(
*ngIf='!hostApp.isFullScreen && config.store.appearance.frame == "full" && config.store.appearance.dock == "off"', *ngIf='!hostApp.isFullScreen && config.store.appearance.frame == "full" && config.store.appearance.dock == "off"',
[class.inset]='hostApp.platform == Platform.macOS' [class.inset]='hostApp.platform == Platform.macOS && !hostApp.isFullScreen'
) )
.content( .content(
@@ -9,6 +9,7 @@ title-bar(
) )
.tab-bar .tab-bar
.inset.background(*ngIf='hostApp.platform == Platform.macOS \ .inset.background(*ngIf='hostApp.platform == Platform.macOS \
&& !hostApp.isFullScreen \
&& config.store.appearance.frame == "thin" \ && config.store.appearance.frame == "thin" \
&& (config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left")') && (config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left")')
.tabs( .tabs(

View File

@@ -85,6 +85,7 @@ $side-tab-width: 200px;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center;
padding: 0 15px; padding: 0 15px;
flex: 0 0 auto; flex: 0 0 auto;
border-bottom: 2px solid transparent; border-bottom: 2px solid transparent;

View File

@@ -142,6 +142,8 @@ export class AppRootComponent {
this.touchbar.update() this.touchbar.update()
this.hostApp.useBuiltinGraphics()
config.changed$.subscribe(() => this.updateVibrancy()) config.changed$.subscribe(() => this.updateVibrancy())
this.updateVibrancy() this.updateVibrancy()

View File

@@ -17,7 +17,7 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
}) })
export class CheckboxComponent implements ControlValueAccessor { export class CheckboxComponent implements ControlValueAccessor {
@HostBinding('class.active') @Input() model: boolean @HostBinding('class.active') @Input() model: boolean
@Input() disabled: boolean @HostBinding('class.disabled') @Input() disabled: boolean
@Input() text: string @Input() text: string
private changed = new Array<(val: boolean) => void>() private changed = new Array<(val: boolean) => void>()

View File

@@ -7,7 +7,7 @@
(ngModelChange)='onFilterChange()' (ngModelChange)='onFilterChange()'
) )
.list-group.mt-3(*ngIf='filteredOptions.length') .list-group(*ngIf='filteredOptions.length')
a.list-group-item.list-group-item-action.d-flex.align-items-center( a.list-group-item.list-group-item-action.d-flex.align-items-center(
#item, #item,
(click)='selectOption(option)', (click)='selectOption(option)',

View File

@@ -1,6 +1,12 @@
.modal-body {
padding: 0;
}
.list-group { .list-group {
max-height: 70vh; max-height: 70vh;
overflow: auto; overflow: auto;
border-top-left-radius: 0;
border-top-right-radius: 0;
} }
.icon { .icon {

View File

@@ -1,9 +1,10 @@
import { Component, Input, HostListener, ViewChildren, QueryList, ElementRef } from '@angular/core' import { Component, Input, HostListener, ViewChildren, QueryList, ElementRef } from '@angular/core' // eslint-disable-line @typescript-eslint/no-unused-vars
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap' import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { SelectorOption } from '../api/selector' import { SelectorOption } from '../api/selector'
/** @hidden */ /** @hidden */
@Component({ @Component({
selector: 'selector-modal',
template: require('./selectorModal.component.pug'), template: require('./selectorModal.component.pug'),
styles: [require('./selectorModal.component.scss')], styles: [require('./selectorModal.component.scss')],
}) })

View File

@@ -6,6 +6,12 @@ $tabs-height: 38px;
flex: 1000 1 200px; flex: 1000 1 200px;
width: 200px; width: 200px;
padding: 0 10px;
&.flex-width {
flex: 1000 1 auto;
width: auto;
}
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -24,7 +30,6 @@ $tabs-height: 38px;
-webkit-app-region: no-drag; -webkit-app-region: no-drag;
cursor: -webkit-grab; cursor: -webkit-grab;
margin-left: 10px;
width: 22px; width: 22px;
border-radius: 10px; border-radius: 10px;
text-align: center; text-align: center;
@@ -34,7 +39,7 @@ $tabs-height: 38px;
.name { .name {
flex: auto; flex: auto;
margin: 0 1px 0 10px; margin-top: 1px;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
@@ -42,6 +47,10 @@ $tabs-height: 38px;
align-self: center; align-self: center;
} }
.index + .name {
margin-left: 10px;
}
button { button {
display: block; display: block;
flex: none; flex: none;
@@ -49,13 +58,15 @@ $tabs-height: 38px;
opacity: 0; opacity: 0;
-webkit-app-region: no-drag; -webkit-app-region: no-drag;
position: absolute;
right: 0;
$button-size: 26px; $button-size: 26px;
width: $button-size; width: $button-size;
height: $button-size; height: $button-size;
border-radius: $button-size / 2; border-radius: $button-size / 2;
line-height: $button-size; line-height: $button-size;
align-self: center; align-self: center;
margin-right: 10px;
text-align: center; text-align: center;
font-size: 20px; font-size: 20px;
@@ -65,6 +76,13 @@ $tabs-height: 38px;
} }
} }
&:hover .name {
-webkit-mask-image: linear-gradient(black 0 0), linear-gradient(to left, transparent 0%, black 100%);
-webkit-mask-size: calc(100% - 60px) auto, 60px auto;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: left, right;
}
&:hover button { &:hover button {
transition: 0.25s opacity; transition: 0.25s opacity;
display: block; display: block;

View File

@@ -29,7 +29,7 @@ export class TabHeaderComponent {
@Input() @HostBinding('class.has-activity') hasActivity: boolean @Input() @HostBinding('class.has-activity') hasActivity: boolean
@Input() tab: BaseTabComponent @Input() tab: BaseTabComponent
@Input() progress: number|null @Input() progress: number|null
@ViewChild('handle') handle: ElementRef @ViewChild('handle') handle?: ElementRef
private constructor ( private constructor (
public app: AppService, public app: AppService,
@@ -58,7 +58,7 @@ export class TabHeaderComponent {
} }
ngAfterViewInit () { ngAfterViewInit () {
if (this.hostApp.platform === Platform.macOS) { if (this.handle && this.hostApp.platform === Platform.macOS) {
this.parentDraggable.setDragHandle(this.handle.nativeElement) this.parentDraggable.setDragHandle(this.handle.nativeElement)
} }
} }
@@ -81,6 +81,10 @@ export class TabHeaderComponent {
return items.slice(1) return items.slice(1)
} }
@HostBinding('class.flex-width') get isFlexWidthEnabled (): boolean {
return this.config.store.appearance.flexTabs
}
@HostListener('dblclick') onDoubleClick (): void { @HostListener('dblclick') onDoubleClick (): void {
this.showRenameTabModal() this.showRenameTabModal()
} }

View File

@@ -3,7 +3,6 @@
$toggle-size: 18px; $toggle-size: 18px;
$height: 30px; $height: 30px;
$padding: 2px; $padding: 2px;
cursor: pointer;
display: inline-flex; display: inline-flex;
overflow: visible; overflow: visible;
border-radius: 3px; border-radius: 3px;
@@ -16,8 +15,11 @@
padding-left: 10px; padding-left: 10px;
margin-left: -10px; margin-left: -10px;
&[disabled] { &.disabled {
opacity: 0.5; opacity: 0.5;
} }
* {
cursor: pointer;
}
} }

View File

@@ -42,6 +42,16 @@ hotkeys:
- 'Alt-9' - 'Alt-9'
tab-10: tab-10:
- 'Alt-0' - 'Alt-0'
tab-11: []
tab-12: []
tab-13: []
tab-14: []
tab-15: []
tab-16: []
tab-17: []
tab-18: []
tab-19: []
tab-20: []
split-right: split-right:
- 'Ctrl-Shift-E' - 'Ctrl-Shift-E'
split-bottom: split-bottom:

View File

@@ -40,6 +40,16 @@ hotkeys:
- '⌘-9' - '⌘-9'
tab-10: tab-10:
- '⌘-0' - '⌘-0'
tab-11: []
tab-12: []
tab-13: []
tab-14: []
tab-15: []
tab-16: []
tab-17: []
tab-18: []
tab-19: []
tab-20: []
split-right: split-right:
- '⌘-Shift-D' - '⌘-Shift-D'
split-bottom: split-bottom:

View File

@@ -43,6 +43,16 @@ hotkeys:
- 'Alt-9' - 'Alt-9'
tab-10: tab-10:
- 'Alt-0' - 'Alt-0'
tab-11: []
tab-12: []
tab-13: []
tab-14: []
tab-15: []
tab-16: []
tab-17: []
tab-18: []
tab-19: []
tab-20: []
split-right: split-right:
- 'Ctrl-Shift-E' - 'Ctrl-Shift-E'
split-bottom: split-bottom:

View File

@@ -2,8 +2,10 @@ appearance:
dock: off dock: off
dockScreen: current dockScreen: current
dockFill: 0.5 dockFill: 0.5
dockSpace: 1
dockHideOnBlur: false dockHideOnBlur: false
dockAlwaysOnTop: true dockAlwaysOnTop: true
flexTabs: false
tabsLocation: top tabsLocation: top
cycleTabs: true cycleTabs: true
theme: Standard theme: Standard

View File

@@ -89,6 +89,46 @@ export class AppHotkeyProvider extends HotkeyProvider {
id: 'tab-10', id: 'tab-10',
name: 'Tab 10', name: 'Tab 10',
}, },
{
id: 'tab-11',
name: 'Tab 11',
},
{
id: 'tab-12',
name: 'Tab 12',
},
{
id: 'tab-13',
name: 'Tab 13',
},
{
id: 'tab-14',
name: 'Tab 14',
},
{
id: 'tab-15',
name: 'Tab 15',
},
{
id: 'tab-16',
name: 'Tab 16',
},
{
id: 'tab-17',
name: 'Tab 17',
},
{
id: 'tab-18',
name: 'Tab 18',
},
{
id: 'tab-19',
name: 'Tab 19',
},
{
id: 'tab-20',
name: 'Tab 20',
},
{ {
id: 'split-right', id: 'split-right',
name: 'Split to the right', name: 'Split to the right',

View File

@@ -44,8 +44,11 @@ import 'ng2-dnd/bundles/style.css'
// PerfectScrollbar fix // PerfectScrollbar fix
import { fromEvent } from 'rxjs/internal/observable/fromEvent' import { fromEvent } from 'rxjs/internal/observable/fromEvent'
import { merge } from 'rxjs/internal/observable/merge' import { merge } from 'rxjs/internal/observable/merge'
try {
require('rxjs').fromEvent = fromEvent require('rxjs').fromEvent = fromEvent
require('rxjs').merge = merge require('rxjs').merge = merge
} catch {}
const PROVIDERS = [ const PROVIDERS = [
{ provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true }, { provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true },
@@ -110,7 +113,7 @@ export default class AppModule { // eslint-disable-line @typescript-eslint/no-ex
}) })
} }
static forRoot (): ModuleWithProviders { static forRoot (): ModuleWithProviders<AppModule> {
return { return {
ngModule: AppModule, ngModule: AppModule,
providers: PROVIDERS, providers: PROVIDERS,

View File

@@ -100,7 +100,7 @@ export class AppService {
hostApp.windowFocused$.subscribe(() => this._activeTab?.emitFocused()) hostApp.windowFocused$.subscribe(() => this._activeTab?.emitFocused())
this.tabClosed$.subscribe(async tab => { this.tabClosed$.subscribe(async tab => {
const token = await tab.getRecoveryToken() const token = await tabRecovery.getFullRecoveryToken(tab)
if (token) { if (token) {
this.closedTabsStack.push(token) this.closedTabsStack.push(token)
} }
@@ -263,7 +263,7 @@ export class AppService {
if (tabIndex > 0) { if (tabIndex > 0) {
this.swapTabs(this._activeTab, this.tabs[tabIndex - 1]) this.swapTabs(this._activeTab, this.tabs[tabIndex - 1])
} else if (this.config.store.appearance.cycleTabs) { } else if (this.config.store.appearance.cycleTabs) {
this.swapTabs(this._activeTab, this.tabs[this.tabs.length - 1]) this.tabs.push(this.tabs.shift()!)
} }
} }
} }
@@ -277,7 +277,7 @@ export class AppService {
if (tabIndex < this.tabs.length - 1) { if (tabIndex < this.tabs.length - 1) {
this.swapTabs(this._activeTab, this.tabs[tabIndex + 1]) this.swapTabs(this._activeTab, this.tabs[tabIndex + 1])
} else if (this.config.store.appearance.cycleTabs) { } else if (this.config.store.appearance.cycleTabs) {
this.swapTabs(this._activeTab, this.tabs[0]) this.tabs.unshift(this.tabs.pop()!)
} }
} }
} }

View File

@@ -144,7 +144,7 @@ export class ConfigService {
load (): void { load (): void {
if (fs.existsSync(this.path)) { if (fs.existsSync(this.path)) {
this._store = yaml.safeLoad(fs.readFileSync(this.path, 'utf8')) this._store = yaml.load(fs.readFileSync(this.path, 'utf8'))
} else { } else {
this._store = {} this._store = {}
} }
@@ -154,7 +154,7 @@ export class ConfigService {
save (): void { save (): void {
// Scrub undefined values // Scrub undefined values
this._store = JSON.parse(JSON.stringify(this._store)) this._store = JSON.parse(JSON.stringify(this._store))
fs.writeFileSync(this.path, yaml.safeDump(this._store), 'utf8') fs.writeFileSync(this.path, yaml.dump(this._store), 'utf8')
this.emitChange() this.emitChange()
this.hostApp.broadcastConfigChange(JSON.parse(JSON.stringify(this.store))) this.hostApp.broadcastConfigChange(JSON.parse(JSON.stringify(this.store)))
} }
@@ -163,14 +163,14 @@ export class ConfigService {
* Reads config YAML as string * Reads config YAML as string
*/ */
readRaw (): string { readRaw (): string {
return yaml.safeDump(this._store) return yaml.dump(this._store)
} }
/** /**
* Writes config YAML as string * Writes config YAML as string
*/ */
writeRaw (data: string): void { writeRaw (data: string): void {
this._store = yaml.safeLoad(data) this._store = yaml.load(data)
this.save() this.save()
this.load() this.load()
this.emitChange() this.emitChange()

View File

@@ -34,25 +34,30 @@ export class DockingService {
const newBounds: Bounds = { x: 0, y: 0, width: 0, height: 0 } const newBounds: Bounds = { x: 0, y: 0, width: 0, height: 0 }
const fill = this.config.store.appearance.dockFill <= 1 ? this.config.store.appearance.dockFill : 1 const fill = this.config.store.appearance.dockFill <= 1 ? this.config.store.appearance.dockFill : 1
const space = this.config.store.appearance.dockSpace <= 1 ? this.config.store.appearance.dockSpace : 1
const [minWidth, minHeight] = this.hostApp.getWindow().getMinimumSize() const [minWidth, minHeight] = this.hostApp.getWindow().getMinimumSize()
if (dockSide === 'left' || dockSide === 'right') { if (dockSide === 'left' || dockSide === 'right') {
newBounds.width = Math.max(minWidth, Math.round(fill * display.bounds.width)) newBounds.width = Math.max(minWidth, Math.round(fill * display.bounds.width))
newBounds.height = display.bounds.height newBounds.height = Math.round(display.bounds.height * space)
} }
if (dockSide === 'top' || dockSide === 'bottom') { if (dockSide === 'top' || dockSide === 'bottom') {
newBounds.width = display.bounds.width newBounds.width = Math.round(display.bounds.width * space)
newBounds.height = Math.max(minHeight, Math.round(fill * display.bounds.height)) newBounds.height = Math.max(minHeight, Math.round(fill * display.bounds.height))
} }
if (dockSide === 'right') { if (dockSide === 'right') {
newBounds.x = display.bounds.x + display.bounds.width - newBounds.width newBounds.x = display.bounds.x + display.bounds.width - newBounds.width
} else { } else if (dockSide === 'left') {
newBounds.x = display.bounds.x newBounds.x = display.bounds.x
} else {
newBounds.x = display.bounds.x + Math.round(display.bounds.width / 2 * (1 - space))
} }
if (dockSide === 'bottom') { if (dockSide === 'bottom') {
newBounds.y = display.bounds.y + display.bounds.height - newBounds.height newBounds.y = display.bounds.y + display.bounds.height - newBounds.height
} else { } else if (dockSide === 'top') {
newBounds.y = display.bounds.y newBounds.y = display.bounds.y
} else {
newBounds.y = display.bounds.y + Math.round(display.bounds.height / 2 * (1 - space))
} }
const alwaysOnTop = this.config.store.appearance.dockAlwaysOnTop const alwaysOnTop = this.config.store.appearance.dockAlwaysOnTop

View File

@@ -1,5 +1,6 @@
import type { BrowserWindow, TouchBar, MenuItemConstructorOptions } from 'electron' import type { BrowserWindow, TouchBar, MenuItemConstructorOptions } from 'electron'
import * as path from 'path' import * as path from 'path'
import * as fs from 'mz/fs'
import shellEscape from 'shell-escape' import shellEscape from 'shell-escape'
import { Observable, Subject } from 'rxjs' import { Observable, Subject } from 'rxjs'
import { Injectable, NgZone, EventEmitter } from '@angular/core' import { Injectable, NgZone, EventEmitter } from '@angular/core'
@@ -7,6 +8,12 @@ import { ElectronService } from './electron.service'
import { Logger, LogService } from './log.service' import { Logger, LogService } from './log.service'
import { isWindowsBuild, WIN_BUILD_FLUENT_BG_SUPPORTED } from '../utils' import { isWindowsBuild, WIN_BUILD_FLUENT_BG_SUPPORTED } from '../utils'
/* eslint-disable block-scoped-var */
try {
var wnr = require('windows-native-registry') // eslint-disable-line @typescript-eslint/no-var-requires, no-var
} catch (_) { }
export enum Platform { export enum Platform {
Linux = 'Linux', Linux = 'Linux',
macOS = 'macOS', macOS = 'macOS',
@@ -150,9 +157,10 @@ export class HostAppService {
this.zone.run(() => this.displaysChanged.next()) this.zone.run(() => this.displaysChanged.next())
}) })
electron.ipcRenderer.on('host:second-instance', (_$event, argv: any, cwd: string) => this.zone.run(() => { electron.ipcRenderer.on('cli', (_$event, argv: any, cwd: string, secondInstance: boolean) => this.zone.run(async () => {
this.logger.info('Second instance', argv) this.logger.info('Second instance', argv)
const op = argv._[0] const op = argv._[0]
const opAsPath = op ? path.resolve(cwd, op) : null
if (op === 'open') { if (op === 'open') {
this.cliOpenDirectory.next(path.resolve(cwd, argv.directory)) this.cliOpenDirectory.next(path.resolve(cwd, argv.directory))
} else if (op === 'run') { } else if (op === 'run') {
@@ -165,9 +173,13 @@ export class HostAppService {
this.cliPaste.next(text) this.cliPaste.next(text)
} else if (op === 'profile') { } else if (op === 'profile') {
this.cliOpenProfile.next(argv.profileName) this.cliOpenProfile.next(argv.profileName)
} else if (op === undefined) { } else if (secondInstance && op === undefined) {
this.newWindow() this.newWindow()
} else { } else if (opAsPath && (await fs.lstat(opAsPath)).isDirectory()) {
this.cliOpenDirectory.next(opAsPath)
}
if (secondInstance) {
this.secondInstance.next() this.secondInstance.next()
} }
})) }))
@@ -277,6 +289,20 @@ export class HostAppService {
this.electron.ipcRenderer.send('app:register-global-hotkey', specs) this.electron.ipcRenderer.send('app:register-global-hotkey', specs)
} }
useBuiltinGraphics (): void {
const keyPath = 'SOFTWARE\\Microsoft\\DirectX\\UserGpuPreferences'
const valueName = this.electron.app.getPath('exe')
if (this.platform === Platform.Windows) {
if (!wnr.getRegistryValue(wnr.HK.CU, keyPath, valueName)) {
wnr.setRegistryValue(wnr.HK.CU, keyPath, valueName, wnr.REG.SZ, 'GpuPreference=1;')
}
}
}
setTrafficLightInset (x: number, y: number): void {
this.getWindow().setTrafficLightPosition({ x, y })
}
relaunch (): void { relaunch (): void {
if (this.isPortable) { if (this.isPortable) {
this.electron.app.relaunch({ execPath: process.env.PORTABLE_EXECUTABLE_FILE }) this.electron.app.relaunch({ execPath: process.env.PORTABLE_EXECUTABLE_FILE })

View File

@@ -1,11 +1,13 @@
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { ElectronService } from './electron.service' import { ElectronService } from './electron.service'
import * as winston from 'winston' import type * as winston from 'winston'
import * as fs from 'fs' import * as fs from 'fs'
import * as path from 'path' import * as path from 'path'
const initializeWinston = (electron: ElectronService) => { const initializeWinston = (electron: ElectronService) => {
const logDirectory = electron.app.getPath('userData') const logDirectory = electron.app.getPath('userData')
// eslint-disable-next-line
const winston = require('winston')
if (!fs.existsSync(logDirectory)) { if (!fs.existsSync(logDirectory)) {
fs.mkdirSync(logDirectory) fs.mkdirSync(logDirectory)
@@ -64,7 +66,11 @@ export class LogService {
/** @hidden */ /** @hidden */
private constructor (electron: ElectronService) { private constructor (electron: ElectronService) {
if (!process.env.XWEB) {
this.log = initializeWinston(electron) this.log = initializeWinston(electron)
} else {
this.log = console as any
}
} }
create (name: string): Logger { create (name: string): Logger {

View File

@@ -0,0 +1,23 @@
import { Injectable } from '@angular/core'
import { ToastrService } from 'ngx-toastr'
@Injectable({ providedIn: 'root' })
export class NotificationsService {
private constructor (
private toastr: ToastrService,
) { }
notice (text: string): void {
this.toastr.info(text, undefined, {
timeOut: 1000,
})
}
info (text: string, details?: string): void {
this.toastr.info(text, details)
}
error (text: string, details?: string): void {
this.toastr.error(text, details)
}
}

View File

@@ -24,20 +24,22 @@ export class TabRecoveryService {
} }
window.localStorage.tabsRecovery = JSON.stringify( window.localStorage.tabsRecovery = JSON.stringify(
(await Promise.all( (await Promise.all(
tabs tabs.map(async tab => this.getFullRecoveryToken(tab))
.map(async tab => tab.getRecoveryToken().then(r => {
if (r) {
r.tabTitle = tab.title
if (tab.color) {
r.tabColor = tab.color
}
}
return r
}))
)).filter(token => !!token) )).filter(token => !!token)
) )
} }
async getFullRecoveryToken (tab: BaseTabComponent): Promise<RecoveryToken|null> {
const token = await tab.getRecoveryToken()
if (token) {
token.tabTitle = tab.title
if (tab.color) {
token.tabColor = tab.color
}
}
return token
}
async recoverTab (token: RecoveryToken): Promise<RecoveredTab|null> { 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 { try {

View File

@@ -30,7 +30,7 @@ export class TabsService {
* Duplicates an existing tab instance (using the tab recovery system) * Duplicates an existing tab instance (using the tab recovery system)
*/ */
async duplicate (tab: BaseTabComponent): Promise<BaseTabComponent|null> { async duplicate (tab: BaseTabComponent): Promise<BaseTabComponent|null> {
const token = await tab.getRecoveryToken() const token = await this.tabRecovery.getFullRecoveryToken(tab)
if (!token) { if (!token) {
return null return null
} }

View File

@@ -1,6 +1,7 @@
import { Inject, Injectable } from '@angular/core' import { Inject, Injectable } from '@angular/core'
import { ConfigService } from '../services/config.service' import { ConfigService } from '../services/config.service'
import { Theme } from '../api/theme' import { Theme } from '../api/theme'
import { HostAppService, Platform } from './hostApp.service'
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ThemesService { export class ThemesService {
@@ -9,6 +10,7 @@ export class ThemesService {
/** @hidden */ /** @hidden */
private constructor ( private constructor (
private config: ConfigService, private config: ConfigService,
private hostApp: HostAppService,
@Inject(Theme) private themes: Theme[], @Inject(Theme) private themes: Theme[],
) { ) {
this.applyCurrentTheme() this.applyCurrentTheme()
@@ -33,6 +35,12 @@ export class ThemesService {
} }
this.styleElement.textContent = theme.css this.styleElement.textContent = theme.css
document.querySelector('style#custom-css')!.innerHTML = this.config.store.appearance.css document.querySelector('style#custom-css')!.innerHTML = this.config.store.appearance.css
if (this.hostApp.platform === Platform.macOS) {
this.hostApp.setTrafficLightInset(
theme.macOSWindowButtonsInsetX ?? 14,
theme.macOSWindowButtonsInsetY ?? 22,
)
}
} }
private applyCurrentTheme (): void { private applyCurrentTheme (): void {

View File

@@ -1,24 +1,18 @@
import { NativeImage, SegmentedControlSegment, TouchBarSegmentedControl } from 'electron' import { SegmentedControlSegment, TouchBarSegmentedControl } from 'electron'
import { Injectable, Inject, NgZone } from '@angular/core' import { Injectable, NgZone } from '@angular/core'
import { AppService } from './app.service' import { AppService } from './app.service'
import { ConfigService } from './config.service'
import { ElectronService } from './electron.service' import { ElectronService } from './electron.service'
import { HostAppService, Platform } from './hostApp.service' import { HostAppService, Platform } from './hostApp.service'
import { ToolbarButton, ToolbarButtonProvider } from '../api'
/** @hidden */ /** @hidden */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class TouchbarService { export class TouchbarService {
private tabsSegmentedControl: TouchBarSegmentedControl private tabsSegmentedControl: TouchBarSegmentedControl
private buttonsSegmentedControl: TouchBarSegmentedControl
private tabSegments: SegmentedControlSegment[] = [] private tabSegments: SegmentedControlSegment[] = []
private nsImageCache: Record<string, NativeImage> = {}
private constructor ( private constructor (
private app: AppService, private app: AppService,
private hostApp: HostAppService, private hostApp: HostAppService,
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
private config: ConfigService,
private electron: ElectronService, private electron: ElectronService,
private zone: NgZone, private zone: NgZone,
) { ) {
@@ -63,16 +57,6 @@ export class TouchbarService {
return return
} }
let buttons: ToolbarButton[] = []
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
buttons = buttons.concat(provider.provide())
})
buttons = buttons.filter(x => !!x.touchBarNSImage)
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({ this.tabsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({
segments: this.tabSegments, segments: this.tabSegments,
selectedIndex: this.app.activeTab ? this.app.tabs.indexOf(this.app.activeTab) : undefined, selectedIndex: this.app.activeTab ? this.app.tabs.indexOf(this.app.activeTab) : undefined,
@@ -81,43 +65,14 @@ export class TouchbarService {
}), }),
}) })
this.buttonsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({
segments: buttons.map(button => this.getButton(button)),
mode: 'buttons',
change: (selectedIndex) => this.zone.run(() => {
if (buttons[selectedIndex].click) {
buttons[selectedIndex].click!()
}
}),
})
const touchBar = new this.electron.TouchBar({ const touchBar = new this.electron.TouchBar({
items: [ items: [
this.tabsSegmentedControl, this.tabsSegmentedControl,
new this.electron.TouchBar.TouchBarSpacer({ size: 'flexible' }),
new this.electron.TouchBar.TouchBarSpacer({ size: 'small' }),
this.buttonsSegmentedControl,
], ],
}) })
this.hostApp.setTouchBar(touchBar) this.hostApp.setTouchBar(touchBar)
} }
private getButton (button: ToolbarButton): SegmentedControlSegment {
return {
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])
}
return this.nsImageCache[name]
}
private shortenTitle (title: string): string { private shortenTitle (title: string): string {
if (title.length > 15) { if (title.length > 15) {
title = title.substring(0, 15) + '...' title = title.substring(0, 15) + '...'

View File

@@ -1,6 +1,10 @@
@import './theme.scss'; @import './theme.scss';
app-root { app-root {
.tabs-on-side .tab-bar {
height: 100% !important;
}
.tab-bar { .tab-bar {
height: 27px !important; height: 27px !important;
@@ -12,6 +16,10 @@ app-root {
height: 14px; height: 14px;
} }
} }
.inset {
width: 70 !important;
}
} }
terminaltab .content { terminaltab .content {

View File

@@ -66,7 +66,9 @@ app-root {
border: none; border: none;
transition: 0.25s all; transition: 0.25s all;
&:hover { background: $button-hover-bg !important; } right: 5px;
&:hover { background: $button-active-bg !important; }
&:active { background: $button-active-bg !important; } &:active { background: $button-active-bg !important; }
} }

View File

@@ -15,6 +15,8 @@ export class StandardCompactTheme extends Theme {
name = 'Compact' name = 'Compact'
css = require('./theme.compact.scss') css = require('./theme.compact.scss')
terminalBackground = '#222a33' terminalBackground = '#222a33'
macOSWindowButtonsInsetX = 8
macOSWindowButtonsInsetY = 12
} }
/** @hidden */ /** @hidden */

View File

@@ -1,60 +1,5 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'core',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname,
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-core:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
{ test: /\.css$/, use: ['to-string-loader', 'css-loader'], include: /component\.css/ },
{ test: /\.css$/, use: ['style-loader', 'css-loader'], exclude: /component\.css/ },
{ test: /\.yaml$/, use: ['json-loader', 'yaml-loader'] },
{ test: /\.svg/, use: ['svg-inline-loader'] },
],
},
externals: [
'electron',
'fs',
'os',
'path',
'windows-native-registry',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
],
}

View File

@@ -11,12 +11,12 @@
enabled "2.0.x" enabled "2.0.x"
kuler "^2.0.0" kuler "^2.0.0"
"@types/js-yaml@^3.9.0": "@types/js-yaml@^4.0.0":
version "3.12.5" version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.5.tgz#136d5e6a57a931e1cce6f9d8126aa98a9c92a6bb" resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.0.tgz#d1a11688112091f2c711674df3a65ea2f47b5dfb"
integrity sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww== integrity sha512-4vlpCM5KPCL5CfGmTbpjwVKbISRYhduEJvvUWsH5EB7QInhEj94XPZ3ts/9FPiLZFqYO0xoW4ZL8z2AabTGgJA==
"@types/semver@^7.3.1": "@types/semver@^7.3.4":
version "7.3.4" version "7.3.4"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb"
integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ== integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==
@@ -40,12 +40,10 @@ agent-base@^4.3.0:
dependencies: dependencies:
es6-promisify "^5.0.0" es6-promisify "^5.0.0"
argparse@^1.0.7: argparse@^2.0.1:
version "1.0.10" version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
dependencies:
sprintf-js "~1.0.2"
async@^3.1.0: async@^3.1.0:
version "3.2.0" version "3.2.0"
@@ -57,24 +55,24 @@ at-least-node@^1.0.0:
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
axios@^0.19.0: axios@^0.21.1:
version "0.19.2" version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
dependencies: dependencies:
follow-redirects "1.5.10" follow-redirects "^1.10.0"
bootstrap@^4.1.3: bootstrap@^4.1.3:
version "4.5.3" version "4.5.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6" resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6"
integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ== integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ==
builder-util-runtime@8.7.2: builder-util-runtime@8.7.3:
version "8.7.2" version "8.7.3"
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.7.2.tgz#d93afc71428a12789b437e13850e1fa7da956d72" resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.7.3.tgz#0aaafa52d25295c939496f62231ca9ff06c30e40"
integrity sha512-xBqv+8bg6cfnzAQK1k3OGpfaHg+QkPgIgpEkXNhouZ0WiUkyZCftuRc2LYzQrLucFywpa14Xbc6+hTbpq83yRA== integrity sha512-1Q2ReBqFblimF5g/TLg2+0M5Xzv0Ih5LxJ/BMWXvEy/e6pQKeeEpbkPMGsN6OiQgkygaZo5VXCXIjOkOQG5EoQ==
dependencies: dependencies:
debug "^4.1.1" debug "^4.3.2"
sax "^1.2.4" sax "^1.2.4"
color-convert@^1.9.1: color-convert@^1.9.1:
@@ -124,22 +122,15 @@ colorspace@1.1.x:
text-hex "1.0.x" text-hex "1.0.x"
core-js@^3.1.2: core-js@^3.1.2:
version "3.7.0" version "3.9.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.7.0.tgz#b0a761a02488577afbf97179e4681bf49568520f" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.1.tgz#cec8de593db8eb2a85ffb0dbdeb312cb6e5460ae"
integrity sha512-NwS7fI5M5B85EwpWuIwJN4i/fbisQUwLwiSNUWeXlkAZ0sbBjLEvLvFLf1uzAUV66PcEPt4xCGCmOZSxVf3xzA== integrity sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg==
core-util-is@~1.0.0: core-util-is@~1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
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@^3.1.0: debug@^3.1.0:
version "3.2.6" version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
@@ -147,10 +138,10 @@ debug@^3.1.0:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
debug@^4.1.1: debug@^4.3.2:
version "4.2.0" version "4.3.2"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
dependencies: dependencies:
ms "2.1.2" ms "2.1.2"
@@ -160,17 +151,17 @@ deepmerge@^4.1.1:
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
electron-updater@^4.0.6: electron-updater@^4.0.6:
version "4.3.5" version "4.3.8"
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.5.tgz#4fb36f593a031c87ea07ee141c9f064d5deffb15" resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.8.tgz#94f1731682a756385726183e2b04b959cb319456"
integrity sha512-5jjN7ebvfj1cLI0VZMdCnJk6aC4bP+dy7ryBf21vArR0JzpRVk0OZHA2QBD+H5rm6ZSeDYHOY6+8PrMEqJ4wlQ== integrity sha512-/tB82Ogb2LqaXrUzAD8waJC+TZV52Pr0Znfj7w+i4D+jA2GgrKFI3Pxjp+36y9FcBMQz7kYsMHcB6c5zBJao+A==
dependencies: dependencies:
"@types/semver" "^7.3.1" "@types/semver" "^7.3.4"
builder-util-runtime "8.7.2" builder-util-runtime "8.7.3"
fs-extra "^9.0.1" fs-extra "^9.1.0"
js-yaml "^3.14.0" js-yaml "^4.0.0"
lazy-val "^1.0.4" lazy-val "^1.0.4"
lodash.isequal "^4.5.0" lodash.isequal "^4.5.0"
semver "^7.3.2" semver "^7.3.4"
enabled@2.0.x: enabled@2.0.x:
version "2.0.0" version "2.0.0"
@@ -189,11 +180,6 @@ es6-promisify@^5.0.0:
dependencies: dependencies:
es6-promise "^4.0.3" es6-promise "^4.0.3"
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
fast-safe-stringify@^2.0.4: fast-safe-stringify@^2.0.4:
version "2.0.7" version "2.0.7"
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
@@ -209,22 +195,20 @@ fn.name@1.x.x:
resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc"
integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
follow-redirects@1.5.10: follow-redirects@^1.10.0:
version "1.5.10" version "1.13.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.1.tgz#5f69b813376cee4fd0474a3aba835df04ab763b7"
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== integrity sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==
dependencies:
debug "=3.1.0"
fs-extra@^9.0.1: fs-extra@^9.1.0:
version "9.0.1" version "9.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
dependencies: dependencies:
at-least-node "^1.0.0" at-least-node "^1.0.0"
graceful-fs "^4.2.0" graceful-fs "^4.2.0"
jsonfile "^6.0.1" jsonfile "^6.0.1"
universalify "^1.0.0" universalify "^2.0.0"
graceful-fs@^4.1.6, graceful-fs@^4.2.0: graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.4" version "4.2.4"
@@ -259,13 +243,12 @@ isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
js-yaml@^3.14.0, js-yaml@^3.9.0: js-yaml@^4.0.0:
version "3.14.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f"
integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==
dependencies: dependencies:
argparse "^1.0.7" argparse "^2.0.1"
esprima "^4.0.0"
jsonfile@^6.0.1: jsonfile@^6.0.1:
version "6.1.0" version "6.1.0"
@@ -302,6 +285,13 @@ logform@^2.2.0:
ms "^2.1.1" ms "^2.1.1"
triple-beam "^1.3.0" triple-beam "^1.3.0"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
dependencies:
yallist "^4.0.0"
mixpanel@^0.10.2: mixpanel@^0.10.2:
version "0.10.3" version "0.10.3"
resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.10.3.tgz#2dff3bc0e17b57d6365547d315cbbf3ecfdb8a00" resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.10.3.tgz#2dff3bc0e17b57d6365547d315cbbf3ecfdb8a00"
@@ -309,11 +299,6 @@ mixpanel@^0.10.2:
dependencies: dependencies:
https-proxy-agent "3.0.0" https-proxy-agent "3.0.0"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ms@2.1.2, ms@^2.1.1: ms@2.1.2, ms@^2.1.1:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
@@ -324,13 +309,14 @@ ng2-dnd@^5.0.2:
resolved "https://registry.yarnpkg.com/ng2-dnd/-/ng2-dnd-5.0.2.tgz#862278ac7dedfa14f5783bbf34014d5d73dfefb4" resolved "https://registry.yarnpkg.com/ng2-dnd/-/ng2-dnd-5.0.2.tgz#862278ac7dedfa14f5783bbf34014d5d73dfefb4"
integrity sha512-5mWWBePwvEPsNd/HkdbD543Q9mPyJofL6zkNydl8/Ah3qrrvZT2DaEPbknY08OgkXpI2qUGksc01OzzVlRQ9dQ== integrity sha512-5mWWBePwvEPsNd/HkdbD543Q9mPyJofL6zkNydl8/Ah3qrrvZT2DaEPbknY08OgkXpI2qUGksc01OzzVlRQ9dQ==
ngx-perfect-scrollbar@^8.0.0: ngx-perfect-scrollbar@^10.1.0:
version "8.0.0" version "10.1.0"
resolved "https://registry.yarnpkg.com/ngx-perfect-scrollbar/-/ngx-perfect-scrollbar-8.0.0.tgz#19c1bbf9b1a36d89b00a68f7834e39427d29182f" resolved "https://registry.yarnpkg.com/ngx-perfect-scrollbar/-/ngx-perfect-scrollbar-10.1.0.tgz#6f7e2d8c849e595077b1c71992b6b544d56084d7"
integrity sha512-IXoFbULQnxyJj0gdCcKCLE/6OW9HCP9KARzMCKS1kNxTuzG4DghjM2AaCBRM5/sFwdbn6rqOKMCINtHA8W8YCA== integrity sha512-CQ4pthb+UOoccTh3dOVcmBJsUILpHNBsKMHatif6AB2jsvhH6y2O6elMaoslhQEFqpv1fJlrU25AKIUJQZIA4A==
dependencies: dependencies:
perfect-scrollbar "^1.4.0" perfect-scrollbar "1.5.0"
resize-observer-polyfill "^1.5.0" resize-observer-polyfill "^1.5.0"
tslib "^2.0.0"
one-time@^1.0.0: one-time@^1.0.0:
version "1.0.0" version "1.0.0"
@@ -339,7 +325,7 @@ one-time@^1.0.0:
dependencies: dependencies:
fn.name "1.x.x" fn.name "1.x.x"
perfect-scrollbar@^1.4.0: perfect-scrollbar@1.5.0:
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz#821d224ed8ff61990c23f26db63048cdc75b6b83" resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz#821d224ed8ff61990c23f26db63048cdc75b6b83"
integrity sha512-NrNHJn5mUGupSiheBTy6x+6SXCFbLlm8fVZh9moIzw/LgqElN5q4ncR4pbCBCYuCJ8Kcl9mYM0NgDxvW+b4LxA== integrity sha512-NrNHJn5mUGupSiheBTy6x+6SXCFbLlm8fVZh9moIzw/LgqElN5q4ncR4pbCBCYuCJ8Kcl9mYM0NgDxvW+b4LxA==
@@ -391,10 +377,12 @@ sax@^1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
semver@^7.3.2: semver@^7.3.4:
version "7.3.2" version "7.3.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
dependencies:
lru-cache "^6.0.0"
shell-escape@^0.2.0: shell-escape@^0.2.0:
version "0.2.0" version "0.2.0"
@@ -408,11 +396,6 @@ simple-swizzle@^0.2.2:
dependencies: dependencies:
is-arrayish "^0.3.1" is-arrayish "^0.3.1"
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
stack-trace@0.0.x: stack-trace@0.0.x:
version "0.0.10" version "0.0.10"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
@@ -442,10 +425,10 @@ triple-beam@^1.2.0, triple-beam@^1.3.0:
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==
universalify@^1.0.0: tslib@^2.0.0:
version "1.0.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
universalify@^2.0.0: universalify@^2.0.0:
version "2.0.0" version "2.0.0"
@@ -458,9 +441,9 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1:
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
uuid@^8.0.0: uuid@^8.0.0:
version "8.3.1" version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg== integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
winston-transport@^4.4.0: winston-transport@^4.4.0:
version "4.4.0" version "4.4.0"
@@ -484,3 +467,8 @@ winston@*, winston@^3.3.3:
stack-trace "0.0.x" stack-trace "0.0.x"
triple-beam "^1.3.0" triple-beam "^1.3.0"
winston-transport "^4.4.0" winston-transport "^4.4.0"
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-plugin-manager", "name": "terminus-plugin-manager",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Terminus' plugin manager", "description": "Terminus' plugin manager",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -18,7 +18,7 @@
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/semver": "^7.1.0", "@types/semver": "^7.1.0",
"axios": "^0.19.0", "axios": "^0.21.1",
"electron-promise-ipc": "^2.2.4", "electron-promise-ipc": "^2.2.4",
"mz": "^2.6.0", "mz": "^2.6.0",
"semver": "^7.1.1" "semver": "^7.1.1"

View File

@@ -2,7 +2,6 @@
strong Error in {{erroredPlugin}}: strong Error in {{erroredPlugin}}:
pre {{errorMessage}} pre {{errorMessage}}
.d-flex .d-flex
h3.mb-1 Installed h3.mb-1 Installed
button.btn.btn-outline-secondary.btn-sm.ml-auto((click)='openPluginsFolder()') button.btn.btn-outline-secondary.btn-sm.ml-auto((click)='openPluginsFolder()')
@@ -11,11 +10,17 @@
.list-group.list-group-flush.mt-2 .list-group.list-group-flush.mt-2
.list-group-item.d-flex.align-items-center(*ngFor='let plugin of pluginManager.installedPlugins') .list-group-item.d-flex.align-items-center(*ngFor='let plugin of pluginManager.installedPlugins')
toggle(
[ngModel]='isPluginEnabled(plugin)',
(ngModelChange)='togglePlugin(plugin)',
[disabled]='!canDisablePlugin(plugin)'
)
.mr-auto.d-flex.flex-column .mr-auto.d-flex.flex-column
div div
strong {{plugin.name}} strong {{plugin.name}}
small.text-muted.ml-1(*ngIf='!plugin.isBuiltin') {{plugin.version}} / {{plugin.author}} small.text-muted.ml-1(*ngIf='!plugin.isBuiltin') {{plugin.version}} / {{plugin.author}}
small.text-warning.ml-1(*ngIf='config.store.pluginBlacklist.includes(plugin.name)') Disabled small.text-warning.ml-1(*ngIf='!isPluginEnabled(plugin)') Disabled
a.text-muted.mb-0((click)='showPluginInfo(plugin)') a.text-muted.mb-0((click)='showPluginInfo(plugin)')
small {{plugin.description}} small {{plugin.description}}
@@ -28,18 +33,6 @@
i.fas.fa-fw.fa-circle-notch.fa-spin(*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}}) span Upgrade ({{knownUpgrades[plugin.name].version}})
button.btn.btn-link.text-primary.ml-2(
*ngIf='config.store.pluginBlacklist.includes(plugin.name)',
(click)='enablePlugin(plugin)'
)
i.fas.fa-fw.fa-play
button.btn.btn-link.ml-2(
*ngIf='!config.store.pluginBlacklist.includes(plugin.name)',
(click)='disablePlugin(plugin)'
)
i.fas.fa-fw.fa-pause
button.btn.btn-link.text-danger.ml-2( button.btn.btn-link.text-danger.ml-2(
(click)='uninstallPlugin(plugin)', (click)='uninstallPlugin(plugin)',
*ngIf='!plugin.isBuiltin', *ngIf='!plugin.isBuiltin',

View File

@@ -9,6 +9,8 @@ import { PluginInfo, PluginManagerService } from '../services/pluginManager.serv
enum BusyState { Installing = 'Installing', Uninstalling = 'Uninstalling' } enum BusyState { Installing = 'Installing', Uninstalling = 'Uninstalling' }
const FORCE_ENABLE = ['terminus-core', 'terminus-settings']
/** @hidden */ /** @hidden */
@Component({ @Component({
template: require('./pluginsSettingsTab.component.pug'), template: require('./pluginsSettingsTab.component.pug'),
@@ -102,6 +104,22 @@ export class PluginsSettingsTabComponent {
this.electron.shell.openExternal('https://www.npmjs.com/package/' + plugin.packageName) this.electron.shell.openExternal('https://www.npmjs.com/package/' + plugin.packageName)
} }
isPluginEnabled (plugin: PluginInfo) {
return !this.config.store.pluginBlacklist.includes(plugin.name)
}
canDisablePlugin (plugin: PluginInfo) {
return !FORCE_ENABLE.includes(plugin.packageName)
}
togglePlugin (plugin: PluginInfo) {
if (this.isPluginEnabled(plugin)) {
this.disablePlugin(plugin)
} else {
this.enablePlugin(plugin)
}
}
enablePlugin (plugin: PluginInfo) { enablePlugin (plugin: PluginInfo) {
this.config.store.pluginBlacklist = this.config.store.pluginBlacklist.filter(x => x !== plugin.name) this.config.store.pluginBlacklist = this.config.store.pluginBlacklist.filter(x => x !== plugin.name)
this.config.save() this.config.save()

View File

@@ -3,6 +3,7 @@ import { BrowserModule } from '@angular/platform-browser'
import { FormsModule } from '@angular/forms' import { FormsModule } from '@angular/forms'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap' import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import TerminusCorePlugin from 'terminus-core'
import { SettingsTabProvider } from 'terminus-settings' import { SettingsTabProvider } from 'terminus-settings'
import { PluginsSettingsTabComponent } from './components/pluginsSettingsTab.component' import { PluginsSettingsTabComponent } from './components/pluginsSettingsTab.component'
@@ -14,6 +15,7 @@ import { PluginsSettingsTabProvider } from './settings'
BrowserModule, BrowserModule,
FormsModule, FormsModule,
NgbModule, NgbModule,
TerminusCorePlugin,
], ],
providers: [ providers: [
{ provide: SettingsTabProvider, useClass: PluginsSettingsTabProvider, multi: true }, { provide: SettingsTabProvider, useClass: PluginsSettingsTabProvider, multi: true },

View File

@@ -1,56 +1,5 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'plugin-manager',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname,
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-plugin-manager:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
],
},
externals: [
'fs',
'net',
'path',
'electron-promise-ipc',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
/^terminus-/,
],
}

View File

@@ -12,12 +12,12 @@ any-promise@^1.0.0:
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
axios@^0.19.0: axios@^0.21.1:
version "0.19.2" version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
dependencies: dependencies:
follow-redirects "1.5.10" follow-redirects "^1.10.0"
call-bind@^1.0.0: call-bind@^1.0.0:
version "1.0.0" version "1.0.0"
@@ -27,13 +27,6 @@ call-bind@^1.0.0:
function-bind "^1.1.1" function-bind "^1.1.1"
get-intrinsic "^1.0.0" 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"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
define-properties@^1.1.3: define-properties@^1.1.3:
version "1.1.3" version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -78,12 +71,10 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1" is-date-object "^1.0.1"
is-symbol "^1.0.2" is-symbol "^1.0.2"
follow-redirects@1.5.10: follow-redirects@^1.10.0:
version "1.5.10" version "1.13.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.1.tgz#5f69b813376cee4fd0474a3aba835df04ab763b7"
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== integrity sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==
dependencies:
debug "=3.1.0"
function-bind@^1.1.1: function-bind@^1.1.1:
version "1.1.1" version "1.1.1"
@@ -145,10 +136,12 @@ is-symbol@^1.0.2:
dependencies: dependencies:
has-symbols "^1.0.1" has-symbols "^1.0.1"
ms@2.0.0: lru-cache@^6.0.0:
version "2.0.0" version "6.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
dependencies:
yallist "^4.0.0"
mz@^2.6.0: mz@^2.6.0:
version "2.7.0" version "2.7.0"
@@ -195,9 +188,11 @@ object.entries@^1.1.3:
has "^1.0.3" has "^1.0.3"
semver@^7.1.1: semver@^7.1.1:
version "7.3.2" version "7.3.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
dependencies:
lru-cache "^6.0.0"
serialize-error@^5.0.0: serialize-error@^5.0.0:
version "5.0.0" version "5.0.0"
@@ -245,3 +240,8 @@ uuid@^3.0.1:
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-serial", "name": "terminus-serial",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Serial connection manager for Terminus", "description": "Serial connection manager for Terminus",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -20,7 +20,10 @@
"@types/node": "14.14.14", "@types/node": "14.14.14",
"@types/ssh2": "^0.5.35", "@types/ssh2": "^0.5.35",
"ansi-colors": "^4.1.1", "ansi-colors": "^4.1.1",
"cli-spinner": "^0.2.10" "binstring": "^0.2.1",
"buffer-replace": "^1.0.0",
"cli-spinner": "^0.2.10",
"hexer": "^1.5.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/animations": "^9.1.9", "@angular/animations": "^9.1.9",

View File

@@ -1,7 +1,15 @@
import hexdump from 'hexer'
import colors from 'ansi-colors'
import binstring from 'binstring'
import stripAnsi from 'strip-ansi'
import bufferReplace from 'buffer-replace'
import { BaseSession } from 'terminus-terminal' import { BaseSession } from 'terminus-terminal'
import { SerialPort } from 'serialport' import { SerialPort } from 'serialport'
import { Logger } from 'terminus-core' import { Logger } from 'terminus-core'
import { Subject, Observable } from 'rxjs' import { Subject, Observable, interval } from 'rxjs'
import { debounce } from 'rxjs/operators'
import { ReadLine, createInterface as createReadline, clearLine } from 'readline'
import { PassThrough, Readable, Writable } from 'stream'
export interface LoginScript { export interface LoginScript {
expect: string expect: string
@@ -23,6 +31,10 @@ export interface SerialConnection {
xany: boolean xany: boolean
scripts?: LoginScript[] scripts?: LoginScript[]
color?: string color?: string
inputMode?: InputMode
inputNewlines?: NewlineMode
outputMode?: OutputMode
outputNewlines?: NewlineMode
} }
export const BAUD_RATES = [ export const BAUD_RATES = [
@@ -34,6 +46,10 @@ export interface SerialPortInfo {
description?: string description?: string
} }
export type InputMode = null | 'readline' | 'readline-hex' // eslint-disable-line @typescript-eslint/no-type-alias
export type OutputMode = null | 'hex' // eslint-disable-line @typescript-eslint/no-type-alias
export type NewlineMode = null | 'cr' | 'lf' | 'crlf' // eslint-disable-line @typescript-eslint/no-type-alias
export class SerialSession extends BaseSession { export class SerialSession extends BaseSession {
scripts?: LoginScript[] scripts?: LoginScript[]
serial: SerialPort serial: SerialPort
@@ -41,18 +57,164 @@ export class SerialSession extends BaseSession {
get serviceMessage$ (): Observable<string> { return this.serviceMessage } get serviceMessage$ (): Observable<string> { return this.serviceMessage }
private serviceMessage = new Subject<string>() private serviceMessage = new Subject<string>()
private inputReadline: ReadLine
private inputPromptVisible = true
private inputReadlineInStream: Readable & Writable
private inputReadlineOutStream: Readable & Writable
constructor (public connection: SerialConnection) { constructor (public connection: SerialConnection) {
super() super()
this.scripts = connection.scripts ?? [] this.scripts = connection.scripts ?? []
this.inputReadlineInStream = new PassThrough()
this.inputReadlineOutStream = new PassThrough()
this.inputReadline = createReadline({
input: this.inputReadlineInStream,
output: this.inputReadlineOutStream,
terminal: true,
prompt: this.connection.inputMode === 'readline-hex' ? 'hex> ' : '> ',
} as any)
this.inputReadlineOutStream.on('data', data => {
this.emitOutput(Buffer.from(data))
})
this.inputReadline.on('line', line => {
this.onInput(new Buffer(line + '\n'))
this.resetInputPrompt()
})
this.output$.pipe(debounce(() => interval(500))).subscribe(() => this.onOutputSettled())
} }
async start (): Promise<void> { async start (): Promise<void> {
this.open = true this.open = true
this.serial.on('data', data => { this.serial.on('readable', () => {
this.onOutput(this.serial.read())
})
this.serial.on('end', () => {
this.logger.info('Shell session ended')
if (this.open) {
this.destroy()
}
})
this.executeUnconditionalScripts()
}
write (data: Buffer): void {
if (this.connection.inputMode?.startsWith('readline')) {
this.inputReadlineInStream.write(data)
} else {
this.onInput(data)
}
}
async destroy (): Promise<void> {
this.serviceMessage.complete()
this.inputReadline.close()
await super.destroy()
}
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-empty-function
resize (_, __) {
this.inputReadlineOutStream.emit('resize')
}
kill (_?: string): void {
this.serial.close()
}
emitServiceMessage (msg: string): void {
this.serviceMessage.next(msg)
this.logger.info(stripAnsi(msg))
}
async getChildProcesses (): Promise<any[]> {
return []
}
async gracefullyKillProcess (): Promise<void> {
this.kill('TERM')
}
supportsWorkingDirectory (): boolean {
return false
}
async getWorkingDirectory (): Promise<string|null> {
return null
}
private replaceNewlines (data: Buffer, mode?: NewlineMode): Buffer {
if (!mode) {
return data
}
data = bufferReplace(data, '\r\n', '\n')
data = bufferReplace(data, '\r', '\n')
const replacement = {
strip: '',
cr: '\r',
lf: '\n',
crlf: '\r\n',
}[mode]
return bufferReplace(data, '\n', replacement)
}
private onInput (data: Buffer) {
if (this.connection.inputMode === 'readline-hex') {
const tokens = data.toString().split(/\s/g)
data = Buffer.concat(tokens.filter(t => !!t).map(t => {
if (t.startsWith('0x')) {
t = t.substring(2)
}
return binstring(t, { 'in': 'hex' })
}))
}
data = this.replaceNewlines(data, this.connection.inputNewlines)
if (this.serial) {
this.serial.write(data.toString())
}
}
private onOutputSettled () {
if (this.connection.inputMode?.startsWith('readline') && !this.inputPromptVisible) {
this.resetInputPrompt()
}
}
private resetInputPrompt () {
this.emitOutput(new Buffer('\r\n'))
this.inputReadline.prompt(true)
this.inputPromptVisible = true
}
private onOutput (data: Buffer) {
const dataString = data.toString() const dataString = data.toString()
if (this.connection.inputMode?.startsWith('readline')) {
if (this.inputPromptVisible) {
clearLine(this.inputReadlineOutStream, 0)
this.inputPromptVisible = false
}
}
data = this.replaceNewlines(data, this.connection.outputNewlines)
if (this.connection.outputMode === 'hex') {
this.emitOutput(Buffer.concat([
new Buffer('\r\n'),
Buffer.from(hexdump(data, {
group: 1,
gutter: 4,
divide: colors.gray(' '),
emptyHuman: colors.gray(''),
}).replace(/\n/g, '\r\n')),
new Buffer('\r\n\n'),
]))
} else {
this.emitOutput(data) this.emitOutput(data)
}
if (this.scripts) { if (this.scripts) {
let found = false let found = false
@@ -61,7 +223,7 @@ export class SerialSession extends BaseSession {
let cmd = '' let cmd = ''
if (script.isRegex) { if (script.isRegex) {
const re = new RegExp(script.expect, 'g') const re = new RegExp(script.expect, 'g')
if (dataString.match(re)) { if (re.test(dataString)) {
cmd = dataString.replace(re, script.send) cmd = dataString.replace(re, script.send)
match = true match = true
found = true found = true
@@ -93,46 +255,6 @@ export class SerialSession extends BaseSession {
this.executeUnconditionalScripts() this.executeUnconditionalScripts()
} }
} }
})
this.serial.on('end', () => {
this.logger.info('Shell session ended')
if (this.open) {
this.destroy()
}
})
this.executeUnconditionalScripts()
}
write (data: Buffer): void {
if (this.serial) {
this.serial.write(data.toString())
}
}
async destroy (): Promise<void> {
this.serviceMessage.complete()
await super.destroy()
}
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-empty-function
resize (_, __) { }
kill (_?: string): void {
this.serial.close()
}
async getChildProcesses (): Promise<any[]> {
return []
}
async gracefullyKillProcess (): Promise<void> {
this.kill('TERM')
}
async getWorkingDirectory (): Promise<string|null> {
return null
} }
private executeUnconditionalScripts () { private executeUnconditionalScripts () {

View File

@@ -11,6 +11,8 @@
[(ngModel)]='connection.name', [(ngModel)]='connection.name',
) )
.row
.col-6
.form-group .form-group
label Path label Path
input.form-control( input.form-control(
@@ -20,6 +22,7 @@
[resultFormatter]='portsFormatter', [resultFormatter]='portsFormatter',
) )
.col-6
.form-group .form-group
label Baud Rate label Baud Rate
select.form-control( select.form-control(
@@ -27,6 +30,66 @@
) )
option([value]='x', *ngFor='let x of baudRates') {{x}} option([value]='x', *ngFor='let x of baudRates') {{x}}
.row
.col-6
.form-line
.header
.title Input mode
.d-flex(ngbDropdown)
button.btn.btn-secondary.btn-tab-bar(
ngbDropdownToggle,
) {{getInputModeName(connection.inputMode)}}
div(ngbDropdownMenu)
a.d-flex.flex-column(
*ngFor='let mode of inputModes',
(click)='connection.inputMode = mode.key',
ngbDropdownItem
)
div {{mode.name}}
.text-muted {{mode.description}}
.col-6
.form-line
.header
.title Input newlines
select.form-control(
[(ngModel)]='connection.inputNewlines',
)
option([ngValue]='mode.key', *ngFor='let mode of newlineModes') {{mode.name}}
.row
.col-6
.form-line
.header
.title Output mode
.d-flex(ngbDropdown)
button.btn.btn-secondary.btn-tab-bar(
ngbDropdownToggle,
) {{getOutputModeName(connection.outputMode)}}
div(ngbDropdownMenu)
a.d-flex.flex-column(
*ngFor='let mode of outputModes',
(click)='connection.outputMode = mode.key',
ngbDropdownItem
)
div {{mode.name}}
.text-muted {{mode.description}}
.col-6
.form-line
.header
.title Output newlines
select.form-control(
[(ngModel)]='connection.outputNewlines',
)
option([ngValue]='mode.key', *ngFor='let mode of newlineModes') {{mode.name}}
ngb-tab(id='advanced') ngb-tab(id='advanced')
ng-template(ngbTabTitle) Advanced ng-template(ngbTabTitle) Advanced
ng-template(ngbTabContent) ng-template(ngbTabContent)

View File

@@ -15,6 +15,22 @@ export class EditConnectionModalComponent {
connection: SerialConnection connection: SerialConnection
foundPorts: SerialPortInfo[] foundPorts: SerialPortInfo[]
baudRates = BAUD_RATES baudRates = BAUD_RATES
inputModes = [
{ key: null, name: 'Normal', description: 'Input is sent as you type' },
{ key: 'readline', name: 'Line by line', description: 'Line editor, input is sent after you press Enter' },
{ key: 'readline-hex', name: 'Hexadecimal', description: 'Send bytes by typing in hex values' },
]
outputModes = [
{ key: null, name: 'Normal', description: 'Output is shown as it is received' },
{ key: 'hex', name: 'Hexadecimal', description: 'Output is shown as a hexdump' },
]
newlineModes = [
{ key: null, name: 'Keep' },
{ key: 'strip', name: 'Strip' },
{ key: 'cr', name: 'Force CR' },
{ key: 'lf', name: 'Force LF' },
{ key: 'crlf', name: 'Force CRLF' },
]
constructor ( constructor (
private modalInstance: NgbActiveModal, private modalInstance: NgbActiveModal,
@@ -24,6 +40,14 @@ export class EditConnectionModalComponent {
) { ) {
} }
getInputModeName (key) {
return this.inputModes.find(x => x.key === key)?.name
}
getOutputModeName (key) {
return this.outputModes.find(x => x.key === key)?.name
}
portsAutocomplete = text$ => text$.pipe(map(() => { portsAutocomplete = text$ => text$.pipe(map(() => {
return this.foundPorts.map(x => x.name) return this.foundPorts.map(x => x.name)
})) }))

View File

@@ -34,6 +34,10 @@ export class SerialSettingsTabComponent {
xany: false, xany: false,
xoff: false, xoff: false,
xon: false, xon: false,
inputMode: null,
outputMode: null,
inputNewlines: null,
outputNewlines: null,
} }
const modal = this.ngbModal.open(EditConnectionModalComponent) const modal = this.ngbModal.open(EditConnectionModalComponent)

View File

@@ -1,16 +1,16 @@
.tab-toolbar .tab-toolbar([class.show]='!session || !session.open')
.btn.btn-outline-secondary.reveal-button .btn.btn-outline-secondary.reveal-button
i.fas.fa-ellipsis-h i.fas.fa-ellipsis-h
.toolbar(*ngIf='session', [class.show]='!session.open') .toolbar
i.fas.fa-circle.text-success.mr-2(*ngIf='session.open') i.fas.fa-circle.text-success.mr-2(*ngIf='session && session.open')
i.fas.fa-circle.text-danger.mr-2(*ngIf='!session.open') i.fas.fa-circle.text-danger.mr-2(*ngIf='!session || !session.open')
strong(*ngIf='session') {{session.connection.port}} ({{session.connection.baudrate}}) strong {{connection.port}} ({{connection.baudrate}})
.mr-auto .mr-auto
button.btn.btn-secondary.mr-3((click)='changeBaudRate()', *ngIf='session.open') button.btn.btn-secondary.mr-3((click)='changeBaudRate()', *ngIf='session && session.open')
span Change baud rate span Change baud rate
button.btn.btn-info((click)='reconnect()', *ngIf='!session.open') button.btn.btn-info((click)='reconnect()', *ngIf='!session || !session.open')
i.fas.fa-reload i.fas.fa-reload
span Reconnect span Reconnect

View File

@@ -11,14 +11,15 @@ import { Subscription } from 'rxjs'
/** @hidden */ /** @hidden */
@Component({ @Component({
selector: 'serial-tab', selector: 'serial-tab',
template: BaseTerminalTabComponent.template + (require('./serialTab.component.pug') as string), template: `${BaseTerminalTabComponent.template} ${require('./serialTab.component.pug')}`,
styles: [require('./serialTab.component.scss'), ...BaseTerminalTabComponent.styles], styles: [require('./serialTab.component.scss'), ...BaseTerminalTabComponent.styles],
animations: BaseTerminalTabComponent.animations, animations: BaseTerminalTabComponent.animations,
}) })
export class SerialTabComponent extends BaseTerminalTabComponent { export class SerialTabComponent extends BaseTerminalTabComponent {
connection?: SerialConnection connection?: SerialConnection
session?: SerialSession session: SerialSession|null = null
serialPort: any serialPort: any
private serialService: SerialService
private homeEndSubscription: Subscription private homeEndSubscription: Subscription
// eslint-disable-next-line @typescript-eslint/no-useless-constructor // eslint-disable-next-line @typescript-eslint/no-useless-constructor
@@ -26,6 +27,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
injector: Injector, injector: Injector,
) { ) {
super(injector) super(injector)
this.serialService = injector.get(SerialService)
} }
ngOnInit () { ngOnInit () {
@@ -42,6 +44,9 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
case 'end': case 'end':
this.sendInput('\x1b[F' ) this.sendInput('\x1b[F' )
break break
case 'restart-serial-session':
this.reconnect()
break
} }
}) })
@@ -62,12 +67,8 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
return return
} }
this.session = this.injector.get(SerialService).createSession(this.connection) const session = this.serialService.createSession(this.connection)
this.session.serviceMessage$.subscribe(msg => { this.setSession(session)
this.write(`\r\n${colors.black.bgWhite(' serial ')} ${msg}\r\n`)
this.session?.resize(this.size.columns, this.size.rows)
})
this.attachSessionHandlers()
this.write(`Connecting to `) this.write(`Connecting to `)
const spinner = new Spinner({ const spinner = new Spinner({
@@ -80,15 +81,32 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
spinner.start() spinner.start()
try { try {
this.serialPort = await this.injector.get(SerialService).connectSession(this.session) this.serialPort = await this.serialService.connectSession(this.session!)
spinner.stop(true) spinner.stop(true)
session.emitServiceMessage('Port opened')
} catch (e) { } catch (e) {
spinner.stop(true) spinner.stop(true)
this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n') this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n')
return return
} }
await this.session.start() await this.session!.start()
this.session.resize(this.size.columns, this.size.rows) this.session!.resize(this.size.columns, this.size.rows)
}
protected attachSessionHandlers () {
this.attachSessionHandler(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.attachSessionHandler(this.session!.destroyed$.subscribe(() => {
this.write('Press any key to reconnect\r\n')
this.input$.pipe(first()).subscribe(() => {
if (!this.session?.open) {
this.reconnect()
}
})
}))
super.attachSessionHandlers()
} }
async getRecoveryToken (): Promise<any> { async getRecoveryToken (): Promise<any> {
@@ -99,8 +117,10 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
} }
} }
reconnect () { async reconnect (): Promise<void> {
this.initializeSession() this.session?.destroy()
await this.initializeSession()
this.session?.releaseInitialDataBuffer()
} }
async changeBaudRate () { async changeBaudRate () {

View File

@@ -12,6 +12,7 @@ export class SerialConfigProvider extends ConfigProvider {
serial: [ serial: [
'Alt-K', 'Alt-K',
], ],
'restart-serial-session': [],
}, },
} }

View File

@@ -9,6 +9,10 @@ export class SerialHotkeyProvider extends HotkeyProvider {
id: 'serial', id: 'serial',
name: 'Show Serial connections', name: 'Show Serial connections',
}, },
{
id: 'restart-serial-session',
name: 'Restart current serial session',
},
] ]
async provide (): Promise<HotkeyDescription[]> { async provide (): Promise<HotkeyDescription[]> {

View File

@@ -1,7 +1,6 @@
import { Injectable, NgZone } from '@angular/core' import { Injectable, NgZone } from '@angular/core'
import SerialPort from 'serialport' import SerialPort from 'serialport'
import { ToastrService } from 'ngx-toastr' import { LogService, AppService, SelectorOption, ConfigService, NotificationsService } from 'terminus-core'
import { LogService, AppService, SelectorOption, ConfigService } from 'terminus-core'
import { SettingsTabComponent } from 'terminus-settings' import { SettingsTabComponent } from 'terminus-settings'
import { SerialConnection, SerialSession, SerialPortInfo, BAUD_RATES } from '../api' import { SerialConnection, SerialSession, SerialPortInfo, BAUD_RATES } from '../api'
import { SerialTabComponent } from '../components/serialTab.component' import { SerialTabComponent } from '../components/serialTab.component'
@@ -11,7 +10,7 @@ export class SerialService {
private constructor ( private constructor (
private log: LogService, private log: LogService,
private zone: NgZone, private zone: NgZone,
private toastr: ToastrService, private notifications: NotificationsService,
private app: AppService, private app: AppService,
private config: ConfigService, private config: ConfigService,
) { } ) { }
@@ -30,10 +29,17 @@ export class SerialService {
} }
async connectSession (session: SerialSession): Promise<SerialPort> { async connectSession (session: SerialSession): Promise<SerialPort> {
const serial = new SerialPort(session.connection.port, { autoOpen: false, baudRate: session.connection.baudrate, const serial = new SerialPort(session.connection.port, {
dataBits: session.connection.databits, stopBits: session.connection.stopbits, parity: session.connection.parity, autoOpen: false,
rtscts: session.connection.rtscts, xon: session.connection.xon, xoff: session.connection.xoff, baudRate: parseInt(session.connection.baudrate as any),
xany: session.connection.xany }) dataBits: session.connection.databits,
stopBits: session.connection.stopbits,
parity: session.connection.parity,
rtscts: session.connection.rtscts,
xon: session.connection.xon,
xoff: session.connection.xoff,
xany: session.connection.xany,
})
session.serial = serial session.serial = serial
let connected = false let connected = false
await new Promise(async (resolve, reject) => { await new Promise(async (resolve, reject) => {
@@ -44,17 +50,21 @@ export class SerialService {
serial.on('error', error => { serial.on('error', error => {
this.zone.run(() => { this.zone.run(() => {
if (connected) { if (connected) {
this.toastr.error(error.toString()) this.notifications.error(error.toString())
} else { } else {
reject(error) reject(error)
} }
}) })
}) })
serial.on('close', () => {
session.emitServiceMessage('Port closed')
session.destroy()
})
try { try {
serial.open() serial.open()
} catch (e) { } catch (e) {
this.toastr.error(e.message) this.notifications.error(e.message)
reject(e) reject(e)
} }
}) })
@@ -103,7 +113,7 @@ export class SerialService {
options.push({ options.push({
name: 'Manage connections', name: 'Manage connections',
icon: 'cog', icon: 'cog',
callback: () => this.app.openNewTab(SettingsTabComponent, { activeTab: 'serial' }), callback: () => this.app.openNewTabRaw(SettingsTabComponent, { activeTab: 'serial' }),
}) })
options.push({ options.push({
@@ -131,7 +141,7 @@ export class SerialService {
}) })
return tab return tab
} catch (error) { } catch (error) {
this.toastr.error(`Could not connect: ${error}`) this.notifications.error(`Could not connect: ${error}`)
throw error throw error
} }
} }

View File

@@ -1,59 +1,5 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'serial',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname,
devtool: 'source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-serial:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js', '.node'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
{ test: /\.svg/, use: ['svg-inline-loader'] },
],
},
externals: [
'fs',
'keytar',
'path',
'ngx-toastr',
'serialport',
'windows-process-tree/build/Release/windows_process_tree.node',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
/^terminus-/,
],
}

View File

@@ -27,12 +27,52 @@
"@types/node" "*" "@types/node" "*"
"@types/ssh2-streams" "*" "@types/ssh2-streams" "*"
ansi-color@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/ansi-color/-/ansi-color-0.2.1.tgz#3e75c037475217544ed763a8db5709fa9ae5bf9a"
integrity sha1-PnXAN0dSF1RO12Oo21cJ+prlv5o=
ansi-colors@^4.1.1: ansi-colors@^4.1.1:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
binstring@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/binstring/-/binstring-0.2.1.tgz#8a174d301f6d54efda550dd98bb4cb524eacd75d"
integrity sha1-ihdNMB9tVO/aVQ3Zi7TLUk6s110=
buffer-replace@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-replace/-/buffer-replace-1.0.0.tgz#bc427c40af4c1f06d6933dede57110acba8ade54"
integrity sha1-vEJ8QK9MHwbWkz3t5XEQrLqK3lQ=
cli-spinner@^0.2.10: cli-spinner@^0.2.10:
version "0.2.10" version "0.2.10"
resolved "https://registry.yarnpkg.com/cli-spinner/-/cli-spinner-0.2.10.tgz#f7d617a36f5c47a7bc6353c697fc9338ff782a47" resolved "https://registry.yarnpkg.com/cli-spinner/-/cli-spinner-0.2.10.tgz#f7d617a36f5c47a7bc6353c697fc9338ff782a47"
integrity sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q== integrity sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q==
hexer@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/hexer/-/hexer-1.5.0.tgz#b86ce808598e8a9d1892c571f3cedd86fc9f0653"
integrity sha1-uGzoCFmOip0YksVx887dhvyfBlM=
dependencies:
ansi-color "^0.2.1"
minimist "^1.1.0"
process "^0.10.0"
xtend "^4.0.0"
minimist@^1.1.0:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
process@^0.10.0:
version "0.10.1"
resolved "https://registry.yarnpkg.com/process/-/process-0.10.1.tgz#842457cc51cfed72dc775afeeafb8c6034372725"
integrity sha1-hCRXzFHP7XLcd1r+6vuMYDQ3JyU=
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==

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-settings", "name": "terminus-settings",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Terminus terminal settings page", "description": "Terminus terminal settings page",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -17,7 +17,8 @@
"author": "Eugene Pankov", "author": "Eugene Pankov",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/deep-equal": "1.0.1" "@types/deep-equal": "1.0.1",
"utils-decorators": "^1.8.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/animations": "^9.1.9", "@angular/animations": "^9.1.9",

View File

@@ -6,12 +6,13 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
i.fas.fa-fw.fa-window-maximize.mr-2 i.fas.fa-fw.fa-window-maximize.mr-2
| Application | Application
ng-template(ngbTabContent) ng-template(ngbTabContent)
.d-flex.align-items-center.mb-4 .d-flex.align-items-center.flex-wrap.mb-4
h1.terminus-title.mb-2.mr-2 Terminus h1.terminus-title.mb-2.mr-2 Terminus
sup α sup α
.text-muted.mr-auto {{homeBase.appVersion}} .text-muted.mr-auto {{homeBase.appVersion}}
div
button.btn.btn-secondary.mr-3((click)='homeBase.openGitHub()') button.btn.btn-secondary.mr-3((click)='homeBase.openGitHub()')
i.fab.fa-github i.fab.fa-github
span GitHub span GitHub
@@ -25,7 +26,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.title Theme .title Theme
select.form-control( select.form-control(
[(ngModel)]='config.store.appearance.theme', [(ngModel)]='config.store.appearance.theme',
(ngModelChange)='config.save()', (ngModelChange)='saveConfiguration()',
) )
option(*ngFor='let theme of themes', [ngValue]='theme.name') {{theme.name}} option(*ngFor='let theme of themes', [ngValue]='theme.name') {{theme.name}}
@@ -34,7 +35,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.title Tabs location .title Tabs location
.btn-group( .btn-group(
[(ngModel)]='config.store.appearance.tabsLocation', [(ngModel)]='config.store.appearance.tabsLocation',
(ngModelChange)='config.save()', (ngModelChange)='saveConfiguration()',
ngbRadioGroup ngbRadioGroup
) )
label.btn.btn-secondary(ngbButtonLabel) label.btn.btn-secondary(ngbButtonLabel)
@@ -66,6 +67,29 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
) )
| Right | Right
.form-line
.header
.title Tabs width
.btn-group(
[(ngModel)]='config.store.appearance.flexTabs',
(ngModelChange)='saveConfiguration()',
ngbRadioGroup
)
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='true'
)
| Dynamic
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='false'
)
| Fixed
.form-line .form-line
.header .header
.title(*ngIf='hostApp.platform !== Platform.macOS') Acrylic background .title(*ngIf='hostApp.platform !== Platform.macOS') Acrylic background
@@ -74,7 +98,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
toggle( toggle(
[(ngModel)]='config.store.appearance.vibrancy', [(ngModel)]='config.store.appearance.vibrancy',
(ngModelChange)='config.save()' (ngModelChange)='saveConfiguration()'
) )
.form-line(*ngIf='config.store.appearance.vibrancy && isFluentVibrancySupported') .form-line(*ngIf='config.store.appearance.vibrancy && isFluentVibrancySupported')
@@ -82,7 +106,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.title Background type .title Background type
.btn-group( .btn-group(
[(ngModel)]='config.store.appearance.vibrancyType', [(ngModel)]='config.store.appearance.vibrancyType',
(ngModelChange)='config.save()', (ngModelChange)='saveConfiguration()',
ngbRadioGroup ngbRadioGroup
) )
label.btn.btn-secondary(ngbButtonLabel) label.btn.btn-secondary(ngbButtonLabel)
@@ -106,7 +130,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
input( input(
type='range', type='range',
[(ngModel)]='config.store.appearance.opacity', [(ngModel)]='config.store.appearance.opacity',
(ngModelChange)='config.save(); (hostApp.platform === Platform.Linux && config.requestRestart())', (ngModelChange)='saveConfiguration(); (hostApp.platform === Platform.Linux && config.requestRestart())',
min='0.4', min='0.4',
max='1', max='1',
step='0.01' step='0.01'
@@ -125,7 +149,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.btn-group( .btn-group(
[(ngModel)]='config.store.appearance.frame', [(ngModel)]='config.store.appearance.frame',
(ngModelChange)='config.save(); config.requestRestart()', (ngModelChange)='saveConfiguration(true)',
ngbRadioGroup ngbRadioGroup
) )
label.btn.btn-secondary(ngbButtonLabel) label.btn.btn-secondary(ngbButtonLabel)
@@ -157,7 +181,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.btn-group( .btn-group(
[(ngModel)]='config.store.appearance.dock', [(ngModel)]='config.store.appearance.dock',
(ngModelChange)='config.save(); docking.dock()', (ngModelChange)='saveConfiguration(); docking.dock()',
ngbRadioGroup ngbRadioGroup
) )
label.btn.btn-secondary(ngbButtonLabel) label.btn.btn-secondary(ngbButtonLabel)
@@ -196,14 +220,14 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
) )
| Bottom | Bottom
.form-line(*ngIf='config.store.appearance.dock != "off"') .ml-5.form-line(*ngIf='config.store.appearance.dock != "off"')
.header .header
.title Display on .title Display on
.description Snaps the window to a side of the screen .description Snaps the window to a side of the screen
div( div(
[(ngModel)]='config.store.appearance.dockScreen', [(ngModel)]='config.store.appearance.dockScreen',
(ngModelChange)='config.save(); docking.dock()', (ngModelChange)='saveConfiguration(); docking.dock()',
ngbRadioGroup ngbRadioGroup
) )
label.btn.btn-secondary(ngbButtonLabel) label.btn.btn-secondary(ngbButtonLabel)
@@ -221,34 +245,46 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
) )
| {{screen.name}} | {{screen.name}}
.form-line(*ngIf='config.store.appearance.dock != "off"') .ml-5.form-line(*ngIf='config.store.appearance.dock != "off"')
.header .header
.title Dock always on top .title Dock always on top
.description Keep docked terminal always on top .description Keep docked terminal always on top
toggle( toggle(
[(ngModel)]='config.store.appearance.dockAlwaysOnTop', [(ngModel)]='config.store.appearance.dockAlwaysOnTop',
(ngModelChange)='config.save(); docking.dock()', (ngModelChange)='saveConfiguration(); docking.dock()',
) )
.form-line(*ngIf='config.store.appearance.dock != "off"') .ml-5.form-line(*ngIf='config.store.appearance.dock != "off"')
.header .header
.title Docked terminal size .title Docked terminal size
input( input(
type='range', type='range',
[(ngModel)]='config.store.appearance.dockFill', [(ngModel)]='config.store.appearance.dockFill',
(mouseup)='config.save(); docking.dock()', (mouseup)='saveConfiguration(); docking.dock()',
min='0.05', min='0.05',
max='1', max='1',
step='0.01' step='0.01'
) )
.form-line(*ngIf='config.store.appearance.dock != "off"') .ml-5.form-line(*ngIf='config.store.appearance.dock != "off"')
.header
.title Docked terminal space
input(
type='range',
[(ngModel)]='config.store.appearance.dockSpace',
(mouseup)='saveConfiguration(); docking.dock()',
min='0.2',
max='1',
step='0.01'
)
.ml-5.form-line(*ngIf='config.store.appearance.dock != "off"')
.header .header
.title Hide dock on blur .title Hide dock on blur
.description Hides the docked terminal when you click away. .description Hides the docked terminal when you click away.
toggle( toggle(
[(ngModel)]='config.store.appearance.dockHideOnBlur', [(ngModel)]='config.store.appearance.dockHideOnBlur',
(ngModelChange)='config.save(); ', (ngModelChange)='saveConfiguration(); ',
) )
.form-line .form-line
@@ -265,21 +301,21 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.description We're only tracking your Terminus and OS versions. .description We're only tracking your Terminus and OS versions.
toggle( toggle(
[(ngModel)]='config.store.enableAnalytics', [(ngModel)]='config.store.enableAnalytics',
(ngModelChange)='config.save(); config.requestRestart()', (ngModelChange)='saveConfiguration(true)',
) )
.form-line .form-line
.header .header
.title Automatic Updates .title Automatic Updates
.description Enable automatic installation of updates when they become available. .description Enable automatic installation of updates when they become available.
toggle([(ngModel)]='config.store.enableAutomaticUpdates', (ngModelChange)='config.save()') toggle([(ngModel)]='config.store.enableAutomaticUpdates', (ngModelChange)='saveConfiguration()')
.form-line .form-line
.header .header
.title Custom CSS .title Custom CSS
textarea.form-control( textarea.form-control(
[(ngModel)]='config.store.appearance.css', [(ngModel)]='config.store.appearance.css',
(ngModelChange)='config.save()', (ngModelChange)='saveConfiguration()',
) )
ngb-tab(id='hotkeys') ngb-tab(id='hotkeys')
@@ -308,7 +344,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
td.pr-5 td.pr-5
multi-hotkey-input( multi-hotkey-input(
[model]='getHotkey(hotkey.id) || []', [model]='getHotkey(hotkey.id) || []',
(modelChange)='setHotkey(hotkey.id, $event); config.save(); docking.dock()' (modelChange)='setHotkey(hotkey.id, $event); saveConfiguration(); docking.dock()'
) )
ngb-tab(*ngFor='let provider of settingsProviders', [id]='provider.id') ngb-tab(*ngFor='let provider of settingsProviders', [id]='provider.id')
@@ -327,7 +363,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.d-flex.flex-column.w-100.h-100 .d-flex.flex-column.w-100.h-100
.h-100.d-flex .h-100.d-flex
.w-100.d-flex.flex-column .w-100.d-flex.flex-column
h3 Config file h3 Config File
textarea.form-control.h-100( textarea.form-control.h-100(
[(ngModel)]='configFile' [(ngModel)]='configFile'
) )

View File

@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import * as yaml from 'js-yaml' import * as yaml from 'js-yaml'
import { debounce } from 'utils-decorators/dist/cjs'
import { Subscription } from 'rxjs' import { Subscription } from 'rxjs'
import { Component, Inject, Input, HostBinding, NgZone } from '@angular/core' import { Component, Inject, Input, HostBinding, NgZone } from '@angular/core'
import { import {
@@ -60,7 +61,7 @@ export class SettingsTabComponent extends BaseTabComponent {
this.settingsProviders = config.enabledServices(this.settingsProviders) this.settingsProviders = config.enabledServices(this.settingsProviders)
this.themes = config.enabledServices(this.themes) this.themes = config.enabledServices(this.themes)
this.configDefaults = yaml.safeDump(config.getDefaults()) this.configDefaults = yaml.dump(config.getDefaults())
const onConfigChange = () => { const onConfigChange = () => {
this.configFile = config.readRaw() this.configFile = config.readRaw()
@@ -104,6 +105,14 @@ export class SettingsTabComponent extends BaseTabComponent {
this.hostApp.relaunch() this.hostApp.relaunch()
} }
@debounce(500)
saveConfiguration (requireRestart?: boolean) {
this.config.save()
if (requireRestart) {
this.config.requestRestart()
}
}
saveConfigFile () { saveConfigFile () {
if (this.isConfigFileValid()) { if (this.isConfigFileValid()) {
this.config.writeRaw(this.configFile) this.config.writeRaw(this.configFile)
@@ -116,7 +125,7 @@ export class SettingsTabComponent extends BaseTabComponent {
isConfigFileValid () { isConfigFileValid () {
try { try {
yaml.safeLoad(this.configFile) yaml.load(this.configFile)
return true return true
} catch (_) { } catch (_) {
return false return false

View File

@@ -1,57 +1,5 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'settings',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname,
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-settings:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
{ test: /\.css$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
{ test: /\.svg/, use: ['svg-inline-loader'] },
],
},
externals: [
'fs',
'path',
'os',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
/^terminus-/,
],
}

View File

@@ -6,3 +6,15 @@
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.1.tgz#71cfabb247c22bcc16d536111f50c0ed12476b03" resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.1.tgz#71cfabb247c22bcc16d536111f50c0ed12476b03"
integrity sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg== integrity sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg==
tinyqueue@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-2.0.3.tgz#64d8492ebf39e7801d7bd34062e29b45b2035f08"
integrity sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==
utils-decorators@^1.8.0:
version "1.8.1"
resolved "https://registry.yarnpkg.com/utils-decorators/-/utils-decorators-1.8.1.tgz#6e7e2cf46c05a9554c05f004e5235696142bd5f7"
integrity sha512-UpqzJj40jdTknZpxdeYL7p+8Ynl3bpHP6yoxoY+RmuDCOaelTiOz4GcDpScPvfZhv/ivHTV1bPJZeQd8tlxczA==
dependencies:
tinyqueue "^2.0.3"

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-ssh", "name": "terminus-ssh",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.1",
"description": "SSH connection manager for Terminus", "description": "SSH connection manager for Terminus",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -21,11 +21,10 @@
"author": "Eugene Pankov", "author": "Eugene Pankov",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/node": "14.14.14", "@types/node": "14.14.31",
"@types/ssh2": "^0.5.35", "@types/ssh2": "^0.5.35",
"ansi-colors": "^4.1.1", "ansi-colors": "^4.1.1",
"cli-spinner": "^0.2.10", "cli-spinner": "^0.2.10",
"run-script-os": "^1.1.3",
"ssh2": "^0.8.9", "ssh2": "^0.8.9",
"ssh2-streams": "Eugeny/ssh2-streams#75f6d3425d071ac73a18fd46e2f5e738bfe897c5", "ssh2-streams": "Eugeny/ssh2-streams#75f6d3425d071ac73a18fd46e2f5e738bfe897c5",
"sshpk": "^1.16.1", "sshpk": "^1.16.1",
@@ -33,6 +32,7 @@
"temp": "^0.9.1" "temp": "^0.9.1"
}, },
"dependencies": { "dependencies": {
"run-script-os": "^1.1.3",
"socksv5": "^0.0.6" "socksv5": "^0.0.6"
}, },
"peerDependencies": { "peerDependencies": {

View File

@@ -140,6 +140,9 @@ export class SSHSession extends BaseSession {
this.shell = await this.openShellChannel({ x11: this.connection.x11 }) this.shell = await this.openShellChannel({ x11: this.connection.x11 })
} catch (err) { } catch (err) {
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote rejected opening a shell channel: ${err}`) this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote rejected opening a shell channel: ${err}`)
if (err.toString().includes('Unable to request X11')) {
this.emitServiceMessage(' Make sure `xauth` is installed on the remote side')
}
return return
} }
@@ -245,7 +248,13 @@ export class SSHSession extends BaseSession {
} }
socket.on('error', e => { socket.on('error', e => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string // 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}`) this.emitServiceMessage(colors.bgRed.black(' X ') + ` Could not connect to the X server: ${e}`)
this.emitServiceMessage(` Terminus tried to connect to ${xHost}:${xPort} based on the DISPLAY environment var (${displaySpec})`)
if (process.platform === 'win32') {
this.emitServiceMessage(' To use X forwarding, you need a local X server, e.g.:')
this.emitServiceMessage(' * VcXsrv: https://sourceforge.net/projects/vcxsrv/')
this.emitServiceMessage(' * Xming: https://sourceforge.net/projects/xming/')
}
reject() reject()
}) })
socket.on('connect', () => { socket.on('connect', () => {
@@ -363,6 +372,10 @@ export class SSHSession extends BaseSession {
this.kill('TERM') this.kill('TERM')
} }
supportsWorkingDirectory (): boolean {
return true
}
async getWorkingDirectory (): Promise<string|null> { async getWorkingDirectory (): Promise<string|null> {
return null return null
} }
@@ -398,3 +411,9 @@ export interface SSHConnectionGroup {
name: string name: string
connections: SSHConnection[] connections: SSHConnection[]
} }
export const ALGORITHM_BLACKLIST = [
// cause native crashes in node crypto, use EC instead
'diffie-hellman-group-exchange-sha256',
'diffie-hellman-group-exchange-sha1',
]

View File

@@ -103,7 +103,7 @@
.header .header
.title Jump host .title Jump host
select.form-control([(ngModel)]='connection.jumpHost') select.form-control([(ngModel)]='connection.jumpHost')
option([ngValue]='null') None option(value='') None
option([ngValue]='x.name', *ngFor='let x of config.store.ssh.connections') {{x.name}} option([ngValue]='x.name', *ngFor='let x of config.store.ssh.connections') {{x.name}}
.form-line .form-line

View File

@@ -3,7 +3,7 @@ import { Component } from '@angular/core'
import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { ElectronService, HostAppService, ConfigService } from 'terminus-core' import { ElectronService, HostAppService, ConfigService } from 'terminus-core'
import { PasswordStorageService } from '../services/passwordStorage.service' import { PasswordStorageService } from '../services/passwordStorage.service'
import { SSHConnection, LoginScript, SSHAlgorithmType } from '../api' import { SSHConnection, LoginScript, SSHAlgorithmType, ALGORITHM_BLACKLIST } from '../api'
import { PromptModalComponent } from './promptModal.component' import { PromptModalComponent } from './promptModal.component'
import { ALGORITHMS } from 'ssh2-streams/lib/constants' import { ALGORITHMS } from 'ssh2-streams/lib/constants'
@@ -40,8 +40,8 @@ export class EditConnectionModalComponent {
[SSHAlgorithmType.CIPHER]: 'CIPHER', [SSHAlgorithmType.CIPHER]: 'CIPHER',
[SSHAlgorithmType.HMAC]: 'HMAC', [SSHAlgorithmType.HMAC]: 'HMAC',
}[k] }[k]
this.supportedAlgorithms[k] = ALGORITHMS[supportedAlg] this.supportedAlgorithms[k] = ALGORITHMS[supportedAlg].filter(x => !ALGORITHM_BLACKLIST.includes(x))
this.defaultAlgorithms[k] = ALGORITHMS[defaultAlg] this.defaultAlgorithms[k] = ALGORITHMS[defaultAlg].filter(x => !ALGORITHM_BLACKLIST.includes(x))
} }
} }

View File

@@ -1,14 +1,14 @@
.tab-toolbar .tab-toolbar([class.show]='!session || !session.open')
.btn.btn-outline-secondary.reveal-button .btn.btn-outline-secondary.reveal-button
i.fas.fa-ellipsis-h i.fas.fa-ellipsis-h
.toolbar(*ngIf='session', [class.show]='!session.open') .toolbar
i.fas.fa-circle.text-success.mr-2(*ngIf='session.open') i.fas.fa-circle.text-success.mr-2(*ngIf='session && session.open')
i.fas.fa-circle.text-danger.mr-2(*ngIf='!session.open') i.fas.fa-circle.text-danger.mr-2(*ngIf='!session || !session.open')
strong.mr-auto(*ngIf='session') {{session.connection.user}}@{{session.connection.host}}:{{session.connection.port}} strong.mr-auto {{connection.user}}@{{connection.host}}:{{connection.port}}
button.btn.btn-secondary.mr-2((click)='reconnect()', [class.btn-info]='!session.open') button.btn.btn-secondary.mr-2((click)='reconnect()', [class.btn-info]='!session || !session.open')
span Reconnect span Reconnect
button.btn.btn-secondary((click)='showPortForwarding()', *ngIf='session.open') button.btn.btn-secondary((click)='showPortForwarding()', *ngIf='session && session.open')
i.fas.fa-plug i.fas.fa-plug
span Ports span Ports

View File

@@ -14,15 +14,17 @@ import { Subscription } from 'rxjs'
/** @hidden */ /** @hidden */
@Component({ @Component({
selector: 'ssh-tab', selector: 'ssh-tab',
template: BaseTerminalTabComponent.template + (require('./sshTab.component.pug') as string), template: `${BaseTerminalTabComponent.template} ${require('./sshTab.component.pug')}`,
styles: [require('./sshTab.component.scss'), ...BaseTerminalTabComponent.styles], styles: [require('./sshTab.component.scss'), ...BaseTerminalTabComponent.styles],
animations: BaseTerminalTabComponent.animations, animations: BaseTerminalTabComponent.animations,
}) })
export class SSHTabComponent extends BaseTerminalTabComponent { export class SSHTabComponent extends BaseTerminalTabComponent {
connection?: SSHConnection connection?: SSHConnection
session?: SSHSession session: SSHSession|null = null
private sessionStack: SSHSession[] = [] private sessionStack: SSHSession[] = []
private homeEndSubscription: Subscription private homeEndSubscription: Subscription
private recentInputs = ''
private reconnectOffered = false
constructor ( constructor (
injector: Injector, injector: Injector,
@@ -52,11 +54,18 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
case 'end': case 'end':
this.sendInput('\x1b[F' ) this.sendInput('\x1b[F' )
break break
case 'restart-ssh-session':
this.reconnect()
break
} }
}) })
this.frontendReady$.pipe(first()).subscribe(() => { this.frontendReady$.pipe(first()).subscribe(() => {
this.initializeSession() this.initializeSession()
this.input$.subscribe(data => {
this.recentInputs += data
this.recentInputs = this.recentInputs.substring(this.recentInputs.length - 32)
})
}) })
super.ngOnInit() super.ngOnInit()
@@ -68,12 +77,23 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
async setupOneSession (session: SSHSession): Promise<void> { async setupOneSession (session: SSHSession): Promise<void> {
if (session.connection.jumpHost) { if (session.connection.jumpHost) {
const jumpConnection = this.config.store.ssh.connections.find(x => x.name === session.connection.jumpHost) const jumpConnection: SSHConnection|null = this.config.store.ssh.connections.find(x => x.name === session.connection.jumpHost)
if (!jumpConnection) {
throw new Error(`${session.connection.host}: jump host "${session.connection.jumpHost}" not found in your config`)
}
const jumpSession = this.ssh.createSession(jumpConnection) const jumpSession = this.ssh.createSession(jumpConnection)
await this.setupOneSession(jumpSession) await this.setupOneSession(jumpSession)
jumpSession.destroyed$.subscribe(() => session.destroy()) this.attachSessionHandler(
jumpSession.destroyed$.subscribe(() => {
if (session.open) {
session.destroy()
}
})
)
session.jumpStream = await new Promise((resolve, reject) => jumpSession.ssh.forwardOut( session.jumpStream = await new Promise((resolve, reject) => jumpSession.ssh.forwardOut(
'127.0.0.1', 0, session.connection.host, session.connection.port ?? 22, '127.0.0.1', 0, session.connection.host, session.connection.port ?? 22,
@@ -93,15 +113,11 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
this.sessionStack.push(session) this.sessionStack.push(session)
} }
this.attachSessionHandler(session.serviceMessage$.subscribe(msg => {
session.serviceMessage$.subscribe(msg => {
this.write(`\r\n${colors.black.bgWhite(' SSH ')} ${msg}\r\n`) this.write(`\r\n${colors.black.bgWhite(' SSH ')} ${msg}\r\n`)
session.resize(this.size.columns, this.size.rows) session.resize(this.size.columns, this.size.rows)
}) }))
session.destroyed$.subscribe(() => {
this.write('\r\n' + colors.black.bgCyan(' SSH ') + ` ${session.connection.host}: session closed\r\n`)
})
this.write('\r\n' + colors.black.bgCyan(' SSH ') + ` Connecting to ${session.connection.host}\r\n`) this.write('\r\n' + colors.black.bgCyan(' SSH ') + ` Connecting to ${session.connection.host}\r\n`)
@@ -128,20 +144,51 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
} }
} }
protected attachSessionHandlers (): void {
const session = this.session!
this.attachSessionHandler(session.destroyed$.subscribe(() => {
if (
// Ctrl-D
this.recentInputs.charCodeAt(this.recentInputs.length - 1) === 4 ||
this.recentInputs.endsWith('exit\r')
) {
// User closed the session
this.destroy()
} else {
// Session was closed abruptly
this.write('\r\n' + colors.black.bgCyan(' SSH ') + ` ${session.connection.host}: session closed\r\n`)
if (!this.reconnectOffered) {
this.reconnectOffered = true
this.write('Press any key to reconnect\r\n')
this.input$.pipe(first()).subscribe(() => {
if (!this.session?.open) {
this.reconnect()
}
})
}
}
}))
super.attachSessionHandlers()
}
async initializeSession (): Promise<void> { async initializeSession (): Promise<void> {
this.reconnectOffered = false
if (!this.connection) { if (!this.connection) {
this.logger.error('No SSH connection info supplied') this.logger.error('No SSH connection info supplied')
return return
} }
this.session = this.ssh.createSession(this.connection) const session = this.ssh.createSession(this.connection)
this.setSession(session)
await this.setupOneSession(this.session) try {
await this.setupOneSession(session)
} catch (e) {
this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n')
}
this.attachSessionHandlers() await this.session!.start()
this.session!.resize(this.size.columns, this.size.rows)
await this.session.start()
this.session.resize(this.size.columns, this.size.rows)
} }
async getRecoveryToken (): Promise<RecoveryToken> { async getRecoveryToken (): Promise<RecoveryToken> {

View File

@@ -13,6 +13,7 @@ export class SSHConfigProvider extends ConfigProvider {
ssh: [ ssh: [
'Alt-S', 'Alt-S',
], ],
'restart-ssh-session': [],
}, },
} }

View File

@@ -9,6 +9,10 @@ export class SSHHotkeyProvider extends HotkeyProvider {
id: 'ssh', id: 'ssh',
name: 'Show SSH connections', name: 'Show SSH connections',
}, },
{
id: 'restart-ssh-session',
name: 'Restart current SSH session',
},
] ]
async provide (): Promise<HotkeyDescription[]> { async provide (): Promise<HotkeyDescription[]> {

View File

@@ -5,14 +5,26 @@ import * as keytar from 'keytar'
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class PasswordStorageService { export class PasswordStorageService {
async savePassword (connection: SSHConnection, password: string): Promise<void> { async savePassword (connection: SSHConnection, password: string): Promise<void> {
return keytar.setPassword(`ssh@${connection.host}`, connection.user, password) let key = `ssh@${connection.host}`
if (connection.port) {
key = `ssh@${connection.host}:${connection.port}`
}
return keytar.setPassword(key, connection.user, password)
} }
async deletePassword (connection: SSHConnection): Promise<void> { async deletePassword (connection: SSHConnection): Promise<void> {
await keytar.deletePassword(`ssh@${connection.host}`, connection.user) let key = `ssh@${connection.host}`
if (connection.port) {
key = `ssh@${connection.host}:${connection.port}`
}
await keytar.deletePassword(key, connection.user)
} }
async loadPassword (connection: SSHConnection): Promise<string|null> { async loadPassword (connection: SSHConnection): Promise<string|null> {
return keytar.getPassword(`ssh@${connection.host}`, connection.user) let key = `ssh@${connection.host}`
if (connection.port) {
key = `ssh@${connection.host}:${connection.port}`
}
return keytar.getPassword(key, connection.user)
} }
} }

View File

@@ -9,10 +9,9 @@ import * as fs from 'mz/fs'
import { execFile } from 'mz/child_process' import { execFile } from 'mz/child_process'
import * as path from 'path' import * as path from 'path'
import * as sshpk from 'sshpk' import * as sshpk from 'sshpk'
import { ToastrService } from 'ngx-toastr' import { HostAppService, Platform, Logger, LogService, ElectronService, AppService, SelectorOption, ConfigService, NotificationsService } from 'terminus-core'
import { HostAppService, Platform, Logger, LogService, ElectronService, AppService, SelectorOption, ConfigService } from 'terminus-core'
import { SettingsTabComponent } from 'terminus-settings' import { SettingsTabComponent } from 'terminus-settings'
import { SSHConnection, SSHSession } from '../api' import { ALGORITHM_BLACKLIST, SSHConnection, SSHSession } from '../api'
import { PromptModalComponent } from '../components/promptModal.component' import { PromptModalComponent } from '../components/promptModal.component'
import { PasswordStorageService } from './passwordStorage.service' import { PasswordStorageService } from './passwordStorage.service'
import { SSHTabComponent } from '../components/sshTab.component' import { SSHTabComponent } from '../components/sshTab.component'
@@ -39,7 +38,7 @@ export class SSHService {
private ngbModal: NgbModal, private ngbModal: NgbModal,
private hostApp: HostAppService, private hostApp: HostAppService,
private passwordStorage: PasswordStorageService, private passwordStorage: PasswordStorageService,
private toastr: ToastrService, private notifications: NotificationsService,
private app: AppService, private app: AppService,
private config: ConfigService, private config: ConfigService,
) { ) {
@@ -70,7 +69,7 @@ export class SSHService {
privateKey = (await fs.readFile(privateKeyPath)).toString() privateKey = (await fs.readFile(privateKeyPath)).toString()
} catch (error) { } catch (error) {
logCallback?.(colors.bgRed.black(' X ') + 'Could not read the private key file') logCallback?.(colors.bgRed.black(' X ') + 'Could not read the private key file')
this.toastr.error('Could not read the private key file') this.notifications.error('Could not read the private key file')
} }
if (privateKey) { if (privateKey) {
@@ -147,6 +146,10 @@ export class SSHService {
session.ssh = ssh session.ssh = ssh
let connected = false let connected = false
let savedPassword: string|null = null let savedPassword: string|null = null
const algorithms = {}
for (const key of Object.keys(session.connection.algorithms ?? {})) {
algorithms[key] = session.connection.algorithms![key].filter(x => !ALGORITHM_BLACKLIST.includes(x))
}
await new Promise(async (resolve, reject) => { await new Promise(async (resolve, reject) => {
ssh.on('ready', () => { ssh.on('ready', () => {
connected = true connected = true
@@ -162,7 +165,7 @@ export class SSHService {
this.zone.run(() => { this.zone.run(() => {
if (connected) { if (connected) {
// eslint-disable-next-line @typescript-eslint/no-base-to-string // eslint-disable-next-line @typescript-eslint/no-base-to-string
this.toastr.error(error.toString()) this.notifications.error(error.toString())
} else { } else {
reject(error) reject(error)
} }
@@ -258,7 +261,7 @@ export class SSHService {
tryKeyboard: true, tryKeyboard: true,
agent: agent ?? undefined, agent: agent ?? undefined,
agentForward: session.connection.agentForward && !!agent, agentForward: session.connection.agentForward && !!agent,
keepaliveInterval: session.connection.keepaliveInterval, keepaliveInterval: session.connection.keepaliveInterval ?? 15000,
keepaliveCountMax: session.connection.keepaliveCountMax, keepaliveCountMax: session.connection.keepaliveCountMax,
readyTimeout: session.connection.readyTimeout, readyTimeout: session.connection.readyTimeout,
hostVerifier: (digest: string) => { hostVerifier: (digest: string) => {
@@ -267,7 +270,7 @@ export class SSHService {
return true return true
}, },
hostHash: 'sha256' as any, hostHash: 'sha256' as any,
algorithms: session.connection.algorithms, algorithms,
sock: session.jumpStream, sock: session.jumpStream,
authHandler: methodsLeft => { authHandler: methodsLeft => {
while (true) { while (true) {
@@ -285,7 +288,7 @@ export class SSHService {
}, },
} as any) } as any)
} catch (e) { } catch (e) {
this.toastr.error(e.message) this.notifications.error(e.message)
return reject(e) return reject(e)
} }
@@ -379,7 +382,7 @@ export class SSHService {
options.push({ options.push({
name: 'Manage connections', name: 'Manage connections',
icon: 'cog', icon: 'cog',
callback: () => this.app.openNewTab(SettingsTabComponent, { activeTab: 'ssh' }), callback: () => this.app.openNewTabRaw(SettingsTabComponent, { activeTab: 'ssh' }),
}) })
options.push({ options.push({
@@ -407,7 +410,7 @@ export class SSHService {
return tab return tab
} catch (error) { } catch (error) {
this.toastr.error(`Could not connect: ${error}`) this.notifications.error(`Could not connect: ${error}`)
throw error throw error
} }
} }
@@ -417,7 +420,9 @@ export class SSHService {
let host = query let host = query
let port = 22 let port = 22
if (host.includes('@')) { if (host.includes('@')) {
[user, host] = host.split('@') const parts = host.split(/@/g)
host = parts[parts.length - 1]
user = parts.slice(0, parts.length - 1).join('@')
} }
if (host.includes(':')) { if (host.includes(':')) {
port = parseInt(host.split(':')[1]) port = parseInt(host.split(':')[1])

View File

@@ -1,61 +1,5 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'ssh',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname,
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-ssh:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
{ test: /\.svg/, use: ['svg-inline-loader'] },
],
},
externals: [
'child_process',
'fs',
'keytar',
'path',
'ngx-toastr',
'socksv5',
'windows-native-registry',
'windows-process-tree/build/Release/windows_process_tree.node',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
/^terminus-/,
],
}

View File

@@ -2,10 +2,10 @@
# yarn lockfile v1 # yarn lockfile v1
"@types/node@*", "@types/node@14.14.14": "@types/node@*", "@types/node@14.14.31":
version "14.14.14" version "14.14.31"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.14.tgz#f7fd5f3cc8521301119f63910f0fb965c7d761ae" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
integrity sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ== integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
"@types/ssh2-streams@*": "@types/ssh2-streams@*":
version "0.1.7" version "0.1.7"
@@ -230,9 +230,9 @@ rimraf@~2.6.2:
glob "^7.1.3" glob "^7.1.3"
run-script-os@^1.1.3: run-script-os@^1.1.3:
version "1.1.3" version "1.1.5"
resolved "https://registry.yarnpkg.com/run-script-os/-/run-script-os-1.1.3.tgz#1069b418307f4fd36ff056b5eda309c273fca8b0" resolved "https://registry.yarnpkg.com/run-script-os/-/run-script-os-1.1.5.tgz#6038a92b370a1cbca5fa2fa73d1c740b0037b6ff"
integrity sha512-xPlzE6533nvWVea5z7e5J7+JAIepfpxTu/HLGxcjJYlemVukOCWJBaRCod/DWXJFRIWEFOgSGbjd2m1QWTJi5w== integrity sha512-kLvUnf1SM1+gSH2bY1P41MNFaWdXaG2nkhoJS9WQNQxk6g9KNuncKderBLG7vOsp77GtQqNs0bEazxip/I6wfg==
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2" version "2.1.2"

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-terminal", "name": "terminus-terminal",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Terminus' terminal emulation core", "description": "Terminus' terminal emulation core",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -27,12 +27,12 @@
"runes": "^0.4.2", "runes": "^0.4.2",
"slugify": "^1.4.0", "slugify": "^1.4.0",
"xterm": "^4.9.0-beta.7", "xterm": "^4.9.0-beta.7",
"xterm-addon-fit": "^0.4.0-beta.8", "xterm-addon-fit": "^0.5.0",
"xterm-addon-ligatures": "^0.4.0-beta.5", "xterm-addon-ligatures": "^0.4.0",
"xterm-addon-search": "^0.7.0-beta.2", "xterm-addon-search": "^0.8.0",
"xterm-addon-serialize": "^0.3.0", "xterm-addon-serialize": "^0.5.0",
"xterm-addon-unicode11": "^0.2.0", "xterm-addon-unicode11": "^0.2.0",
"xterm-addon-webgl": "^0.8.0", "xterm-addon-webgl": "^0.10.0",
"zmodem.js": "^0.1.9" "zmodem.js": "^0.1.9"
}, },
"peerDependencies": { "peerDependencies": {

View File

@@ -1,11 +1,10 @@
import type { MenuItemConstructorOptions } from 'electron' import type { MenuItemConstructorOptions } from 'electron'
import { Observable, Subject, Subscription } from 'rxjs' import { Observable, Subject, Subscription } from 'rxjs'
import { first } from 'rxjs/operators' import { first } from 'rxjs/operators'
import { ToastrService } from 'ngx-toastr'
import colors from 'ansi-colors' import colors from 'ansi-colors'
import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags } from '@angular/core' import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags } from '@angular/core'
import { trigger, transition, style, animate, AnimationTriggerMetadata } from '@angular/animations' import { trigger, transition, style, animate, AnimationTriggerMetadata } from '@angular/animations'
import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppService, HotkeysService, Platform, LogService, Logger, TabContextMenuItemProvider, SplitTabComponent } from 'terminus-core' import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppService, HotkeysService, NotificationsService, Platform, LogService, Logger, TabContextMenuItemProvider, SplitTabComponent } from 'terminus-core'
import { BaseSession, SessionsService } from '../services/sessions.service' import { BaseSession, SessionsService } from '../services/sessions.service'
import { TerminalFrontendService } from '../services/terminalFrontend.service' import { TerminalFrontendService } from '../services/terminalFrontend.service'
@@ -15,10 +14,6 @@ import { ResizeEvent } from './interfaces'
import { TerminalDecorator } from './decorator' import { TerminalDecorator } from './decorator'
/** @hidden */
export interface ToastrServiceProxy {
info: (_: string) => void
}
/** /**
* A class to base your custom terminal tabs on * A class to base your custom terminal tabs on
*/ */
@@ -35,7 +30,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
]), ]),
])] ])]
session?: BaseSession session: BaseSession|null = null
savedState?: any savedState?: any
@Input() zoom = 0 @Input() zoom = 0
@@ -81,7 +76,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
protected sessions: SessionsService protected sessions: SessionsService
protected electron: ElectronService protected electron: ElectronService
protected terminalContainersService: TerminalFrontendService protected terminalContainersService: TerminalFrontendService
protected toastr: ToastrServiceProxy protected notifications: NotificationsService
protected log: LogService protected log: LogService
protected decorators: TerminalDecorator[] = [] protected decorators: TerminalDecorator[] = []
protected contextMenuProviders: TabContextMenuItemProvider[] protected contextMenuProviders: TabContextMenuItemProvider[]
@@ -89,11 +84,13 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
protected logger: Logger protected logger: Logger
protected output = new Subject<string>() protected output = new Subject<string>()
protected sessionChanged = new Subject<BaseSession|null>()
private sessionCloseSubscription: Subscription private sessionCloseSubscription: Subscription
private hotkeysSubscription: Subscription private hotkeysSubscription: Subscription
private bellPlayer: HTMLAudioElement private bellPlayer: HTMLAudioElement
private termContainerSubscriptions: Subscription[] = [] private termContainerSubscriptions: Subscription[] = []
private allFocusModeSubscription: Subscription|null = null private allFocusModeSubscription: Subscription|null = null
private sessionHandlers: Subscription[] = []
get input$ (): Observable<Buffer> { get input$ (): Observable<Buffer> {
if (!this.frontend) { if (!this.frontend) {
@@ -120,6 +117,8 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
get frontendReady$ (): Observable<void> { return this.frontendReady } get frontendReady$ (): Observable<void> { return this.frontendReady }
get sessionChanged$ (): Observable<BaseSession|null> { return this.sessionChanged }
constructor (protected injector: Injector) { constructor (protected injector: Injector) {
super() super()
@@ -132,7 +131,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
this.sessions = injector.get(SessionsService) this.sessions = injector.get(SessionsService)
this.electron = injector.get(ElectronService) this.electron = injector.get(ElectronService)
this.terminalContainersService = injector.get(TerminalFrontendService) this.terminalContainersService = injector.get(TerminalFrontendService)
this.toastr = injector.get(ToastrService) this.notifications = injector.get(NotificationsService)
this.log = injector.get(LogService) this.log = injector.get(LogService)
this.decorators = injector.get<any>(TerminalDecorator, null, InjectFlags.Optional) as TerminalDecorator[] this.decorators = injector.get<any>(TerminalDecorator, null, InjectFlags.Optional) as TerminalDecorator[]
this.contextMenuProviders = injector.get<any>(TabContextMenuItemProvider, null, InjectFlags.Optional) as TabContextMenuItemProvider[] this.contextMenuProviders = injector.get<any>(TabContextMenuItemProvider, null, InjectFlags.Optional) as TabContextMenuItemProvider[]
@@ -140,7 +139,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
this.logger = this.log.create('baseTerminalTab') this.logger = this.log.create('baseTerminalTab')
this.setTitle('Terminal') this.setTitle('Terminal')
this.hotkeysSubscription = this.hotkeys.matchedHotkey.subscribe(hotkey => { this.hotkeysSubscription = this.hotkeys.matchedHotkey.subscribe(async hotkey => {
if (!this.hasFocus) { if (!this.hasFocus) {
return return
} }
@@ -149,7 +148,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
if (this.frontend?.getSelection()) { if (this.frontend?.getSelection()) {
this.frontend.copySelection() this.frontend.copySelection()
this.frontend.clearSelection() this.frontend.clearSelection()
this.toastr.info('Copied') this.notifications.notice('Copied')
} else { } else {
this.sendInput('\x03') this.sendInput('\x03')
} }
@@ -157,7 +156,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
case 'copy': case 'copy':
this.frontend?.copySelection() this.frontend?.copySelection()
this.frontend?.clearSelection() this.frontend?.clearSelection()
this.toastr.info('Copied') this.notifications.notice('Copied')
break break
case 'paste': case 'paste':
this.paste() this.paste()
@@ -207,6 +206,9 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
case 'pane-focus-all': case 'pane-focus-all':
this.focusAllPanes() this.focusAllPanes()
break break
case 'copy-current-path':
this.copyCurrentPath()
break
} }
}) })
this.bellPlayer = document.createElement('audio') this.bellPlayer = document.createElement('audio')
@@ -328,7 +330,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
} }
const percentageMatch = /(^|[^\d])(\d+(\.\d+)?)%([^\d]|$)/.exec(data) const percentageMatch = /(^|[^\d])(\d+(\.\d+)?)%([^\d]|$)/.exec(data)
if (!this.alternateScreenActive && percentageMatch) { if (!this.alternateScreenActive && percentageMatch && this.config.store.terminal.detectProgress) {
const percentage = percentageMatch[3] ? parseFloat(percentageMatch[2]) : parseInt(percentageMatch[2]) const percentage = percentageMatch[3] ? parseFloat(percentageMatch[2]) : parseInt(percentageMatch[2])
if (percentage > 0 && percentage <= 100) { if (percentage > 0 && percentage <= 100) {
this.setProgress(percentage) this.setProgress(percentage)
@@ -343,7 +345,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
async paste (): Promise<void> { async paste (): Promise<void> {
let data = this.electron.clipboard.readText() let data = this.electron.clipboard.readText()
if (this.config.store.terminal.bracketedPaste) { if (this.config.store.terminal.bracketedPaste) {
data = '\x1b[200~' + data + '\x1b[201~' data = `\x1b[200~${data}\x1b[201~`
} }
if (this.hostApp.platform === Platform.Windows) { if (this.hostApp.platform === Platform.Windows) {
data = data.replace(/\r\n/g, '\r') data = data.replace(/\r\n/g, '\r')
@@ -414,10 +416,11 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
return return
} }
if (this.parent instanceof SplitTabComponent) { if (this.parent instanceof SplitTabComponent) {
this.parent._allFocusMode = true const parent = this.parent
this.parent.layout() parent._allFocusMode = true
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()) { for (const tab of parent.getAllTabs()) {
if (tab !== this && tab instanceof BaseTerminalTabComponent) { if (tab !== this && tab instanceof BaseTerminalTabComponent) {
tab.sendInput(data) tab.sendInput(data)
} }
@@ -438,6 +441,19 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
} }
} }
async copyCurrentPath (): Promise<void> {
let cwd: string|null = null
if (this.session?.supportsWorkingDirectory()) {
cwd = await this.session.getWorkingDirectory()
}
if (cwd) {
this.electron.clipboard.writeText(cwd)
this.notifications.notice('Copied')
} else {
this.notifications.error('Shell does not support current path detection')
}
}
/** @hidden */ /** @hidden */
ngOnDestroy (): void { ngOnDestroy (): void {
this.frontend?.detach(this.content.nativeElement) this.frontend?.detach(this.content.nativeElement)
@@ -550,26 +566,56 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
] ]
} }
setSession (session: BaseSession|null, destroyOnSessionClose = false): void {
if (session) {
if (this.session) {
this.setSession(null)
}
this.detachSessionHandlers()
this.session = session
this.attachSessionHandlers(destroyOnSessionClose)
} else {
this.detachSessionHandlers()
this.session = null
}
this.sessionChanged.next(session)
}
protected attachSessionHandler (subscription: Subscription): void {
this.sessionHandlers.push(subscription)
}
protected attachSessionHandlers (destroyOnSessionClose = false): void { protected attachSessionHandlers (destroyOnSessionClose = false): void {
if (!this.session) { if (!this.session) {
throw new Error('Session not set') throw new Error('Session not set')
} }
// this.session.output$.bufferTime(10).subscribe((datas) => { // this.session.output$.bufferTime(10).subscribe((datas) => {
this.session.output$.subscribe(data => { this.attachSessionHandler(this.session.output$.subscribe(data => {
if (this.enablePassthrough) { if (this.enablePassthrough) {
this.zone.run(() => { this.zone.run(() => {
this.output.next(data) this.output.next(data)
this.write(data) this.write(data)
}) })
} }
}) }))
if (destroyOnSessionClose) { if (destroyOnSessionClose) {
this.sessionCloseSubscription = this.session.closed$.subscribe(() => { this.attachSessionHandler(this.sessionCloseSubscription = this.session.closed$.subscribe(() => {
this.frontend?.destroy() this.frontend?.destroy()
this.destroy() this.destroy()
}) }))
} }
this.attachSessionHandler(this.session.destroyed$.subscribe(() => {
this.setSession(null)
}))
}
protected detachSessionHandlers (): void {
for (const s of this.sessionHandlers) {
s.unsubscribe()
}
this.sessionHandlers = []
} }
} }

View File

@@ -22,6 +22,7 @@ export interface Profile {
shell?: string shell?: string
isBuiltin?: boolean isBuiltin?: boolean
icon?: string icon?: string
disableDynamicTitle?: boolean
} }
export interface TerminalColorScheme { export interface TerminalColorScheme {

View File

@@ -1,6 +1,6 @@
h3.mb-3 Appearance h3.mb-3 Appearance
.d-flex .row
.mr-5.w-100 .col-12.col-md-6
.form-line .form-line
.header .header
.title Font .title Font
@@ -30,6 +30,7 @@ h3.mb-3 Appearance
.alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.ligatures && config.store.terminal.frontend == "xterm-webgl"') Ligatures are not supported by the WebGL frontend .alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.ligatures && config.store.terminal.frontend == "xterm-webgl"') Ligatures are not supported by the WebGL frontend
.col-12.col-md-6
color-scheme-preview([scheme]='config.store.terminal.colorScheme', [fontPreview]='true') color-scheme-preview([scheme]='config.store.terminal.colorScheme', [fontPreview]='true')
.form-line .form-line

View File

@@ -62,6 +62,12 @@
placeholder='#000000' placeholder='#000000'
) )
.form-line
.header
.title Disable dynamic tab title
.description Connection name will be used as a title instead
toggle([(ngModel)]='profile.disableDynamicTitle')
.modal-footer .modal-footer
button.btn.btn-outline-primary((click)='save()') Save button.btn.btn-outline-primary((click)='save()') Save
button.btn.btn-outline-danger((click)='cancel()') Cancel button.btn.btn-outline-danger((click)='cancel()') Cancel

View File

@@ -1,7 +1,6 @@
import { Component, Input, Output, EventEmitter } from '@angular/core' import { Component, Input, Output, EventEmitter } from '@angular/core'
import { ToastrService } from 'ngx-toastr'
import { Frontend, SearchOptions } from '../frontends/frontend' import { Frontend, SearchOptions } from '../frontends/frontend'
import { ConfigService } from 'terminus-core' import { ConfigService, NotificationsService } from 'terminus-core'
@Component({ @Component({
selector: 'search-panel', selector: 'search-panel',
@@ -20,7 +19,7 @@ export class SearchPanelComponent {
@Output() close = new EventEmitter() @Output() close = new EventEmitter()
constructor ( constructor (
private toastr: ToastrService, private notifications: NotificationsService,
public config: ConfigService, public config: ConfigService,
) { } ) { }
@@ -35,7 +34,7 @@ export class SearchPanelComponent {
} }
if (!this.frontend.findNext(this.query, { ...this.options, incremental: incremental || undefined })) { if (!this.frontend.findNext(this.query, { ...this.options, incremental: incremental || undefined })) {
this.notFound = true this.notFound = true
this.toastr.error('Not found') this.notifications.notice('Not found')
} }
} }
@@ -45,7 +44,7 @@ export class SearchPanelComponent {
} }
if (!this.frontend.findPrevious(this.query, { ...this.options, incremental: incremental || undefined })) { if (!this.frontend.findPrevious(this.query, { ...this.options, incremental: incremental || undefined })) {
this.notFound = true this.notFound = true
this.toastr.error('Not found') this.notifications.notice('Not found')
} }
} }

View File

@@ -57,15 +57,14 @@ h3.mb-3 Shell
.form-line .form-line
.header .header
.title Always Use Working Directory .title Directory for new tabs
.description
div By default, new terminals will open where the previous terminal was working.
div Enabling this option will always launch new terminals in the working directory specified above.
toggle( select.form-control(
[(ngModel)]='config.store.terminal.alwaysUseWorkingDirectory', [(ngModel)]='config.store.terminal.alwaysUseWorkingDirectory',
(ngModelChange)='config.save()' (ngModelChange)='config.save()',
) )
option([ngValue]='false') Same as active tab's directory
option([ngValue]='true') The working directory from above
.form-line.align-items-start .form-line.align-items-start
.header .header
@@ -97,7 +96,7 @@ h3.mt-3 Saved Profiles
button.btn.btn-outline-danger.ml-1((click)='$event.stopPropagation(); deleteProfile(profile)') button.btn.btn-outline-danger.ml-1((click)='$event.stopPropagation(); deleteProfile(profile)')
i.fas.fa-trash i.fas.fa-trash
div(ngbDropdown, placement='top-left') .pb-4(ngbDropdown, placement='top-left')
button.btn.btn-primary(ngbDropdownToggle) button.btn.btn-primary(ngbDropdownToggle)
i.fas.fa-fw.fa-plus i.fas.fa-fw.fa-plus
| New profile | New profile

View File

@@ -4,6 +4,7 @@ import { ConfigProvider, Platform } from 'terminus-core'
export class TerminalConfigProvider extends ConfigProvider { export class TerminalConfigProvider extends ConfigProvider {
defaults = { defaults = {
hotkeys: { hotkeys: {
'copy-current-path': [],
shell: { shell: {
__nonStructural: true, __nonStructural: true,
}, },
@@ -73,6 +74,7 @@ export class TerminalConfigProvider extends ConfigProvider {
wholeWord: false, wholeWord: false,
caseSensitive: false, caseSensitive: false,
}, },
detectProgress: true,
}, },
} }

Some files were not shown because too many files have changed in this diff Show More