feat(plugin-webpack): capture logs into web ui, handle preload scripts
This commit is contained in:
Родитель
8ffab0b445
Коммит
e800049b13
|
@ -51,6 +51,7 @@
|
|||
"electron-packager": "^12.0.1",
|
||||
"electron-rebuild": "^1.6.0",
|
||||
"express": "^4.16.2",
|
||||
"express-ws": "^3.0.0",
|
||||
"form-data": "^2.1.4",
|
||||
"fs-extra": "^5.0.0",
|
||||
"glob": "^7.1.1",
|
||||
|
@ -78,6 +79,7 @@
|
|||
"webpack-dev-middleware": "^2.0.5",
|
||||
"webpack-hot-middleware": "^2.21.0",
|
||||
"webpack-merge": "^4.1.1",
|
||||
"xterm": "^3.3.0",
|
||||
"yarn-or-npm": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -95,6 +97,7 @@
|
|||
"@types/electron-packager": "^10.1.0",
|
||||
"@types/electron-winstaller": "^2.6.1",
|
||||
"@types/express": "^4.11.1",
|
||||
"@types/express-ws": "^3.0.0",
|
||||
"@types/fetch-mock": "^6.0.1",
|
||||
"@types/form-data": "^2.2.1",
|
||||
"@types/fs-extra": "^5.0.2",
|
||||
|
|
|
@ -66,4 +66,4 @@
|
|||
"engines": {
|
||||
"node": ">= 6.0"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,6 +65,7 @@ export default async ({
|
|||
if (typeof spawnedPluginChild === 'string') {
|
||||
electronExecPath = spawnedPluginChild;
|
||||
} else if (spawnedPluginChild) {
|
||||
await runHook(forgeConfig, 'postStart', spawnedPluginChild);
|
||||
return spawnedPluginChild;
|
||||
}
|
||||
|
||||
|
@ -93,5 +94,6 @@ export default async ({
|
|||
spawned = spawn(process.execPath, [electronExecPath, appPath].concat(args as string[]), spawnOpts);
|
||||
});
|
||||
|
||||
await runHook(forgeConfig, 'postStart', spawned);
|
||||
return spawned;
|
||||
};
|
||||
|
|
|
@ -10,17 +10,16 @@
|
|||
"scripts": {
|
||||
"test": "exit 0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.0.0",
|
||||
"mocha": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"engines": {
|
||||
"node": ">= 6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron-forge/async-ora": "6.0.0-beta.10",
|
||||
"@electron-forge/plugin-base": "6.0.0-beta.10",
|
||||
"@electron-forge/web-multi-logger": "^6.0.0-beta.10",
|
||||
"cross-spawn-promise": "^0.10.1",
|
||||
"debug": "^3.0.0",
|
||||
"express": "^4.16.2",
|
||||
"fs-extra": "^5.0.0",
|
||||
"global": "^4.3.2",
|
||||
|
@ -30,4 +29,4 @@
|
|||
"webpack-hot-middleware": "^2.21.0",
|
||||
"webpack-merge": "^4.1.1"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,13 +4,18 @@ export interface WebpackPluginEntryPoint {
|
|||
html: string;
|
||||
js: string;
|
||||
name: string;
|
||||
prefixedEntries?: string[];
|
||||
preload?: WebpackPreloadEntryPoint;
|
||||
}
|
||||
|
||||
export interface WebpackPreloadEntryPoint {
|
||||
js: string;
|
||||
prefixedEntries?: string[];
|
||||
}
|
||||
|
||||
export interface WebpackPluginRendererConfig {
|
||||
config: WebpackConfiguration | string;
|
||||
|
||||
prefixedEntries?: string[];
|
||||
|
||||
entryPoints: WebpackPluginEntryPoint[];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import { asyncOra } from '@electron-forge/async-ora';
|
||||
import PluginBase from '@electron-forge/plugin-base';
|
||||
import Logger from '@electron-forge/web-multi-logger';
|
||||
import Tab from '@electron-forge/web-multi-logger/dist/Tab';
|
||||
import { ChildProcess } from 'child_process';
|
||||
import debug from 'debug';
|
||||
import fs from 'fs-extra';
|
||||
import merge from 'webpack-merge';
|
||||
import path from 'path';
|
||||
|
@ -8,17 +12,23 @@ import webpack, { Configuration } from 'webpack';
|
|||
import webpackHotMiddleware from 'webpack-hot-middleware';
|
||||
import webpackDevMiddleware from 'webpack-dev-middleware';
|
||||
import express from 'express';
|
||||
import http from 'http';
|
||||
|
||||
import HtmlWebpackPlugin, { Config } from 'html-webpack-plugin';
|
||||
|
||||
import { WebpackPluginConfig, WebpackPluginEntryPoint } from './Config';
|
||||
import once from './util/once';
|
||||
import { WebpackPluginConfig, WebpackPluginEntryPoint, WebpackPreloadEntryPoint } from './Config';
|
||||
|
||||
const d = debug('electron-forge:plugin:webpack');
|
||||
const BASE_PORT = 3000;
|
||||
|
||||
export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
|
||||
name = 'webpack';
|
||||
private isProd = false;
|
||||
private baseDir!: string;
|
||||
private watchers: webpack.Compiler.Watching[] = [];
|
||||
private servers: http.Server[] = [];
|
||||
private loggers: Logger[] = [];
|
||||
|
||||
constructor(c: WebpackPluginConfig) {
|
||||
super(c);
|
||||
|
@ -32,8 +42,35 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
|
|||
return config;
|
||||
}
|
||||
|
||||
private exitHandler = (options: { cleanup?: boolean; exit?: boolean }, err?: Error) => {
|
||||
d('handling process exit with:', options);
|
||||
if (options.cleanup) {
|
||||
for (const watcher of this.watchers) {
|
||||
d('cleaning webpack watcher');
|
||||
watcher.close(() => {});
|
||||
}
|
||||
this.watchers = [];
|
||||
for (const server of this.servers) {
|
||||
d('cleaning http server');
|
||||
server.close();
|
||||
}
|
||||
this.servers = [];
|
||||
for (const logger of this.loggers) {
|
||||
d('stopping logger');
|
||||
logger.stop();
|
||||
}
|
||||
this.loggers = [];
|
||||
}
|
||||
if (err) console.error(err.stack);
|
||||
if (options.exit) process.exit();
|
||||
}
|
||||
|
||||
init = (dir: string) => {
|
||||
this.baseDir = path.resolve(dir, '.webpack');
|
||||
|
||||
d('hooking process events');
|
||||
process.on('exit', this.exitHandler.bind(this, { cleanup: true }));
|
||||
process.on('SIGINT', this.exitHandler.bind(this, { exit: true }));
|
||||
}
|
||||
|
||||
getHook(name: string) {
|
||||
|
@ -44,6 +81,13 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
|
|||
await this.compileMain();
|
||||
await this.compileRenderers();
|
||||
};
|
||||
case 'postStart':
|
||||
return async (_: any, child: ChildProcess) => {
|
||||
console.log(child);
|
||||
console.log(Object.keys(child));
|
||||
d('hooking electron process exit');
|
||||
child.on('exit', () => this.exitHandler({ cleanup: true, exit: true }));
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -57,11 +101,21 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
|
|||
|
||||
const defines: { [key: string]: string; } = {};
|
||||
let index = 0;
|
||||
if (!this.config.renderer.entryPoints || !Array.isArray(this.config.renderer.entryPoints)) {
|
||||
throw new Error('Required config option "renderer.entryPoints" has not been defined');
|
||||
}
|
||||
for (const entryPoint of this.config.renderer.entryPoints) {
|
||||
defines[`${entryPoint.name.toUpperCase().replace(/ /g, '_')}_WEBPACK_ENTRY`] =
|
||||
this.isProd
|
||||
? `\`file://\$\{require('path').resolve(__dirname, '../renderer', '${entryPoint.name}', 'index.html')\}\``
|
||||
: `'http://localhost:${BASE_PORT + index}'`;
|
||||
|
||||
if (entryPoint.preload) {
|
||||
defines[`${entryPoint.name.toUpperCase().replace(/ /g, '_')}_PRELOAD_WEBPACK_ENTRY`] =
|
||||
this.isProd
|
||||
? `\`file://\$\{require('path').resolve(__dirname, '../renderer', '${entryPoint.name}', 'preload.js')\}\``
|
||||
: `'${path.resolve(this.baseDir, 'renderer', entryPoint.name, 'preload.js')}'`;
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
return merge.smart({
|
||||
|
@ -79,12 +133,40 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
|
|||
__dirname: false,
|
||||
__filename: false,
|
||||
},
|
||||
resolve: {
|
||||
modules: [
|
||||
path.resolve(path.dirname(this.baseDir), './'),
|
||||
path.resolve(path.dirname(this.baseDir), 'node_modules'),
|
||||
path.resolve(__dirname, '..', 'node_modules'),
|
||||
],
|
||||
},
|
||||
}, mainConfig || {});
|
||||
}
|
||||
|
||||
getPreloadRendererConfig = async (parentPoint: WebpackPluginEntryPoint, entryPoint: WebpackPreloadEntryPoint) => {
|
||||
const rendererConfig = this.resolveConfig(this.config.renderer.config);
|
||||
const prefixedEntries = entryPoint.prefixedEntries || [];
|
||||
|
||||
return merge.smart({
|
||||
devtool: 'inline-source-map',
|
||||
target: 'electron-renderer',
|
||||
entry: prefixedEntries.concat([
|
||||
entryPoint.js,
|
||||
]),
|
||||
output: {
|
||||
path: path.resolve(this.baseDir, 'renderer', parentPoint.name),
|
||||
filename: 'preload.js',
|
||||
},
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false,
|
||||
},
|
||||
}, rendererConfig);
|
||||
}
|
||||
|
||||
getRendererConfig = async (entryPoint: WebpackPluginEntryPoint) => {
|
||||
const rendererConfig = this.resolveConfig(this.config.renderer.config);
|
||||
const prefixedEntries = this.config.renderer.prefixedEntries || [];
|
||||
const prefixedEntries = entryPoint.prefixedEntries || [];
|
||||
return merge.smart({
|
||||
devtool: 'inline-source-map',
|
||||
target: 'electron-renderer',
|
||||
|
@ -108,18 +190,35 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
|
|||
}, rendererConfig);
|
||||
}
|
||||
|
||||
compileMain = async () => {
|
||||
compileMain = async (watch = false, logger?: Logger) => {
|
||||
let tab: Tab;
|
||||
if (logger) {
|
||||
tab = logger.createTab('Main Process');
|
||||
}
|
||||
await asyncOra('Compiling Main Process Code', async () => {
|
||||
await new Promise(async (resolve, reject) => {
|
||||
webpack(await this.getMainConfig()).run((err, stats) => {
|
||||
if (err) return reject(err);
|
||||
resolve();
|
||||
});
|
||||
const compiler = webpack(await this.getMainConfig());
|
||||
const [onceResolve, onceReject] = once(resolve, reject);
|
||||
const cb: webpack.ICompiler.Handler = (err, stats) => {
|
||||
if (tab) {
|
||||
tab.log(stats.toString({
|
||||
colors: true,
|
||||
}));
|
||||
}
|
||||
|
||||
if (err) return onceReject(err);
|
||||
onceResolve();
|
||||
};
|
||||
if (watch) {
|
||||
this.watchers.push(compiler.watch({}, cb));
|
||||
} else {
|
||||
compiler.run(cb);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
compileRenderers = async () => {
|
||||
compileRenderers = async (watch = false) => {
|
||||
for (const entryPoint of this.config.renderer.entryPoints) {
|
||||
await asyncOra(`Compiling Renderer Template: ${entryPoint.name}`, async () => {
|
||||
await new Promise(async (resolve, reject) => {
|
||||
|
@ -128,18 +227,33 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
|
|||
resolve();
|
||||
});
|
||||
});
|
||||
if (entryPoint.preload) {
|
||||
await new Promise(async (resolve, reject) => {
|
||||
webpack(await this.getPreloadRendererConfig(entryPoint, entryPoint.preload!)).run((err, stats) => {
|
||||
if (err) return reject(err);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
launchDevServers = async () => {
|
||||
launchDevServers = async (logger: Logger) => {
|
||||
await asyncOra('Launch Dev Servers', async () => {
|
||||
let index = 0;
|
||||
for (const entryPoint of this.config.renderer.entryPoints) {
|
||||
const tab = logger.createTab(entryPoint.name);
|
||||
|
||||
const config = await this.getRendererConfig(entryPoint);
|
||||
const compiler = webpack(config);
|
||||
const server = webpackDevMiddleware(compiler, {
|
||||
logLevel: 'silent',
|
||||
logger: {
|
||||
log: tab.log.bind(tab),
|
||||
info: tab.log.bind(tab),
|
||||
error: tab.log.bind(tab),
|
||||
warn: tab.log.bind(tab),
|
||||
},
|
||||
publicPath: '/',
|
||||
hot: true,
|
||||
historyApiFallback: true,
|
||||
|
@ -147,15 +261,38 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
|
|||
const app = express();
|
||||
app.use(server);
|
||||
app.use(webpackHotMiddleware(compiler));
|
||||
app.listen(BASE_PORT + index);
|
||||
this.servers.push(app.listen(BASE_PORT + index));
|
||||
index += 1;
|
||||
}
|
||||
});
|
||||
|
||||
await asyncOra('Compile Preload Scripts', async () => {
|
||||
for (const entryPoint of this.config.renderer.entryPoints) {
|
||||
if (entryPoint.preload) {
|
||||
await new Promise(async (resolve, reject) => {
|
||||
const tab = logger.createTab(`${entryPoint.name} - Preload`);
|
||||
const [onceResolve, onceReject] = once(resolve, reject);
|
||||
const cb: webpack.ICompiler.Handler = (err, stats) => {
|
||||
tab.log(stats.toString({
|
||||
colors: true,
|
||||
}));
|
||||
|
||||
if (err) return onceReject(err);
|
||||
onceResolve();
|
||||
};
|
||||
this.watchers.push(webpack(await this.getPreloadRendererConfig(entryPoint, entryPoint.preload!)).watch({}, cb));
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async startLogic(): Promise<false> {
|
||||
await this.compileMain();
|
||||
await this.launchDevServers();
|
||||
const logger = new Logger();
|
||||
this.loggers.push(logger);
|
||||
await this.compileMain(true, logger);
|
||||
await this.launchDevServers(logger);
|
||||
await logger.start();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
export default <A, B>(fn1: A, fn2: B): [A, B] => {
|
||||
let once = true;
|
||||
let val: any;
|
||||
const make = <T>(fn: T): T => {
|
||||
return ((...args: any[]) => {
|
||||
if (once) {
|
||||
val = (fn as any)(...args);
|
||||
once = false;
|
||||
}
|
||||
return val;
|
||||
}) as any as T;
|
||||
};
|
||||
return [
|
||||
make(fn1),
|
||||
make(fn2),
|
||||
];
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "@electron-forge/web-multi-logger",
|
||||
"version": "6.0.0-beta.10",
|
||||
"description": "A helper utility for wrapping async functions in an ora",
|
||||
"repository": "https://github.com/electron-userland/electron-forge",
|
||||
"author": "Samuel Attard",
|
||||
"license": "MIT",
|
||||
"main": "dist/Logger.js",
|
||||
"typings": "dist/Logger.d.ts",
|
||||
"scripts": {
|
||||
"test": "exit 0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"dependencies": {
|
||||
"express": "^4.16.2",
|
||||
"express-ws": "^3.0.0",
|
||||
"xterm": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export default class Log {
|
||||
constructor(public line: string, public timestamp: Date) {}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import express from 'express';
|
||||
import path from 'path';
|
||||
import ews from 'express-ws';
|
||||
import http from 'http';
|
||||
|
||||
import Tab from './Tab';
|
||||
|
||||
export default class Logger {
|
||||
private app = express();
|
||||
private ws!: ews.Instance;
|
||||
private tabs: Tab[] = [];
|
||||
private server: http.Server | null = null;
|
||||
|
||||
constructor(private port = 9000) {
|
||||
this.registerRoutes();
|
||||
}
|
||||
|
||||
registerRoutes() {
|
||||
this.ws = ews(this.app);
|
||||
this.app.get('/rest/tabs', (req, res) => {
|
||||
return res.json(this.tabs);
|
||||
});
|
||||
|
||||
this.app.use('/xterm', express.static(path.resolve(__dirname, '..', 'node_modules', 'xterm', 'dist')));
|
||||
this.app.use(express.static(path.resolve(__dirname, '..', 'static')));
|
||||
(this.app as any).ws('/sub', () => {});
|
||||
}
|
||||
|
||||
createTab(name: string) {
|
||||
const tab = new Tab(name, this.ws);
|
||||
this.tabs.push(tab);
|
||||
return tab;
|
||||
}
|
||||
|
||||
start() {
|
||||
return new Promise<number>((resolve) => {
|
||||
this.server = this.app.listen(this.port, () => resolve(this.port));
|
||||
});
|
||||
}
|
||||
|
||||
stop() {
|
||||
if (this.server) this.server.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
import ews from 'express-ws';
|
||||
|
||||
import Log from './Log';
|
||||
|
||||
let idCounter = 1;
|
||||
|
||||
export default class Tab {
|
||||
private logs: Log[] = [];
|
||||
private id: number;
|
||||
|
||||
constructor(public name: string, private ws: ews.Instance) {
|
||||
this.id = idCounter;
|
||||
idCounter += 1;
|
||||
}
|
||||
|
||||
log(line: string) {
|
||||
const log = new Log(line, new Date());
|
||||
this.logs.push(log);
|
||||
|
||||
for (const client of this.ws.getWss().clients) {
|
||||
client.send(JSON.stringify({
|
||||
tab: this.id,
|
||||
payload: log,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
logs: this.logs,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Electron Forge Logger</title>
|
||||
<link rel="stylesheet" href="/xterm/xterm.css" />
|
||||
<style>
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: #002B36;
|
||||
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,"Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
height: 48px;
|
||||
background: #eee8d5;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.tabs .tab {
|
||||
padding: 0 16px 6px 16px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
transition: background 0.4s ease-in-out, color 0.4s ease-in-out;
|
||||
background: #eee8d5;
|
||||
color: #073642;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tabs .tab:hover, .tabs .tab.selected-tab {
|
||||
background: #586e75;
|
||||
color: #eee8d5;
|
||||
}
|
||||
|
||||
.tabs .tab.selected-tab {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#terminal {
|
||||
margin-top: 20px;
|
||||
height: calc(100vh - 88px);
|
||||
padding-left: 16px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="tabs"></div>
|
||||
|
||||
<div id="terminal"></div>
|
||||
|
||||
<script src="/xterm/xterm.js"></script>
|
||||
<script src="/xterm/addons/fit/fit.js"></script>
|
||||
<script src="/xterm/addons/search/search.js"></script>
|
||||
<script src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,113 @@
|
|||
Terminal.applyAddon(fit);
|
||||
Terminal.applyAddon(search);
|
||||
|
||||
const split = (text) => {
|
||||
return text.split(/\n/g);
|
||||
}
|
||||
|
||||
class Renderer {
|
||||
constructor() {
|
||||
this.term = new Terminal({
|
||||
cursorBlink: false,
|
||||
theme: {
|
||||
foreground: '#93A1A1',
|
||||
background: '#002B36',
|
||||
cursor: '#D30102',
|
||||
cursorAccent: '#D30102',
|
||||
selection: '#2AA19899',
|
||||
black: '#073642',
|
||||
red: '#dc322f',
|
||||
green: '#859900',
|
||||
yellow: '#b58900',
|
||||
blue: '#268bd2',
|
||||
magenta: '#d33682',
|
||||
cyan: '#2aa198',
|
||||
white: '#eee8d5',
|
||||
brightBlack: '#586e75',
|
||||
brightRed: '#cb4b16',
|
||||
brightGreen: '#586e75',
|
||||
brightYellow: '#657b83',
|
||||
brightBlue: '#839496',
|
||||
brightMagenta: '#6c71c4',
|
||||
brightCyan: '#93a1a1',
|
||||
brightWhite: '#fdf6e3'
|
||||
}
|
||||
});
|
||||
this.container = document.querySelector('#terminal');
|
||||
|
||||
this.term.open(this.container);
|
||||
this.term.fit();
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
this.term.fit();
|
||||
});
|
||||
|
||||
this.fetch = this.fetch.bind(this);
|
||||
this.initialRender = this.initialRender.bind(this);
|
||||
this.subscribe = this.subscribe.bind(this);
|
||||
this.renderTabs = this.renderTabs.bind(this);
|
||||
this.fetch();
|
||||
}
|
||||
|
||||
async fetch() {
|
||||
const response = await fetch('/rest/tabs');
|
||||
const tabs = await response.json();
|
||||
this.tabs = tabs;
|
||||
this.renderTabs();
|
||||
|
||||
this.selectTab(tabs[0]);
|
||||
this.subscribe(tabs);
|
||||
}
|
||||
|
||||
subscribe(tabs) {
|
||||
const sub = new WebSocket(`ws://localhost:${location.port}/sub`);
|
||||
sub.onmessage = (message) => {
|
||||
const data = JSON.parse(message.data);
|
||||
const tab = tabs.find(tab => tab.id === data.tab);
|
||||
if (tab) {
|
||||
tab.logs.push(data.payload);
|
||||
if (this.currentTab.id === tab.id) {
|
||||
for (const line of split(data.payload.line)) {
|
||||
this.term.writeln(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderTabs() {
|
||||
const tabsContainer = document.querySelector('.tabs');
|
||||
|
||||
for (const tab of this.tabs) {
|
||||
const elem = document.createElement('span');
|
||||
elem.innerText = tab.name;
|
||||
elem.classList.add('tab');
|
||||
elem.setAttribute('data-id', tab.id);
|
||||
elem.addEventListener('click', () => {
|
||||
this.selectTab(tab);
|
||||
});
|
||||
tabsContainer.appendChild(elem);
|
||||
}
|
||||
}
|
||||
|
||||
selectTab(tab) {
|
||||
const selected = document.querySelector('.selected-tab');
|
||||
if (selected) selected.classList.remove('selected-tab');
|
||||
document.querySelector(`[data-id="${tab.id}"]`).classList.add('selected-tab');
|
||||
this.currentTab = tab;
|
||||
this.initialRender(tab);
|
||||
}
|
||||
|
||||
initialRender(tab) {
|
||||
this.term.clear();
|
||||
for (const log of tab.logs) {
|
||||
for (const line of split(log.line)) {
|
||||
this.term.writeln(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// term.write('Hello from \033[1;3;31mxterm.js\033[0m $ ');
|
||||
|
||||
const r = new Renderer();
|
219
yarn.lock
219
yarn.lock
|
@ -763,7 +763,15 @@
|
|||
"@types/events" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/express@^4.11.1":
|
||||
"@types/express-ws@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/express-ws/-/express-ws-3.0.0.tgz#89674edba2e9141916fc4d4d30fbd4f810e6b80b"
|
||||
dependencies:
|
||||
"@types/express" "*"
|
||||
"@types/express-serve-static-core" "*"
|
||||
"@types/ws" "*"
|
||||
|
||||
"@types/express@*", "@types/express@^4.11.1":
|
||||
version "4.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.11.1.tgz#f99663b3ab32d04cb11db612ef5dd7933f75465b"
|
||||
dependencies:
|
||||
|
@ -1078,6 +1086,13 @@
|
|||
"@types/uglify-js" "*"
|
||||
source-map "^0.6.0"
|
||||
|
||||
"@types/ws@*":
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.0.tgz#a6382c1ad2dc3a68d0650fbb4ce214ca78f2e5bf"
|
||||
dependencies:
|
||||
"@types/events" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
abab@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
|
||||
|
@ -1194,18 +1209,18 @@ ansi-styles@^2.2.1:
|
|||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
|
||||
ansi-styles@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
|
||||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
ansi-to-html@^0.6.4:
|
||||
version "0.6.4"
|
||||
resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.4.tgz#8b14ace87f8b3d25367d03cd5300d60be17cf9e0"
|
||||
dependencies:
|
||||
entities "^1.1.1"
|
||||
|
||||
anymatch@^1.3.0:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
|
||||
|
@ -1469,10 +1484,14 @@ aws-sign2@~0.7.0:
|
|||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
|
||||
aws4@^1.2.1, aws4@^1.6.0:
|
||||
aws4@^1.2.1:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
|
||||
|
||||
aws4@^1.6.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289"
|
||||
|
||||
babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
|
||||
|
@ -1975,7 +1994,7 @@ chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3:
|
|||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0:
|
||||
chalk@^2.0.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796"
|
||||
dependencies:
|
||||
|
@ -1983,17 +2002,17 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0:
|
|||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.2.0"
|
||||
|
||||
chalk@^2.3.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.0.tgz#a060a297a6b57e15b61ca63ce84995daa0fe6e52"
|
||||
chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
chalk@^2.3.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
|
||||
chalk@^2.3.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.0.tgz#a060a297a6b57e15b61ca63ce84995daa0fe6e52"
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
@ -2119,11 +2138,7 @@ cli-cursor@^2.1.0:
|
|||
dependencies:
|
||||
restore-cursor "^2.0.0"
|
||||
|
||||
cli-spinners@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.1.0.tgz#f1847b168844d917a671eb9d147e3df497c90d06"
|
||||
|
||||
cli-spinners@^1.1.0:
|
||||
cli-spinners@^1.0.1, cli-spinners@^1.1.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a"
|
||||
|
||||
|
@ -2204,8 +2219,8 @@ colors@1.0.x:
|
|||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
|
||||
|
||||
colors@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.2.3.tgz#1b152a9c4f6c9f74bc4bb96233ad0b7983b79744"
|
||||
|
||||
colors@^1.2.0:
|
||||
version "1.2.1"
|
||||
|
@ -3413,6 +3428,12 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2:
|
|||
dependencies:
|
||||
homedir-polyfill "^1.0.1"
|
||||
|
||||
express-ws@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/express-ws/-/express-ws-3.0.0.tgz#7ddaaf3b7c758865c099905989911b6234477dbd"
|
||||
dependencies:
|
||||
ws "^2.0.0"
|
||||
|
||||
express@^4.16.2:
|
||||
version "4.16.3"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
|
||||
|
@ -3522,8 +3543,8 @@ eyes@0.1.x:
|
|||
resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
|
||||
|
||||
fast-deep-equal@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
version "2.0.0"
|
||||
|
@ -4294,8 +4315,8 @@ homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1:
|
|||
parse-passwd "^1.0.0"
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.6.0.tgz#23235b29ab230c576aab0d4f13fc046b0b038222"
|
||||
|
||||
html-entities@^1.2.0:
|
||||
version "1.2.1"
|
||||
|
@ -5530,7 +5551,13 @@ mime-db@~1.33.0:
|
|||
version "1.33.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
|
||||
|
||||
mime-types@^2.1.12, mime-types@^2.1.17, mime-types@~2.1.17, mime-types@~2.1.7:
|
||||
mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18:
|
||||
version "2.1.18"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
|
||||
dependencies:
|
||||
mime-db "~1.33.0"
|
||||
|
||||
mime-types@^2.1.17, mime-types@~2.1.7:
|
||||
version "2.1.17"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
|
||||
dependencies:
|
||||
|
@ -5540,12 +5567,6 @@ mime-types@~1.0.1:
|
|||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-1.0.2.tgz#995ae1392ab8affcbfcb2641dd054e943c0d5dce"
|
||||
|
||||
mime-types@~2.1.18:
|
||||
version "2.1.18"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
|
||||
dependencies:
|
||||
mime-db "~1.33.0"
|
||||
|
||||
mime@1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
|
||||
|
@ -5737,8 +5758,8 @@ no-case@^2.2.0:
|
|||
lower-case "^1.1.1"
|
||||
|
||||
node-abi@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.2.0.tgz#e802ac7a2408e2c0593fb3176ffdf8a99a9b4dec"
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.4.0.tgz#3c27515cb842f5bbc132a31254f9f1e1c55c7b83"
|
||||
dependencies:
|
||||
semver "^5.4.1"
|
||||
|
||||
|
@ -6528,7 +6549,7 @@ q@^1.1.2:
|
|||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||
|
||||
qs@6.5.1, qs@~6.5.1:
|
||||
qs@6.5.1:
|
||||
version "6.5.1"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
|
||||
|
||||
|
@ -6540,6 +6561,10 @@ qs@~6.4.0:
|
|||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
|
||||
|
||||
qs@~6.5.1:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
|
||||
querystring-es3@^0.2.0:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
|
||||
|
@ -6658,7 +6683,7 @@ readable-stream@^1.1.8, readable-stream@~1.1.9:
|
|||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
readable-stream@^2.0.1, readable-stream@^2.3.3:
|
||||
readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.3.3:
|
||||
version "2.3.6"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
|
||||
dependencies:
|
||||
|
@ -6670,7 +6695,7 @@ readable-stream@^2.0.1, readable-stream@^2.3.3:
|
|||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2:
|
||||
readable-stream@^2.0.2, readable-stream@^2.1.4, readable-stream@^2.2.2:
|
||||
version "2.3.4"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071"
|
||||
dependencies:
|
||||
|
@ -6819,9 +6844,9 @@ replace-comments-x@^2.0.0:
|
|||
require-coercible-to-string-x "^1.0.0"
|
||||
to-string-x "^1.4.2"
|
||||
|
||||
request@2, request@^2.45.0, request@^2.55.0, request@^2.79.0:
|
||||
version "2.83.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
|
||||
request@2:
|
||||
version "2.85.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa"
|
||||
dependencies:
|
||||
aws-sign2 "~0.7.0"
|
||||
aws4 "^1.6.0"
|
||||
|
@ -6894,6 +6919,33 @@ request@2.81.0:
|
|||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.0.0"
|
||||
|
||||
request@^2.45.0, request@^2.55.0, request@^2.79.0:
|
||||
version "2.83.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
|
||||
dependencies:
|
||||
aws-sign2 "~0.7.0"
|
||||
aws4 "^1.6.0"
|
||||
caseless "~0.12.0"
|
||||
combined-stream "~1.0.5"
|
||||
extend "~3.0.1"
|
||||
forever-agent "~0.6.1"
|
||||
form-data "~2.3.1"
|
||||
har-validator "~5.0.3"
|
||||
hawk "~6.0.2"
|
||||
http-signature "~1.2.0"
|
||||
is-typedarray "~1.0.0"
|
||||
isstream "~0.1.2"
|
||||
json-stringify-safe "~5.0.1"
|
||||
mime-types "~2.1.17"
|
||||
oauth-sign "~0.8.2"
|
||||
performance-now "^2.1.0"
|
||||
qs "~6.5.1"
|
||||
safe-buffer "^5.1.1"
|
||||
stringstream "~0.0.5"
|
||||
tough-cookie "~2.3.3"
|
||||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.1.0"
|
||||
|
||||
require-coercible-to-string-x@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/require-coercible-to-string-x/-/require-coercible-to-string-x-1.0.0.tgz#367b3e9ca67e00324c411b0b498453a74cd5569e"
|
||||
|
@ -7016,7 +7068,13 @@ rx@^4.1.0:
|
|||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
|
||||
|
||||
rxjs@^5.1.1, rxjs@^5.5.2:
|
||||
rxjs@^5.1.1:
|
||||
version "5.5.10"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.10.tgz#fde02d7a614f6c8683d0d1957827f492e09db045"
|
||||
dependencies:
|
||||
symbol-observable "1.0.1"
|
||||
|
||||
rxjs@^5.5.2:
|
||||
version "5.5.6"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.6.tgz#e31fb96d6fd2ff1fd84bcea8ae9c02d007179c02"
|
||||
dependencies:
|
||||
|
@ -7036,14 +7094,18 @@ s3@^4.4.0:
|
|||
rimraf "~2.2.8"
|
||||
streamsink "~1.2.0"
|
||||
|
||||
safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
safe-buffer@5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
|
||||
|
||||
safe-buffer@^5.1.0:
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, 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#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
|
||||
safe-buffer@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7"
|
||||
|
||||
samsam@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50"
|
||||
|
@ -7340,19 +7402,27 @@ spawn-wrap@^1.4.2:
|
|||
signal-exit "^3.0.2"
|
||||
which "^1.3.0"
|
||||
|
||||
spdx-correct@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
|
||||
spdx-correct@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82"
|
||||
dependencies:
|
||||
spdx-license-ids "^1.0.2"
|
||||
spdx-expression-parse "^3.0.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
|
||||
spdx-expression-parse@~1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c"
|
||||
spdx-exceptions@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9"
|
||||
|
||||
spdx-license-ids@^1.0.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
|
||||
spdx-expression-parse@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0"
|
||||
dependencies:
|
||||
spdx-exceptions "^2.1.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
|
||||
spdx-license-ids@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87"
|
||||
|
||||
speedometer@~0.1.2:
|
||||
version "0.1.4"
|
||||
|
@ -7381,8 +7451,8 @@ sprintf-js@~1.0.2:
|
|||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
|
||||
sshpk@^1.7.0:
|
||||
version "1.13.1"
|
||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.1.tgz#130f5975eddad963f1d56f92b9ac6c51fa9f83eb"
|
||||
dependencies:
|
||||
asn1 "~0.2.3"
|
||||
assert-plus "^1.0.0"
|
||||
|
@ -7547,13 +7617,13 @@ supports-color@^4.2.1:
|
|||
dependencies:
|
||||
has-flag "^2.0.0"
|
||||
|
||||
supports-color@^5.1.0, supports-color@^5.2.0:
|
||||
supports-color@^5.1.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a"
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
supports-color@^5.3.0:
|
||||
supports-color@^5.2.0, supports-color@^5.3.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
|
||||
dependencies:
|
||||
|
@ -7813,12 +7883,18 @@ touch@^3.1.0:
|
|||
dependencies:
|
||||
nopt "~1.0.10"
|
||||
|
||||
tough-cookie@>=0.12.0, tough-cookie@^2.2.0, tough-cookie@~2.3.0, tough-cookie@~2.3.3:
|
||||
tough-cookie@>=0.12.0, tough-cookie@^2.2.0, tough-cookie@~2.3.0:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
|
||||
dependencies:
|
||||
punycode "^1.4.1"
|
||||
|
||||
tough-cookie@~2.3.3:
|
||||
version "2.3.4"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
|
||||
dependencies:
|
||||
punycode "^1.4.1"
|
||||
|
||||
tr46@~0.0.1:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
|
@ -8043,6 +8119,10 @@ uid-number@^0.0.6:
|
|||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
|
||||
|
||||
ultron@~1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
|
||||
|
||||
undefsafe@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76"
|
||||
|
@ -8231,11 +8311,11 @@ uuid@^3.0.0, uuid@^3.1.0:
|
|||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
|
||||
|
||||
validate-npm-package-license@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338"
|
||||
dependencies:
|
||||
spdx-correct "~1.0.0"
|
||||
spdx-expression-parse "~1.0.0"
|
||||
spdx-correct "^3.0.0"
|
||||
spdx-expression-parse "^3.0.0"
|
||||
|
||||
validate.io-undefined@^1.0.3:
|
||||
version "1.0.3"
|
||||
|
@ -8450,6 +8530,13 @@ write-file-atomic@^2.0.0:
|
|||
imurmurhash "^0.1.4"
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
ws@^2.0.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-2.3.1.tgz#6b94b3e447cb6a363f785eaf94af6359e8e81c80"
|
||||
dependencies:
|
||||
safe-buffer "~5.0.1"
|
||||
ultron "~1.1.0"
|
||||
|
||||
xdg-basedir@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
|
||||
|
@ -8499,6 +8586,10 @@ xtend@~2.1.1:
|
|||
dependencies:
|
||||
object-keys "~0.4.0"
|
||||
|
||||
xterm@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.3.0.tgz#b09a19fc2cd5decd21112e5c9dab0b61991f6cf3"
|
||||
|
||||
y18n@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
|
||||
|
|
Загрузка…
Ссылка в новой задаче