diff --git a/.eslintrc.js b/.eslintrc.js
index 26503e2..a1e07b0 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,6 +1,6 @@
module.exports = {
- parser: 'eslint-plugin-typescript/parser',
- plugins: ['typescript', 'prettier'],
+ parser: '@typescript-eslint/parser',
+ plugins: ['@typescript-eslint', 'prettier'],
env: {
es6: true,
node: true,
@@ -9,24 +9,23 @@ module.exports = {
root: true,
extends: [
'airbnb-base',
- 'plugin:typescript/recommended',
- 'plugin:prettier/recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'prettier',
+ 'prettier/@typescript-eslint',
],
rules: {
- 'typescript/indent': 'off',
'linebreak-style': ['error', 'unix'],
'arrow-parens': ['error', 'as-needed'],
'no-param-reassign': ['error', { props: false }],
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'no-use-before-define': ['error', { functions: false }],
- 'typescript/no-use-before-define': ['error', { functions: false }],
+ '@typescript-eslint/no-use-before-define': ['error', { functions: false }],
},
settings: {
'import/resolver': {
- 'typescript-eslint-parser': ['.ts', '.tsx'],
node: {
extensions: ['.ts', '.js'],
},
},
- },
+ }
};
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 64e033f..a0d1be4 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -18,7 +18,7 @@ jobs:
- run: yarn
name: Install dependencies
- name: ESLint checks
- uses: gimenete/eslint-action@1.0
+ run: yarn lint
- run: yarn build
name: Compile Typescript
- name: Publish
diff --git a/.github/workflows/rebase.yml b/.github/workflows/rebase.yml
index faab0c7..d5f83ca 100644
--- a/.github/workflows/rebase.yml
+++ b/.github/workflows/rebase.yml
@@ -1,13 +1,16 @@
---
name: Automatic Rebase
-on: issue_comment
+on:
+ issue_comment:
+ types: [created]
jobs:
rebase:
name: Rebase
+ if: contains(github.event.comment.body, '/rebase')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Automatic Rebase
- uses: cirrus-actions/rebase@1.0
+ uses: cirrus-actions/rebase@master
env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.node_github_token }}
diff --git a/README.md b/README.md
index facbc17..414a8ce 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,17 @@ websockets rather then Ajax and hence better response time.
## Install
+### Requiments
+
+To instal WeTTy you'll need to have the following installed:
+
+- Node.JS 10+
+- make
+- python
+- build-essential
+
+### From source
+
WeTTy can be installed from source or from npm.
To install from source run:
@@ -20,11 +31,15 @@ $ yarn
$ yarn build
```
+### From NPM
+
To install it globally from npm use yarn or npm:
- yarn, `yarn global add wetty`
- npm, `npm i -g wetty`
+### Autologin
+
For auto-login feature you'll need sshpass installed (NOT required for rest of
the program).
@@ -119,6 +134,35 @@ the user like this (Only while running wetty as a non root account):
This is not a required feature and the security implications for passing the
password in the url will have to be considered by the user
+### File Downloading
+
+Wetty supports file downloads by printing terminal escape sequences between a
+base64 encoded file.
+
+The terminal escape sequences used are `^[[5i` and `^[[4i` (VT100 for "enter
+auto print" and "exit auto print" respectively -
+https://vt100.net/docs/tp83/appendixc.html).
+
+An example of a helper script that prints the terminal escape characters and
+base64s stdin:
+
+```
+$ cat wetty-download.sh
+#!/bin/sh
+echo '^[[5i'$(cat /dev/stdin | base64)'^[[4i'
+```
+
+You are then able to download files via wetty!
+
+```
+$ cat my-pdf-file.pdf | ./wetty-download.sh
+```
+
+Wetty will then issue a popup like the following that links to a local file
+blob:
+
+`Download ready: file-20191015233654.pdf`
+
## Run wetty behind nginx or apache
As said earlier you can use a proxy to add https to WeTTy.
diff --git a/docker-compose.yml b/docker-compose.yml
index 28b21eb..a1ea398 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -32,6 +32,7 @@ services:
build:
context: .
dockerfile: Dockerfile-ssh
+ image: butlerx/wetty:ssh
container_name: 'wetty-ssh'
networks:
diff --git a/docs/API.md b/docs/API.md
index d767747..89bc3b1 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -1,93 +1,88 @@
-
-
## WeTTy
Create WeTTY server
-* [WeTTy](#module_WeTTy)
- * [~start](#module_WeTTy..start) ⇒ Promise
- * ["connection"](#event_connection)
- * ["spawn"](#event_spawn)
- * ["exit"](#event_exit)
- * ["disconnect"](#event_disconnect)
- * ["server"](#event_server)
-
-
+- [WeTTy](#module_WeTTy)
+ - [start](#module_WeTTy..start) ⇒ `Promise`
+ - [connection](#event_connection)
+ - [spawn](#event_spawn)
+ - [exit](#event_exit)
+ - [disconnect](#event_disconnect)
+ - [server](#event_server)
-### WeTTy~start ⇒ Promise
+### WeTTy.start ⇒ `Promise`
Starts WeTTy Server
-**Kind**: inner property of [WeTTy
](#module_WeTTy)
-**Returns**: Promise
- Promise resolves once server is running
-
-| Param | Type | Default | Description |
-| ------------ | ------------------- | ------------------------------------- | --------------------------- |
-| [ssh] | Object
| | SSH settings |
-| [ssh.user] | string
| "''"
| default user for ssh |
-| [ssh.host] | string
| "localhost"
| machine to ssh too |
-| [ssh.auth] | string
| "password"
| authtype to use |
-| [ssh.port] | number
| 22
| port to connect to over ssh |
-| [serverPort] | number
| 3000
| Port to run server on |
-| [ssl] | Object
| | SSL settings |
-| [ssl.key] | string
| | Path to ssl key |
-| [ssl.cert] | string
| | Path to ssl cert |
-
-
+**Kind**: inner property of [`WeTTy`](#module_WeTTy)
+**Returns**: `Promise` - Promise resolves once server is running
+
+| Param | Type | Default | Description |
+| :------------------------ | --------- | ------------- | ---------------------------------------------------------------------------------------------------------------------- |
+| [ssh] | `Object` | | SSH settings |
+| [ssh.user] | `string` | `"''"` | default user for ssh |
+| [ssh.host] | `string` | `"localhost"` | machine to ssh too |
+| [ssh.auth] | `string` | `"password"` | authtype to use |
+| [ssh.port] | `number` | `22` | port to connect to over ssh |
+| [ssh.pass] | `string` | | Optional param of a password to use for ssh |
+| [ssh.key] | `string` | | path to an optional client private key (connection will be password-less and insecure!) |
+| [serverConf] | `Object` | | Server settings |
+| [serverConf.base] | `Object` | `'/wetty/'` | Server settings |
+| [serverConf.port] | `number` | `3000` | Port to run server on |
+| [serverConf.host] | `string` | `'0.0.0.0'` | Host address for server |
+| [serverConf.title] | `string` | `'WeTTy'` | Title of the server |
+| [serverConf.bypasshelmet] | `boolean` | `false` | if helmet should be disabled on the sever |
+| [command] | `string` | `"''"` | The command to execute. If running as root and no host specified this will be login if a host is specified will be ssh |
+| [ssl] | `Object` | | SSL settings |
+| [ssl.key] | `string` | | Path to ssl key |
+| [ssl.cert] | `string` | | Path to ssl cert |
### "connection"
-**Kind**: event emitted by [WeTTy
](#module_WeTTy)
+**Kind**: event emitted by [`WeTTy`](#module_WeTTy)
**Properties**
-| Name | Type | Description |
-| ---- | ------------------- | --------------------------- |
-| msg | string
| Message for logs |
-| date | Date
| date and time of connection |
-
-
+| Name | Type | Description |
+| ---- | -------- | --------------------------- |
+| msg | `string` | Message for logs |
+| date | `Date` | date and time of connection |
### "spawn"
Terminal process spawned
-**Kind**: event emitted by [WeTTy
](#module_WeTTy)
+**Kind**: event emitted by [`WeTTy`](#module_WeTTy)
**Properties**
-| Name | Type | Description |
-| ------- | ------------------- | -------------------------------------- |
-| msg | string
| Message containing pid info and status |
-| pid | number
| Pid of the terminal |
-| address | string
| address of connecting user |
-
-
+| Name | Type | Description |
+| ------- | -------- | -------------------------------------- |
+| msg | `string` | Message containing pid info and status |
+| pid | `number` | Pid of the terminal |
+| address | `string` | address of connecting user |
### "exit"
Terminal process exits
-**Kind**: event emitted by [WeTTy
](#module_WeTTy)
+**Kind**: event emitted by [`WeTTy`](#module_WeTTy)
**Properties**
-| Name | Type | Description |
-| ---- | ------------------- | -------------------------------------- |
-| code | number
| the exit code |
-| msg | string
| Message containing pid info and status |
-
-
+| Name | Type | Description |
+| ---- | -------- | -------------------------------------- |
+| code | `number` | the exit code |
+| msg | `string` | Message containing pid info and status |
### "disconnect"
-**Kind**: event emitted by [WeTTy
](#module_WeTTy)
-
+**Kind**: event emitted by [`WeTTy`](#module_WeTTy)
### "server"
-**Kind**: event emitted by [WeTTy
](#module_WeTTy)
+**Kind**: event emitted by [`WeTTy`](#module_WeTTy)
**Properties**
-| Name | Type | Description |
-| ---------- | ------------------- | ------------------------------- |
-| msg | string
| Message for logging |
-| port | number
| port sever is on |
-| connection | string
| connection type for web traffic |
+| Name | Type | Description |
+| ---------- | -------- | ------------------------------- |
+| msg | `string` | Message for logging |
+| port | `number` | port sever is on |
+| connection | `string` | connection type for web traffic |
diff --git a/package.json b/package.json
index b6dcaac..82ea695 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "wetty",
- "version": "1.1.5",
+ "version": "1.1.8",
"description": "WeTTY = Web + TTY. Terminal access in browser over http/https",
"homepage": "https://github.com/krishnasrinivas/wetty",
"repository": {
@@ -14,7 +14,7 @@
},
"main": "index.js",
"scripts": {
- "lint": "eslint --ext .js,.ts .",
+ "lint": "eslint --ext .ts .",
"build": "babel-node node_modules/.bin/webpack",
"start": "node .",
"dev": "NODE_ENV=development concurrently --kill-others --success first \"babel-node node_modules/.bin/webpack --watch\" \"nodemon .\"",
@@ -51,15 +51,17 @@
"dependencies": {
"compression": "^1.7.4",
"express": "^4.17.1",
+ "file-type": "^12.3.0",
"fs-extra": "^8.1.0",
"helmet": "^3.20.1",
"lodash": "^4.17.15",
"morgan": "^1.9.1",
- "node-pty": "^0.8.1",
+ "node-pty": "0.9.0-beta28",
"serve-favicon": "^2.5.0",
"socket.io": "^2.2.0",
"socket.io-client": "^2.2.0",
"source-map-loader": "^0.2.4",
+ "toastify-js": "^1.6.1",
"winston": "^3.2.1",
"xterm": "^3.14.5",
"yargs": "^14.0.0"
@@ -82,16 +84,17 @@
"@types/socket.io-client": "^1.4.32",
"@types/webpack-env": "^1.14.0",
"@types/yargs": "^13.0.2",
+ "@typescript-eslint/eslint-plugin": "^2.5.0",
+ "@typescript-eslint/parser": "^2.5.0",
"babel-loader": "^8.0.6",
"babel-plugin-lodash": "^3.3.4",
"concurrently": "^4.1.2",
"css-loader": "^3.2.0",
- "eslint": "^6.3.0",
- "eslint-config-airbnb-base": "^14.0.0",
- "eslint-config-prettier": "^6.2.0",
+ "eslint": "6.1.0",
+ "eslint-config-airbnb-base": "14.0.0",
+ "eslint-config-prettier": "^6.4.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^3.1.0",
- "eslint-plugin-typescript": "^1.0.0-rc.1",
"file-loader": "^4.2.0",
"husky": "^3.0.5",
"lint-staged": "~9.2.5",
@@ -125,6 +128,7 @@
"Strubbl ",
"koushikmln ",
"mirtouf ",
- "nosemeocurrenada "
+ "nosemeocurrenada ",
+ "Ben Letchford "
]
}
diff --git a/src/client/index.ts b/src/client/index.ts
index 693a90d..a17e107 100644
--- a/src/client/index.ts
+++ b/src/client/index.ts
@@ -2,6 +2,8 @@ import { Terminal } from 'xterm';
import { isUndefined } from 'lodash';
import * as io from 'socket.io-client';
import { fit } from 'xterm/lib/addons/fit/fit';
+import * as fileType from 'file-type';
+import Toastify from 'toastify-js';
import './wetty.scss';
import './favicon.ico';
@@ -12,6 +14,9 @@ const socket = io(window.location.origin, {
path: `${trim(socketBase)}/socket.io`,
});
+const FILE_BEGIN = '\u001b[5i';
+const FILE_END = '\u001b[4i';
+
//NOTE text selection on double click or select
const copyToClipboard = (text: string) => {
if (window.clipboardData && window.clipboardData.setData) {
@@ -35,11 +40,13 @@ const copyToClipboard = (text: string) => {
socket.on('connect', () => {
const term = new Terminal();
+ let fileBuffer = [];
term.open(document.getElementById('terminal'));
const defaultOptions = {
fontSize: 14
};
- let options: any;
+ let options: object;
+
try {
if (localStorage.options === undefined) {
options = defaultOptions;
@@ -54,9 +61,9 @@ socket.on('connect', () => {
term.setOption(key, value);
});
const code = JSON.stringify(options, null, 2);
- const editor = document.querySelector('#options .editor');
+ const editor = document.querySelector('#options .editor') || {value: code};
editor.value = code;
- editor.addEventListener('keyup', e => {
+ editor.addEventListener('keyup', () => {
try {
const updated = JSON.parse(editor.value);
const updatedCode = JSON.stringify(updated, null, 2);
@@ -114,6 +121,52 @@ socket.on('connect', () => {
disconnect(data);
}
+ function onCompleteFile() {
+ let bufferCharacters = fileBuffer.join('');
+ bufferCharacters = bufferCharacters.substring(bufferCharacters.lastIndexOf(FILE_BEGIN) + FILE_BEGIN.length, bufferCharacters.lastIndexOf(FILE_END));
+
+ // Try to decode it as base64, if it fails we assume it's not base64
+ try {
+ bufferCharacters = window.atob(bufferCharacters);
+ } catch (err) {
+ // Assuming it's not base64...
+ }
+
+ const bytes = new Uint8Array(bufferCharacters.length);
+ for (let i = 0; i < bufferCharacters.length; i += 1) {
+ bytes[i] = bufferCharacters.charCodeAt(i);
+ }
+
+ let mimeType = 'application/octet-stream';
+ let fileExt = '';
+ const typeData = fileType(bytes);
+ if (typeData) {
+ mimeType = typeData.mime;
+ fileExt = typeData.ext;
+ }
+ const fileName = `file-${new Date()
+ .toISOString()
+ .split('.')[0]
+ .replace(/-/g, '')
+ .replace('T', '')
+ .replace(/:/g, '')}${fileExt ? `.${fileExt}` : ''}`;
+
+ const blob = new Blob([new Uint8Array(bytes.buffer)], { type: mimeType });
+ const blobUrl = URL.createObjectURL(blob);
+
+ fileBuffer = [];
+
+ Toastify({
+ text: `Download ready: ${fileName}`,
+ duration: 10000,
+ newWindow: true,
+ gravity: 'bottom',
+ position: 'right',
+ backgroundColor: '#fff',
+ stopOnFocus: true,
+ }).showToast();
+ }
+
term.on('data', data => {
socket.emit('input', data);
});
@@ -122,7 +175,31 @@ socket.on('connect', () => {
});
socket
.on('data', (data: string) => {
- term.write(data);
+ const indexOfFileBegin = data.indexOf(FILE_BEGIN);
+ const indexOfFileEnd = data.indexOf(FILE_END);
+
+ // If we've got the entire file in one chunk
+ if (indexOfFileBegin !== -1 && indexOfFileEnd !== -1) {
+ fileBuffer.push(data);
+ onCompleteFile();
+ }
+ // If we've found a beginning marker
+ else if (indexOfFileBegin !== -1) {
+ fileBuffer.push(data);
+ }
+ // If we've found an ending marker
+ else if (indexOfFileEnd !== -1) {
+ fileBuffer.push(data);
+ onCompleteFile();
+ }
+ // If we've found the continuation of a file
+ else if (fileBuffer.length > 0) {
+ fileBuffer.push(data);
+ }
+ // Just treat it as normal data
+ else {
+ term.write(data);
+ }
})
.on('login', () => {
term.writeln('');
diff --git a/src/client/wetty.scss b/src/client/wetty.scss
index c8ae18c..aa5816a 100644
--- a/src/client/wetty.scss
+++ b/src/client/wetty.scss
@@ -1,4 +1,5 @@
@import '~xterm/dist/xterm';
+@import '~toastify-js/src/toastify.css';
$black: #000;
$grey: rgba(0, 0, 0, 0.75);
@@ -94,4 +95,9 @@ body {
display: flex;
}
}
+
+ .toastify {
+ border-radius: 0;
+ color: $black;
+ }
}
diff --git a/src/server/index.ts b/src/server/index.ts
index 408fe4c..65e54ae 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -58,11 +58,10 @@ export default class Server {
host: sshhost,
auth: sshauth,
port: sshport,
- title,
pass: sshpass,
key: sshkey,
},
- { base, host, port, title, bypasshelmet },
+ { base, host, port, title, bypasshelmet},
command,
{ key: sslkey, cert: sslcert }
);
diff --git a/src/server/interfaces.ts b/src/server/interfaces.ts
index 05b391c..89d8172 100644
--- a/src/server/interfaces.ts
+++ b/src/server/interfaces.ts
@@ -20,6 +20,7 @@ export interface SSLBuffer {
export interface Server {
port: number;
host: string;
+ title: string;
base: string;
bypasshelmet: boolean;
}
diff --git a/src/server/server.ts b/src/server/server.ts
index 5d47e0d..1bcb5c1 100644
--- a/src/server/server.ts
+++ b/src/server/server.ts
@@ -67,7 +67,7 @@ export default function createServer(
.use(favicon(path.join(distDir, 'favicon.ico')))
.use(`${basePath}/public`, express.static(distDir))
.use((req, res, next) => {
- if (req.url === basePath) res.redirect(301, req.url + '/');
+ if (req.url === basePath) res.redirect(301, `${req.url }/`);
else next();
});
diff --git a/src/server/ssl.ts b/src/server/ssl.ts
index 1ab223d..958185b 100644
--- a/src/server/ssl.ts
+++ b/src/server/ssl.ts
@@ -4,7 +4,7 @@ import { isUndefined } from 'lodash';
import { SSL, SSLBuffer } from './interfaces';
export default async function loadSSL(ssl: SSL): Promise {
- if (isUndefined(ssl.key) || isUndefined(ssl.cert)) return {};
+ if (isUndefined(ssl) || isUndefined(ssl.key) || isUndefined(ssl.cert)) return {};
const files = [readFile(resolve(ssl.key)), readFile(resolve(ssl.cert))];
const [key, cert]: Buffer[] = await Promise.all(files);
return { key, cert };
diff --git a/src/server/term.ts b/src/server/term.ts
index af5ba89..742a46a 100644
--- a/src/server/term.ts
+++ b/src/server/term.ts
@@ -44,9 +44,9 @@ export default class Term {
public static login(socket: SocketIO.Socket): Promise {
// Check request-header for username
- let remoteUser = socket.request.headers['remote-user'];
+ const remoteUser = socket.request.headers['remote-user'];
if (remoteUser) {
- return new Promise((resolve,reject) => {
+ return new Promise(resolve => {
resolve(remoteUser);
});
}
diff --git a/src/server/wetty.ts b/src/server/wetty.ts
index 7e18f6b..9eab321 100644
--- a/src/server/wetty.ts
+++ b/src/server/wetty.ts
@@ -16,8 +16,14 @@ export default class WeTTy extends EventEmitter {
*/
public start(
ssh: SSH = { user: '', host: 'localhost', auth: 'password', port: 22 },
- serverConf: Server = { base: '/wetty/', port: 3000, host: '0.0.0.0' },
- command: string = '',
+ serverConf: Server = {
+ base: '/wetty/',
+ port: 3000,
+ host: '0.0.0.0',
+ title: 'WeTTy',
+ bypasshelmet: false,
+ },
+ command = '',
ssl?: SSL
): Promise {
return loadSSL(ssl).then((sslBuffer: SSLBuffer) => {
diff --git a/webpack.config.babel.js b/webpack.config.babel.js
index ee1a8f7..cf410c5 100644
--- a/webpack.config.babel.js
+++ b/webpack.config.babel.js
@@ -4,9 +4,8 @@ import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import nodeExternals from 'webpack-node-externals';
const template = override =>
- Object.assign(
- {
- mode: process.env.NODE_ENV || 'development',
+ ({
+ mode: process.env.NODE_ENV || 'development',
resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
extensions: ['.ts', '.json', '.js', '.node'],
@@ -15,9 +14,8 @@ const template = override =>
stats: {
colors: true,
},
- },
- override
- );
+ ...override
+ });
const entry = (folder, file) =>
path.join(__dirname, 'src', folder, `${file}.ts`);
diff --git a/yarn.lock b/yarn.lock
index 92b726d..99316e4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -756,6 +756,11 @@
dependencies:
"@types/node" "*"
+"@types/eslint-visitor-keys@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
+ integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
+
"@types/events@*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
@@ -801,6 +806,11 @@
dependencies:
"@types/express" "*"
+"@types/json-schema@^7.0.3":
+ version "7.0.3"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636"
+ integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==
+
"@types/lodash@^4.14.138":
version "4.14.138"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.138.tgz#34f52640d7358230308344e579c15b378d91989e"
@@ -882,6 +892,47 @@
dependencies:
"@types/yargs-parser" "*"
+"@typescript-eslint/eslint-plugin@^2.5.0":
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.5.0.tgz#101d96743ce3365b3223df73d641078c9b775903"
+ integrity sha512-ddrJZxp5ns1Lh5ofZQYk3P8RyvKfyz/VcRR4ZiJLHO/ljnQAO8YvTfj268+WJOOadn99mvDiqJA65+HAKoeSPA==
+ dependencies:
+ "@typescript-eslint/experimental-utils" "2.5.0"
+ eslint-utils "^1.4.2"
+ functional-red-black-tree "^1.0.1"
+ regexpp "^2.0.1"
+ tsutils "^3.17.1"
+
+"@typescript-eslint/experimental-utils@2.5.0":
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.5.0.tgz#383a97ded9a7940e5053449f6d73995e782b8fb1"
+ integrity sha512-UgcQGE0GKJVChyRuN1CWqDW8Pnu7+mVst0aWrhiyuUD1J9c+h8woBdT4XddCvhcXDodTDVIfE3DzGHVjp7tUeQ==
+ dependencies:
+ "@types/json-schema" "^7.0.3"
+ "@typescript-eslint/typescript-estree" "2.5.0"
+ eslint-scope "^5.0.0"
+
+"@typescript-eslint/parser@^2.5.0":
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.5.0.tgz#858030ddd808fbbe88e03f42e5971efaccb8218a"
+ integrity sha512-9UBMiAwIDWSl79UyogaBdj3hidzv6exjKUx60OuZuFnJf56tq/UMpdPcX09YmGqE8f4AnAueYtBxV8IcAT3jdQ==
+ dependencies:
+ "@types/eslint-visitor-keys" "^1.0.0"
+ "@typescript-eslint/experimental-utils" "2.5.0"
+ "@typescript-eslint/typescript-estree" "2.5.0"
+ eslint-visitor-keys "^1.1.0"
+
+"@typescript-eslint/typescript-estree@2.5.0":
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.5.0.tgz#40ada624d6217ef092a3a79ed30d947ad4f212ce"
+ integrity sha512-AXURyF8NcA3IsnbjNX1v9qbwa0dDoY9YPcKYR2utvMHoUcu3636zrz0gRWtVAyxbPCkhyKuGg6WZIyi2Fc79CA==
+ dependencies:
+ debug "^4.1.1"
+ glob "^7.1.4"
+ is-glob "^4.0.1"
+ lodash.unescape "4.0.1"
+ semver "^6.3.0"
+
"@webassemblyjs/ast@1.8.5":
version "1.8.5"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
@@ -1051,20 +1102,20 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
mime-types "~2.1.24"
negotiator "0.6.2"
-acorn-jsx@^5.0.2:
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f"
- integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==
+acorn-jsx@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384"
+ integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==
acorn@^6.2.1:
version "6.3.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e"
integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==
-acorn@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.0.0.tgz#26b8d1cd9a9b700350b71c0905546f64d1284e7a"
- integrity sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==
+acorn@^7.1.0:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c"
+ integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==
after@0.8.2:
version "0.8.2"
@@ -2667,7 +2718,7 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
-eslint-config-airbnb-base@^14.0.0:
+eslint-config-airbnb-base@14.0.0:
version "14.0.0"
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz#8a7bcb9643d13c55df4dd7444f138bf4efa61e17"
integrity sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==
@@ -2676,10 +2727,10 @@ eslint-config-airbnb-base@^14.0.0:
object.assign "^4.1.0"
object.entries "^1.1.0"
-eslint-config-prettier@^6.2.0:
- version "6.2.0"
- resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.2.0.tgz#80e0b8714e3f6868c4ac2a25fbf39c02e73527a7"
- integrity sha512-VLsgK/D+S/FEsda7Um1+N8FThec6LqE3vhcMyp8mlmto97y3fGf3DX7byJexGuOb1QY0Z/zz222U5t+xSfcZDQ==
+eslint-config-prettier@^6.4.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.4.0.tgz#0a04f147e31d33c6c161b2dd0971418ac52d0477"
+ integrity sha512-YrKucoFdc7SEko5Sxe4r6ixqXPDP1tunGw91POeZTTRKItf/AMFYt/YLEQtZMkR2LVpAVhcAcZgcWpm1oGPW7w==
dependencies:
get-stdin "^6.0.0"
@@ -2723,15 +2774,7 @@ eslint-plugin-prettier@^3.1.0:
dependencies:
prettier-linter-helpers "^1.0.0"
-eslint-plugin-typescript@^1.0.0-rc.1:
- version "1.0.0-rc.3"
- resolved "https://registry.yarnpkg.com/eslint-plugin-typescript/-/eslint-plugin-typescript-1.0.0-rc.3.tgz#aa5359248dc6172ee261bc6574b5b540573e9b67"
- integrity sha512-urXH7sKqRkFLcDj6dP3tvQALfWIRGn8J8Kg9dYSoavXvy62FxfUv6JgjDAHQZudi9fSRQpEZA/LqdJXDOwKHPA==
- dependencies:
- requireindex "^1.2.0"
- typescript-eslint-parser "21.0.2"
-
-eslint-scope@^4.0.0, eslint-scope@^4.0.3:
+eslint-scope@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848"
integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==
@@ -2747,6 +2790,13 @@ eslint-scope@^5.0.0:
esrecurse "^4.1.0"
estraverse "^4.1.1"
+eslint-utils@^1.3.1:
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f"
+ integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==
+ dependencies:
+ eslint-visitor-keys "^1.1.0"
+
eslint-utils@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab"
@@ -2759,10 +2809,10 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
-eslint@^6.3.0:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.3.0.tgz#1f1a902f67bfd4c354e7288b81e40654d927eb6a"
- integrity sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==
+eslint@6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.1.0.tgz#06438a4a278b1d84fb107d24eaaa35471986e646"
+ integrity sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==
dependencies:
"@babel/code-frame" "^7.0.0"
ajv "^6.10.0"
@@ -2771,9 +2821,9 @@ eslint@^6.3.0:
debug "^4.0.1"
doctrine "^3.0.0"
eslint-scope "^5.0.0"
- eslint-utils "^1.4.2"
- eslint-visitor-keys "^1.1.0"
- espree "^6.1.1"
+ eslint-utils "^1.3.1"
+ eslint-visitor-keys "^1.0.0"
+ espree "^6.0.0"
esquery "^1.0.1"
esutils "^2.0.2"
file-entry-cache "^5.0.1"
@@ -2802,13 +2852,13 @@ eslint@^6.3.0:
text-table "^0.2.0"
v8-compile-cache "^2.0.3"
-espree@^6.1.1:
- version "6.1.1"
- resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de"
- integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==
+espree@^6.0.0:
+ version "6.1.2"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.2.tgz#6c272650932b4f91c3714e5e7b5f5e2ecf47262d"
+ integrity sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==
dependencies:
- acorn "^7.0.0"
- acorn-jsx "^5.0.2"
+ acorn "^7.1.0"
+ acorn-jsx "^5.1.0"
eslint-visitor-keys "^1.1.0"
esprima@^4.0.0:
@@ -3102,6 +3152,11 @@ file-loader@^4.2.0:
loader-utils "^1.2.3"
schema-utils "^2.0.0"
+file-type@^12.3.0:
+ version "12.3.0"
+ resolved "https://registry.yarnpkg.com/file-type/-/file-type-12.3.0.tgz#74d755e5dc9c5cbc7ee6f182529b453906ac88c2"
+ integrity sha512-4E4Esq9KLwjYCY32E7qSmd0h7LefcniZHX+XcdJ4Wfx1uGJX7QCigiqw/U0yT7WOslm28yhxl87DJ0wHYv0RAA==
+
fill-range@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
@@ -4910,12 +4965,7 @@ mute-stream@0.0.7:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
-nan@2.12.1:
- version "2.12.1"
- resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
- integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==
-
-nan@^2.12.1, nan@^2.13.2:
+nan@^2.12.1, nan@^2.13.2, nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
@@ -5047,12 +5097,12 @@ node-pre-gyp@^0.12.0:
semver "^5.3.0"
tar "^4"
-node-pty@^0.8.1:
- version "0.8.1"
- resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.8.1.tgz#94b457bec013e7a09b8d9141f63b0787fa25c23f"
- integrity sha512-j+/g0Q5dR+vkELclpJpz32HcS3O/3EdPSGPvDXJZVJQLCvgG0toEbfmymxAEyQyZEpaoKHAcoL+PvKM+4N9nlw==
+node-pty@0.9.0-beta28:
+ version "0.9.0-beta28"
+ resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.9.0-beta28.tgz#f086cea157b4640bace2ea787136fde73a26b273"
+ integrity sha512-qpLJE52oLRIOEvIeVmPzymn+zqUnYhPmlNjSRW60PwEZvhcdmazdP0IJcQfEK6ivwml14TzQLObMjEj8FFO7xg==
dependencies:
- nan "2.12.1"
+ nan "^2.14.0"
node-releases@^1.1.29:
version "1.1.29"
@@ -6213,11 +6263,6 @@ require-package-name@^2.0.1:
resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9"
integrity sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk=
-requireindex@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef"
- integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==
-
resolve-cwd@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
@@ -6428,11 +6473,6 @@ semver-diff@^2.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-semver@5.5.0:
- version "5.5.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
- integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==
-
semver@^6.1.2, semver@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
@@ -7161,6 +7201,11 @@ to-regex@^3.0.1, to-regex@^3.0.2:
regex-not "^1.0.2"
safe-regex "^1.1.0"
+toastify-js@^1.6.1:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/toastify-js/-/toastify-js-1.6.1.tgz#2ec20654925d6f83f935d5a6907c146e6bcb67d6"
+ integrity sha512-yosiXPEdr3B9KL1rF7M/IMdw8d8Z69UJe2JsvxbfdpaL2/olqSB8tvp7/N6gkT9G46y6nqR2e62CCnf0LxeIBQ==
+
toidentifier@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
@@ -7208,11 +7253,18 @@ triple-beam@^1.2.0, triple-beam@^1.3.0:
dependencies:
glob "^7.1.2"
-tslib@^1.9.0:
+tslib@^1.8.1, tslib@^1.9.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
+tsutils@^3.17.1:
+ version "3.17.1"
+ resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
+ integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==
+ dependencies:
+ tslib "^1.8.1"
+
tty-browserify@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
@@ -7255,23 +7307,6 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-typescript-eslint-parser@21.0.2:
- version "21.0.2"
- resolved "https://registry.yarnpkg.com/typescript-eslint-parser/-/typescript-eslint-parser-21.0.2.tgz#270af10e4724528677fbcf34ea495284bec3a894"
- integrity sha512-u+pj4RVJBr4eTzj0n5npoXD/oRthvfUCjSKndhNI714MG0mQq2DJw5WP7qmonRNIFgmZuvdDOH3BHm9iOjIAfg==
- dependencies:
- eslint-scope "^4.0.0"
- eslint-visitor-keys "^1.0.0"
- typescript-estree "5.3.0"
-
-typescript-estree@5.3.0:
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/typescript-estree/-/typescript-estree-5.3.0.tgz#fb6c977b5e21073eb16cbdc0338a7f752da99ff5"
- integrity sha512-Vu0KmYdSCkpae+J48wsFC1ti19Hq3Wi/lODUaE+uesc3gzqhWbZ5itWbsjylLVbjNW4K41RqDzSfnaYNbmEiMQ==
- dependencies:
- lodash.unescape "4.0.1"
- semver "5.5.0"
-
typescript@~3.6.2:
version "3.6.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.2.tgz#105b0f1934119dde543ac8eb71af3a91009efe54"