From dd0b60416ea0096b04af2ae463a6b188f9b44b2f Mon Sep 17 00:00:00 2001 From: afrokick Date: Thu, 22 Aug 2019 20:59:55 +0300 Subject: [PATCH 1/6] ref --- .eslintrc.json | 19 - .gitignore | 4 +- bin/peerjs | 63 +- config/index.js | 15 - config/index.ts | 33 + dist/app.json | 5 + dist/config/index.js | 18 + dist/src/api/index.js | 24 + dist/src/api/middleware/auth/index.js | 27 + dist/src/api/middleware/middleware.js | 2 + dist/src/api/v1/calls/index.js | 30 + dist/src/api/v1/public/index.js | 23 + dist/src/enums.js | 21 + dist/src/index.js | 106 + dist/src/messageHandler/handler.js | 2 + .../handlers/heartbeat/index.js | 8 + .../handlers/transmission/index.js | 57 + dist/src/messageHandler/index.js | 35 + dist/src/messageHandler/messageHandlers.js | 22 + dist/src/models/client.js | 32 + dist/src/models/message.js | 2 + dist/src/models/messageQueue.js | 25 + dist/src/models/realm.js | 50 + .../services/checkBrokenConnections/index.js | 56 + dist/src/services/messagesExpire/index.js | 54 + dist/src/services/webSocketServer/index.js | 91 + .../src/services/webSocketServer/webSocket.js | 2 + package-lock.json | 3627 +++++++++++------ package.json | 34 +- src/api/index.js | 23 - src/api/index.ts | 33 + src/api/middleware/auth/index.js | 25 - src/api/middleware/auth/index.ts | 35 + src/api/middleware/middleware.ts | 5 + src/api/v1/calls/index.js | 36 - src/api/v1/calls/index.ts | 36 + src/api/v1/public/{index.js => index.ts} | 14 +- src/enums.js | 18 - src/enums.ts | 18 + src/index.js | 134 - src/index.ts | 152 + src/messageHandler/handler.ts | 4 + .../handlers/heartbeat/index.js | 4 - .../handlers/heartbeat/index.ts | 7 + .../handlers/transmission/index.js | 49 - .../handlers/transmission/index.ts | 58 + src/messageHandler/index.js | 49 - src/messageHandler/index.ts | 43 + src/messageHandler/messageHandlers.ts | 29 + src/models/client.js | 38 - src/models/client.ts | 57 + src/models/message.ts | 8 + src/models/messageQueue.js | 30 - src/models/messageQueue.ts | 37 + src/models/realm.js | 58 - src/models/realm.ts | 82 + src/services/checkBrokenConnections/index.js | 57 - src/services/checkBrokenConnections/index.ts | 73 + src/services/messagesExpire/index.js | 63 - src/services/messagesExpire/index.ts | 81 + src/services/webSocketServer/index.js | 114 - src/services/webSocketServer/index.ts | 137 + src/services/webSocketServer/webSocket.ts | 4 + .../handlers/heartbeat/index.js | 2 +- tsconfig.json | 31 + tslint.json | 20 + 66 files changed, 4214 insertions(+), 1937 deletions(-) delete mode 100644 .eslintrc.json delete mode 100644 config/index.js create mode 100644 config/index.ts create mode 100644 dist/app.json create mode 100644 dist/config/index.js create mode 100644 dist/src/api/index.js create mode 100644 dist/src/api/middleware/auth/index.js create mode 100644 dist/src/api/middleware/middleware.js create mode 100644 dist/src/api/v1/calls/index.js create mode 100644 dist/src/api/v1/public/index.js create mode 100644 dist/src/enums.js create mode 100644 dist/src/index.js create mode 100644 dist/src/messageHandler/handler.js create mode 100644 dist/src/messageHandler/handlers/heartbeat/index.js create mode 100644 dist/src/messageHandler/handlers/transmission/index.js create mode 100644 dist/src/messageHandler/index.js create mode 100644 dist/src/messageHandler/messageHandlers.js create mode 100644 dist/src/models/client.js create mode 100644 dist/src/models/message.js create mode 100644 dist/src/models/messageQueue.js create mode 100644 dist/src/models/realm.js create mode 100644 dist/src/services/checkBrokenConnections/index.js create mode 100644 dist/src/services/messagesExpire/index.js create mode 100644 dist/src/services/webSocketServer/index.js create mode 100644 dist/src/services/webSocketServer/webSocket.js delete mode 100644 src/api/index.js create mode 100644 src/api/index.ts delete mode 100644 src/api/middleware/auth/index.js create mode 100644 src/api/middleware/auth/index.ts create mode 100644 src/api/middleware/middleware.ts delete mode 100644 src/api/v1/calls/index.js create mode 100644 src/api/v1/calls/index.ts rename src/api/v1/public/{index.js => index.ts} (51%) delete mode 100644 src/enums.js create mode 100644 src/enums.ts delete mode 100644 src/index.js create mode 100644 src/index.ts create mode 100644 src/messageHandler/handler.ts delete mode 100644 src/messageHandler/handlers/heartbeat/index.js create mode 100644 src/messageHandler/handlers/heartbeat/index.ts delete mode 100644 src/messageHandler/handlers/transmission/index.js create mode 100644 src/messageHandler/handlers/transmission/index.ts delete mode 100644 src/messageHandler/index.js create mode 100644 src/messageHandler/index.ts create mode 100644 src/messageHandler/messageHandlers.ts delete mode 100644 src/models/client.js create mode 100644 src/models/client.ts create mode 100644 src/models/message.ts delete mode 100644 src/models/messageQueue.js create mode 100644 src/models/messageQueue.ts delete mode 100644 src/models/realm.js create mode 100644 src/models/realm.ts delete mode 100644 src/services/checkBrokenConnections/index.js create mode 100644 src/services/checkBrokenConnections/index.ts delete mode 100644 src/services/messagesExpire/index.js create mode 100644 src/services/messagesExpire/index.ts delete mode 100644 src/services/webSocketServer/index.js create mode 100644 src/services/webSocketServer/index.ts create mode 100644 src/services/webSocketServer/webSocket.ts create mode 100644 tsconfig.json create mode 100644 tslint.json diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 738756d..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": [ - "eslint:recommended" - ], - "env": { - "node": true, - "es6": true, - "mocha": true - }, - "parserOptions": { - "ecmaVersion": 2018, - "sourceType": "module", - "allowImportExportEverywhere": true - }, - "rules": { - "no-var": "error", - "no-console": "off" - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index e372c24..16bd87a 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,6 @@ results node_modules npm-debug.log -.idea \ No newline at end of file +.idea +.cache +.vscode \ No newline at end of file diff --git a/bin/peerjs b/bin/peerjs index 01c4a8f..9d45ca8 100755 --- a/bin/peerjs +++ b/bin/peerjs @@ -1,69 +1,70 @@ #!/usr/bin/env node +// tslint:disable -const path = require('path'); -const pkg = require('../package.json'); -const fs = require('fs'); +const path = require("path"); +const pkg = require("../package.json"); +const fs = require("fs"); const version = pkg.version; -const PeerServer = require('../src').PeerServer; -const opts = require('optimist') - .usage('Usage: $0') +const { PeerServer } = require("../dist/src"); +const opts = require("optimist") + .usage("Usage: $0") .options({ expire_timeout: { demand: false, - alias: 't', - description: 'timeout (milliseconds)', + alias: "t", + description: "timeout (milliseconds)", default: 5000 }, concurrent_limit: { demand: false, - alias: 'c', - description: 'concurrent limit', + alias: "c", + description: "concurrent limit", default: 5000 }, alive_timeout: { demand: false, - description: 'broken connection check timeout (milliseconds)', + description: "broken connection check timeout (milliseconds)", default: 60000 }, key: { demand: false, - alias: 'k', - description: 'connection key', - default: 'peerjs' + alias: "k", + description: "connection key", + default: "peerjs" }, sslkey: { demand: false, - description: 'path to SSL key' + description: "path to SSL key" }, sslcert: { demand: false, - description: 'path to SSL certificate' + description: "path to SSL certificate" }, port: { demand: true, - alias: 'p', - description: 'port' + alias: "p", + description: "port" }, path: { demand: false, - description: 'custom path', - default: '/' + description: "custom path", + default: "/" }, allow_discovery: { demand: false, - description: 'allow discovery of peers' + description: "allow discovery of peers" }, proxied: { demand: false, - description: 'Set true if PeerServer stays behind a reverse proxy', + description: "Set true if PeerServer stays behind a reverse proxy", default: false } }) - .boolean('allow_discovery') + .boolean("allow_discovery") .argv; -process.on('uncaughtException', function (e) { - console.error('Error: ' + e); +process.on("uncaughtException", function (e) { + console.error("Error: " + e); }); if (opts.sslkey || opts.sslcert) { @@ -76,8 +77,8 @@ if (opts.sslkey || opts.sslcert) { delete opts.sslkey; delete opts.sslcert; } else { - console.error('Warning: PeerServer will not run because either ' + - 'the key or the certificate has not been provided.'); + console.error("Warning: PeerServer will not run because either " + + "the key or the certificate has not been provided."); process.exit(1); } } @@ -88,15 +89,15 @@ const server = PeerServer(opts, server => { const port = server.address().port; console.log( - 'Started PeerServer on %s, port: %s, path: %s (v. %s)', - host, port, userPath || '/', version + "Started PeerServer on %s, port: %s, path: %s (v. %s)", + host, port, userPath || "/", version ); }); -server.on('connection', client => { +server.on("connection", client => { console.log(`Client connected: ${client.getId()}`); }); -server.on('disconnect', client => { +server.on("disconnect", client => { console.log(`Client disconnected: ${client.getId()}`); }); diff --git a/config/index.js b/config/index.js deleted file mode 100644 index 3b0ecb4..0000000 --- a/config/index.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - port: 9000, - expire_timeout: 5000, - alive_timeout: 60000, - key: 'peerjs', - path: '/myapp', - concurrent_limit: 5000, - allow_discovery: false, - proxied: false, - cleanup_out_msgs: 1000, - ssl: { - key: '', - cert: '' - } -}; diff --git a/config/index.ts b/config/index.ts new file mode 100644 index 0000000..cfff64c --- /dev/null +++ b/config/index.ts @@ -0,0 +1,33 @@ +export interface IConfig { + readonly port: number; + readonly expire_timeout: number; + readonly alive_timeout: number; + readonly key: string; + readonly path: string; + readonly concurrent_limit: number; + readonly allow_discovery: boolean; + readonly proxied: boolean | string; + readonly cleanup_out_msgs: number; + readonly ssl: { + key: string; + cert: string; + }; +} + +const defaultConfig: IConfig = { + port: 9000, + expire_timeout: 5000, + alive_timeout: 60000, + key: "peerjs", + path: "/myapp", + concurrent_limit: 5000, + allow_discovery: false, + proxied: false, + cleanup_out_msgs: 1000, + ssl: { + key: "", + cert: "" + } +}; + +export default defaultConfig; diff --git a/dist/app.json b/dist/app.json new file mode 100644 index 0000000..6490e45 --- /dev/null +++ b/dist/app.json @@ -0,0 +1,5 @@ +{ + "name": "PeerJS Server", + "description": "A server side element to broker connections between PeerJS clients.", + "website": "http://peerjs.com/" +} diff --git a/dist/config/index.js b/dist/config/index.js new file mode 100644 index 0000000..b95d622 --- /dev/null +++ b/dist/config/index.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const defaultConfig = { + port: 9000, + expire_timeout: 5000, + alive_timeout: 60000, + key: "peerjs", + path: "/myapp", + concurrent_limit: 5000, + allow_discovery: false, + proxied: false, + cleanup_out_msgs: 1000, + ssl: { + key: "", + cert: "" + } +}; +exports.default = defaultConfig; diff --git a/dist/src/api/index.js b/dist/src/api/index.js new file mode 100644 index 0000000..ed7fabc --- /dev/null +++ b/dist/src/api/index.js @@ -0,0 +1,24 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const body_parser_1 = __importDefault(require("body-parser")); +const cors_1 = __importDefault(require("cors")); +const express_1 = __importDefault(require("express")); +const app_json_1 = __importDefault(require("../../app.json")); +const auth_1 = require("./middleware/auth"); +const calls_1 = __importDefault(require("./v1/calls")); +const public_1 = __importDefault(require("./v1/public")); +exports.Api = ({ config, realm, messageHandler }) => { + const authMiddleware = new auth_1.AuthMiddleware(config, realm); + const app = express_1.default.Router(); + const jsonParser = body_parser_1.default.json(); + app.use(cors_1.default()); + app.get("/", (_, res) => { + res.send(app_json_1.default); + }); + app.use("/:key", public_1.default({ config, realm })); + app.use("/:key/:id/:token", authMiddleware.handle, jsonParser, calls_1.default({ realm, messageHandler })); + return app; +}; diff --git a/dist/src/api/middleware/auth/index.js b/dist/src/api/middleware/auth/index.js new file mode 100644 index 0000000..11d15ca --- /dev/null +++ b/dist/src/api/middleware/auth/index.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const enums_1 = require("../../../enums"); +class AuthMiddleware { + constructor(config, realm) { + this.config = config; + this.realm = realm; + } + handle(req, res, next) { + const { id, token, key } = req.params; + if (key !== this.config.key) { + return res.status(401).send(enums_1.Errors.INVALID_KEY); + } + if (!id) { + return res.sendStatus(401); + } + const client = this.realm.getClientById(id); + if (!client) { + return res.sendStatus(401); + } + if (client.getToken() && token !== client.getToken()) { + return res.status(401).send(enums_1.Errors.INVALID_TOKEN); + } + next(); + } +} +exports.AuthMiddleware = AuthMiddleware; diff --git a/dist/src/api/middleware/middleware.js b/dist/src/api/middleware/middleware.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/dist/src/api/middleware/middleware.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/dist/src/api/v1/calls/index.js b/dist/src/api/v1/calls/index.js new file mode 100644 index 0000000..807208c --- /dev/null +++ b/dist/src/api/v1/calls/index.js @@ -0,0 +1,30 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const express_1 = __importDefault(require("express")); +exports.default = ({ realm, messageHandler }) => { + const app = express_1.default.Router(); + const handle = (req, res, next) => { + const { id } = req.params; + if (!id) { + return next(); + } + const client = realm.getClientById(id); + const { type, dst, payload } = req.body; + const message = { + type, + src: id, + dst, + payload + }; + messageHandler.handle(client, message); + res.sendStatus(200); + }; + app.post("/offer", handle); + app.post("/candidate", handle); + app.post("/answer", handle); + app.post("/leave", handle); + return app; +}; diff --git a/dist/src/api/v1/public/index.js b/dist/src/api/v1/public/index.js new file mode 100644 index 0000000..1bf69f9 --- /dev/null +++ b/dist/src/api/v1/public/index.js @@ -0,0 +1,23 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const express_1 = __importDefault(require("express")); +exports.default = ({ config, realm }) => { + const app = express_1.default.Router(); + // Retrieve guaranteed random ID. + app.get("/id", (_, res) => { + res.contentType("html"); + res.send(realm.generateClientId()); + }); + // Get a list of all peers for a key, enabled by the `allowDiscovery` flag. + app.get("/peers", (_, res) => { + if (config.allow_discovery) { + const clientsIds = realm.getClientsIds(); + return res.send(clientsIds); + } + res.sendStatus(401); + }); + return app; +}; diff --git a/dist/src/enums.js b/dist/src/enums.js new file mode 100644 index 0000000..7670504 --- /dev/null +++ b/dist/src/enums.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Errors; +(function (Errors) { + Errors["INVALID_KEY"] = "Invalid key provided"; + Errors["INVALID_TOKEN"] = "Invalid token provided"; + Errors["INVALID_WS_PARAMETERS"] = "No id, token, or key supplied to websocket server"; + Errors["CONNECTION_LIMIT_EXCEED"] = "Server has reached its concurrent user limit"; +})(Errors = exports.Errors || (exports.Errors = {})); +var MessageType; +(function (MessageType) { + MessageType["OPEN"] = "OPEN"; + MessageType["LEAVE"] = "LEAVE"; + MessageType["CANDIDATE"] = "CANDIDATE"; + MessageType["OFFER"] = "OFFER"; + MessageType["ANSWER"] = "ANSWER"; + MessageType["EXPIRE"] = "EXPIRE"; + MessageType["HEARTBEAT"] = "HEARTBEAT"; + MessageType["ID_TAKEN"] = "ID-TAKEN"; + MessageType["ERROR"] = "ERROR"; +})(MessageType = exports.MessageType || (exports.MessageType = {})); diff --git a/dist/src/index.js b/dist/src/index.js new file mode 100644 index 0000000..948f4e4 --- /dev/null +++ b/dist/src/index.js @@ -0,0 +1,106 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const express_1 = __importDefault(require("express")); +const http_1 = __importDefault(require("http")); +const https_1 = __importDefault(require("https")); +const config_1 = __importDefault(require("../config")); +const api_1 = require("./api"); +const messageHandler_1 = require("./messageHandler"); +const realm_1 = require("./models/realm"); +const checkBrokenConnections_1 = require("./services/checkBrokenConnections"); +const messagesExpire_1 = require("./services/messagesExpire"); +const webSocketServer_1 = require("./services/webSocketServer"); +const init = ({ app, server, options }) => { + const config = options; + const realm = new realm_1.Realm(); + const messageHandler = new messageHandler_1.MessageHandler(realm); + const api = api_1.Api({ config, realm, messageHandler }); + const messagesExpire = new messagesExpire_1.MessagesExpire({ realm, config, messageHandler }); + const checkBrokenConnections = new checkBrokenConnections_1.CheckBrokenConnections({ + realm, + config, + onClose: (client) => { + app.emit("disconnect", client); + } + }); + app.use(options.path, api); + const wss = new webSocketServer_1.WebSocketServer({ + server, + realm, + config: Object.assign({}, config) + }); + wss.on("connection", (client) => { + const messageQueue = realm.getMessageQueueById(client.getId()); + if (messageQueue) { + let message; + // tslint:disable + while (message = messageQueue.readMessage()) { + messageHandler.handle(client, message); + } + realm.clearMessageQueue(client.getId()); + } + app.emit("connection", client); + }); + wss.on("message", (client, message) => { + app.emit("message", client, message); + messageHandler.handle(client, message); + }); + wss.on("close", (client) => { + app.emit("disconnect", client); + }); + wss.on("error", (error) => { + app.emit("error", error); + }); + messagesExpire.startMessagesExpiration(); + checkBrokenConnections.start(); +}; +function ExpressPeerServer(server, options) { + const app = express_1.default(); + const newOptions = Object.assign({}, config_1.default, options); + if (newOptions.proxied) { + app.set("trust proxy", newOptions.proxied === "false" ? false : !!newOptions.proxied); + } + app.on("mount", () => { + if (!server) { + throw new Error("Server is not passed to constructor - " + + "can't start PeerServer"); + } + init({ app, server, options: newOptions }); + }); + return app; +} +exports.ExpressPeerServer = ExpressPeerServer; +function PeerServer(options = {}, callback) { + const app = express_1.default(); + const newOptions = Object.assign({}, config_1.default, options); + let path = newOptions.path; + const port = newOptions.port; + if (path[0] !== "/") { + path = "/" + path; + } + if (path[path.length - 1] !== "/") { + path += "/"; + } + let server; + if (newOptions.ssl && newOptions.ssl.key && newOptions.ssl.cert) { + server = https_1.default.createServer(options.ssl, app); + // @ts-ignore + delete newOptions.ssl; + } + else { + server = http_1.default.createServer(app); + } + const peerjs = ExpressPeerServer(server, newOptions); + app.use(peerjs); + if (callback) { + server.listen(port, () => callback(server)); + } + else { + server.listen(port); + } + return peerjs; +} +exports.PeerServer = PeerServer; diff --git a/dist/src/messageHandler/handler.js b/dist/src/messageHandler/handler.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/dist/src/messageHandler/handler.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/dist/src/messageHandler/handlers/heartbeat/index.js b/dist/src/messageHandler/handlers/heartbeat/index.js new file mode 100644 index 0000000..80c7b6a --- /dev/null +++ b/dist/src/messageHandler/handlers/heartbeat/index.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function default_1(client) { + const nowTime = new Date().getTime(); + client.setLastPing(nowTime); + return true; +} +exports.default = default_1; diff --git a/dist/src/messageHandler/handlers/transmission/index.js b/dist/src/messageHandler/handlers/transmission/index.js new file mode 100644 index 0000000..f099da5 --- /dev/null +++ b/dist/src/messageHandler/handlers/transmission/index.js @@ -0,0 +1,57 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const enums_1 = require("../../../enums"); +function default_1({ realm }) { + const handle = (client, message) => { + const type = message.type; + const srcId = message.src; + const dstId = message.dst; + const destinationClient = realm.getClientById(dstId); + // User is connected! + if (destinationClient) { + try { + if (destinationClient.getSocket()) { + const data = JSON.stringify(message); + destinationClient.getSocket().send(data); + } + else { + // Neither socket no res available. Peer dead? + throw new Error("Peer dead"); + } + } + catch (e) { + // This happens when a peer disconnects without closing connections and + // the associated WebSocket has not closed. + // Tell other side to stop trying. + if (destinationClient.getSocket()) { + destinationClient.getSocket().close(); + } + else { + realm.removeClientById(destinationClient.getId()); + } + handle(client, { + type: enums_1.MessageType.LEAVE, + src: dstId, + dst: srcId + }); + } + } + else { + // Wait for this client to connect/reconnect (XHR) for important + // messages. + if (type !== enums_1.MessageType.LEAVE && type !== enums_1.MessageType.EXPIRE && dstId) { + realm.addMessageToQueue(dstId, message); + } + else if (type === enums_1.MessageType.LEAVE && !dstId) { + realm.removeClientById(srcId); + } + else { + // Unavailable destination specified with message LEAVE or EXPIRE + // Ignore + } + } + return true; + }; + return handle; +} +exports.default = default_1; diff --git a/dist/src/messageHandler/index.js b/dist/src/messageHandler/index.js new file mode 100644 index 0000000..0cdaa9f --- /dev/null +++ b/dist/src/messageHandler/index.js @@ -0,0 +1,35 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const enums_1 = require("../enums"); +const heartbeat_1 = __importDefault(require("./handlers/heartbeat")); +const transmission_1 = __importDefault(require("./handlers/transmission")); +const messageHandlers_1 = require("./messageHandlers"); +class MessageHandler { + constructor(realm) { + this.messageHandlers = new messageHandlers_1.MessageHandlers(); + const transmissionHandler = transmission_1.default({ realm }); + const heartbeatHandler = heartbeat_1.default; + const handleTransmission = (client, message) => { + return transmissionHandler(client, { + type: message.type, + src: message.src, + dst: message.dst, + payload: message.payload + }); + }; + const handleHeartbeat = (client, message) => heartbeatHandler(client, message); + this.messageHandlers.registerHandler(enums_1.MessageType.HEARTBEAT, handleHeartbeat); + this.messageHandlers.registerHandler(enums_1.MessageType.OFFER, handleTransmission); + this.messageHandlers.registerHandler(enums_1.MessageType.ANSWER, handleTransmission); + this.messageHandlers.registerHandler(enums_1.MessageType.CANDIDATE, handleTransmission); + this.messageHandlers.registerHandler(enums_1.MessageType.LEAVE, handleTransmission); + this.messageHandlers.registerHandler(enums_1.MessageType.EXPIRE, handleTransmission); + } + handle(client, message) { + return this.messageHandlers.handle(client, message); + } +} +exports.MessageHandler = MessageHandler; diff --git a/dist/src/messageHandler/messageHandlers.js b/dist/src/messageHandler/messageHandlers.js new file mode 100644 index 0000000..167f3d6 --- /dev/null +++ b/dist/src/messageHandler/messageHandlers.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class MessageHandlers { + constructor() { + this.handlers = new Map(); + } + registerHandler(messageType, handler) { + if (this.handlers.has(messageType)) { + return; + } + this.handlers.set(messageType, handler); + } + handle(client, message) { + const { type } = message; + const handler = this.handlers.get(type); + if (!handler) { + return false; + } + return handler(client, message); + } +} +exports.MessageHandlers = MessageHandlers; diff --git a/dist/src/models/client.js b/dist/src/models/client.js new file mode 100644 index 0000000..084d0b6 --- /dev/null +++ b/dist/src/models/client.js @@ -0,0 +1,32 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class Client { + constructor({ id, token }) { + this.socket = null; + this.lastPing = new Date().getTime(); + this.id = id; + this.token = token; + } + getId() { + return this.id; + } + getToken() { + return this.token; + } + getSocket() { + return this.socket; + } + setSocket(socket) { + this.socket = socket; + } + getLastPing() { + return this.lastPing; + } + setLastPing(lastPing) { + this.lastPing = lastPing; + } + send(data) { + this.socket.send(JSON.stringify(data)); + } +} +exports.Client = Client; diff --git a/dist/src/models/message.js b/dist/src/models/message.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/dist/src/models/message.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/dist/src/models/messageQueue.js b/dist/src/models/messageQueue.js new file mode 100644 index 0000000..fbe3a77 --- /dev/null +++ b/dist/src/models/messageQueue.js @@ -0,0 +1,25 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class MessageQueue { + constructor() { + this.lastReadAt = new Date().getTime(); + this.messages = []; + } + getLastReadAt() { + return this.lastReadAt; + } + addMessage(message) { + this.messages.push(message); + } + readMessage() { + if (this.messages.length > 0) { + this.lastReadAt = new Date().getTime(); + return this.messages.shift(); + } + return null; + } + getMessages() { + return this.messages; + } +} +exports.MessageQueue = MessageQueue; diff --git a/dist/src/models/realm.js b/dist/src/models/realm.js new file mode 100644 index 0000000..3682847 --- /dev/null +++ b/dist/src/models/realm.js @@ -0,0 +1,50 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const messageQueue_1 = require("./messageQueue"); +class Realm { + constructor() { + this.clients = new Map(); + this.messageQueues = new Map(); + } + getClientsIds() { + return [...this.clients.keys()]; + } + getClientById(clientId) { + return this.clients.get(clientId); + } + getClientsIdsWithQueue() { + return [...this.messageQueues.keys()]; + } + setClient(client, id) { + this.clients.set(id, client); + } + removeClientById(id) { + const client = this.getClientById(id); + if (!client) { + return false; + } + this.clients.delete(id); + return true; + } + getMessageQueueById(id) { + return this.messageQueues.get(id); + } + addMessageToQueue(id, message) { + if (!this.getMessageQueueById(id)) { + this.messageQueues.set(id, new messageQueue_1.MessageQueue()); + } + this.getMessageQueueById(id).addMessage(message); + } + clearMessageQueue(id) { + this.messageQueues.delete(id); + } + generateClientId() { + const randomId = () => (Math.random().toString(36) + "0000000000000000000").substr(2, 16); + let clientId = randomId(); + while (this.getClientById(clientId)) { + clientId = randomId(); + } + return clientId; + } +} +exports.Realm = Realm; diff --git a/dist/src/services/checkBrokenConnections/index.js b/dist/src/services/checkBrokenConnections/index.js new file mode 100644 index 0000000..0d8d7fe --- /dev/null +++ b/dist/src/services/checkBrokenConnections/index.js @@ -0,0 +1,56 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const DEFAULT_CHECK_INTERVAL = 300; +class CheckBrokenConnections { + constructor({ realm, config, checkInterval = DEFAULT_CHECK_INTERVAL, onClose }) { + this.realm = realm; + this.config = config; + this.onClose = onClose; + this.checkInterval = checkInterval; + } + start() { + if (this.timeoutId) { + clearTimeout(this.timeoutId); + } + this.timeoutId = setTimeout(() => { + this.checkConnections(); + this.timeoutId = null; + this.start(); + }, this.checkInterval); + } + stop() { + if (this.timeoutId) { + clearTimeout(this.timeoutId); + this.timeoutId = null; + } + } + checkConnections() { + const clientsIds = this.realm.getClientsIds(); + const now = new Date().getTime(); + const aliveTimeout = this.config.alive_timeout; + for (const clientId of clientsIds) { + const client = this.realm.getClientById(clientId); + const timeSinceLastPing = now - client.getLastPing(); + if (timeSinceLastPing < aliveTimeout) { + continue; + } + try { + if (client.getSocket()) { + client.getSocket().close(); + } + } + catch (e) { + // @ts-nocheck + } + finally { + this.realm.clearMessageQueue(clientId); + this.realm.removeClientById(clientId); + client.setSocket(null); + if (this.onClose) { + this.onClose(client); + } + } + } + } +} +exports.CheckBrokenConnections = CheckBrokenConnections; diff --git a/dist/src/services/messagesExpire/index.js b/dist/src/services/messagesExpire/index.js new file mode 100644 index 0000000..7e63c3b --- /dev/null +++ b/dist/src/services/messagesExpire/index.js @@ -0,0 +1,54 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const enums_1 = require("../../enums"); +class MessagesExpire { + constructor({ realm, config, messageHandler }) { + this.timeoutId = null; + this.realm = realm; + this.config = config; + this.messageHandler = messageHandler; + } + startMessagesExpiration() { + if (this.timeoutId) { + clearTimeout(this.timeoutId); + } + // Clean up outstanding messages + this.timeoutId = setTimeout(() => { + this.pruneOutstanding(); + this.timeoutId = null; + this.startMessagesExpiration(); + }, this.config.cleanup_out_msgs); + } + stopMessagesExpiration() { + if (this.timeoutId) { + clearTimeout(this.timeoutId); + this.timeoutId = null; + } + } + pruneOutstanding() { + const destinationClientsIds = this.realm.getClientsIdsWithQueue(); + const now = new Date().getTime(); + const maxDiff = this.config.expire_timeout; + const seen = {}; + for (const destinationClientId of destinationClientsIds) { + const messageQueue = this.realm.getMessageQueueById(destinationClientId); + const lastReadDiff = now - messageQueue.getLastReadAt(); + if (lastReadDiff < maxDiff) { + continue; + } + const messages = messageQueue.getMessages(); + for (const message of messages) { + if (!seen[message.src]) { + this.messageHandler.handle(null, { + type: enums_1.MessageType.EXPIRE, + src: message.dst, + dst: message.src + }); + seen[message.src] = true; + } + } + this.realm.clearMessageQueue(destinationClientId); + } + } +} +exports.MessagesExpire = MessagesExpire; diff --git a/dist/src/services/webSocketServer/index.js b/dist/src/services/webSocketServer/index.js new file mode 100644 index 0000000..5f45f5f --- /dev/null +++ b/dist/src/services/webSocketServer/index.js @@ -0,0 +1,91 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = __importDefault(require("events")); +const url_1 = __importDefault(require("url")); +const ws_1 = __importDefault(require("ws")); +const enums_1 = require("../../enums"); +const client_1 = require("../../models/client"); +class WebSocketServer extends events_1.default { + constructor({ server, realm, config }) { + super(); + this.setMaxListeners(0); + this.realm = realm; + this.config = config; + const path = this.config.path; + this.path = path + (path[path.length - 1] !== "/" ? "/" : "") + "peerjs"; + this.webSocketServer = new ws_1.default.Server({ path, server }); + this.webSocketServer.on("connection", (socket, req) => this._onSocketConnection(socket, req)); + this.webSocketServer.on("error", (error) => this._onSocketError(error)); + } + _onSocketConnection(socket, req) { + const { query = {} } = url_1.default.parse(req.url, true); + const { id, token, key } = query; + if (!id || !token || !key) { + return this._sendErrorAndClose(socket, enums_1.Errors.INVALID_WS_PARAMETERS); + } + if (key !== this.config.key) { + return this._sendErrorAndClose(socket, enums_1.Errors.INVALID_KEY); + } + const client = this.realm.getClientById(id); + if (client) { + if (token !== client.getToken()) { + // ID-taken, invalid token + socket.send(JSON.stringify({ + type: enums_1.MessageType.ID_TAKEN, + payload: { msg: "ID is taken" } + })); + return socket.close(); + } + return this._configureWS(socket, client); + } + this._registerClient({ socket, id, token }); + } + _onSocketError(error) { + // handle error + this.emit("error", error); + } + _registerClient({ socket, id, token }) { + // Check concurrent limit + const clientsCount = this.realm.getClientsIds().length; + if (clientsCount >= this.config.concurrent_limit) { + return this._sendErrorAndClose(socket, enums_1.Errors.CONNECTION_LIMIT_EXCEED); + } + const newClient = new client_1.Client({ id, token }); + this.realm.setClient(newClient, id); + socket.send(JSON.stringify({ type: enums_1.MessageType.OPEN })); + this._configureWS(socket, newClient); + } + _configureWS(socket, client) { + client.setSocket(socket); + // Cleanup after a socket closes. + socket.on("close", () => { + if (client.getSocket() === socket) { + this.realm.removeClientById(client.getId()); + this.emit("close", client); + } + }); + // Handle messages from peers. + socket.on("message", (data) => { + try { + const message = JSON.parse(data); + message.src = client.getId(); + this.emit("message", client, message); + } + catch (e) { + this.emit("error", e); + } + }); + this.emit("connection", client); + } + _sendErrorAndClose(socket, msg) { + socket.send(JSON.stringify({ + type: enums_1.MessageType.ERROR, + payload: { msg } + })); + socket.close(); + } +} +exports.WebSocketServer = WebSocketServer; diff --git a/dist/src/services/webSocketServer/webSocket.js b/dist/src/services/webSocketServer/webSocket.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/dist/src/services/webSocketServer/webSocket.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/package-lock.json b/package-lock.json index 0131cba..e4ace55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,6 +68,100 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, + "@types/body-parser": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz", + "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-zw8UvoBEImn392tLjxoavuonblX/4Yb9ha4KBU10FirCfwgzhKO0dvyJSF9ByxV1xK1r2AgnAi/tvQaLgxQqxA==", + "dev": true + }, + "@types/connect": { + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", + "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "requires": { + "@types/node": "*" + } + }, + "@types/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-invOmosX0DqbpA+cE2yoHGUlF/blyf7nB0OGYBBiH27crcVm5NmFaZkLP4Ta1hGaesckCi5lVLlydNJCxkTOSg==", + "requires": { + "@types/express": "*" + } + }, + "@types/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.1.tgz", + "integrity": "sha512-VfH/XCP0QbQk5B5puLqTLEeFgR8lfCJHZJKkInZ9mkYd+u8byX0kztXEQxEk4wZXJs8HI+7km2ALXjn4YKcX9w==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.16.9", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.9.tgz", + "integrity": "sha512-GqpaVWR0DM8FnRUJYKlWgyARoBUAVfRIeVDZQKOttLFp5SmhhF9YFIYeTPwMd/AXfxlP7xVO2dj1fGu0Q+krKQ==", + "requires": { + "@types/node": "*", + "@types/range-parser": "*" + } + }, + "@types/mime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", + "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==" + }, + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", + "dev": true + }, + "@types/node": { + "version": "10.14.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.16.tgz", + "integrity": "sha512-/opXIbfn0P+VLt+N8DE4l8Mn8rbhiJgabU96ZJ0p9mxOkIks5gh6RUnpHak7Yh0SFkyjO/ODbxsQQPV2bpMmyA==" + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, + "@types/serve-static": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", + "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", + "requires": { + "@types/express-serve-static-core": "*", + "@types/mime": "*" + } + }, + "@types/ws": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.2.tgz", + "integrity": "sha512-22XiR1ox9LftTaAtn/c5JCninwc7moaqbkJfaDUb7PkaUitcf5vbTZHdq9dxSMviCm9C3W85rzB8e6yNR70apQ==", + "requires": { + "@types/node": "*" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -77,28 +171,13 @@ "negotiator": "0.6.2" } }, - "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", - "dev": true - }, - "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", - "dev": true - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "string-width": "^2.0.0" } }, "ansi-colors": { @@ -107,15 +186,6 @@ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", "dev": true }, - "ansi-escapes": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", - "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", - "dev": true, - "requires": { - "type-fest": "^0.5.2" - } - }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -131,6 +201,33 @@ "color-convert": "^1.9.0" } }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "arg": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", + "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -140,6 +237,24 @@ "sprintf-js": "~1.0.2" } }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -151,15 +266,11 @@ "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", "dev": true }, - "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" - } + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true }, "assertion-error": { "version": "1.1.0", @@ -167,10 +278,16 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, - "astral-regex": { + "assign-symbols": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, "async-limiter": { @@ -178,12 +295,79 @@ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -211,6 +395,29 @@ } } }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -221,22 +428,74 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } }, "camelcase": { "version": "5.3.1", @@ -244,6 +503,12 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "dev": true + }, "chai": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", @@ -280,31 +545,88 @@ } } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { - "restore-cursor": "^3.1.0" + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + } } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", "dev": true }, "cliui": { @@ -324,6 +646,16 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -339,17 +671,37 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } }, "content-disposition": { "version": "0.5.3", @@ -374,6 +726,18 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, "cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -383,6 +747,15 @@ "vary": "^1" } }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -396,6 +769,12 @@ "which": "^1.2.9" } }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -404,18 +783,18 @@ "ms": "2.0.0" } }, - "debug-log": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", - "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", - "dev": true - }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", @@ -425,10 +804,10 @@ "type-detect": "^4.0.0" } }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, "define-properties": { @@ -440,25 +819,44 @@ "object-keys": "^1.0.12" } }, - "deglob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/deglob/-/deglob-4.0.0.tgz", - "integrity": "sha512-nrUWPTcQ4ap7KWCSeWNDXUgIe4A3nSbsp9cmWrxbKOOxUxLpAVzU1aeatYZfjE+lVHO1lUjXpBmoxOgPYbV5lg==", + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "find-root": "^1.0.0", - "glob": "^7.0.5", - "ignore": "^5.0.0", - "pkg-config": "^1.1.0", - "run-parallel": "^1.1.2", - "uniq": "^1.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { - "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", - "dev": true + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } } } }, @@ -478,15 +876,21 @@ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", "dev": true, "requires": { - "esutils": "^2.0.2" + "is-obj": "^1.0.0" } }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -557,327 +961,28 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "eslint": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.2.1.tgz", - "integrity": "sha512-ES7BzEzr0Q6m5TK9i+/iTpKjclXitOdDK4vT07OqbkBT2/VcN/gO9EL1C4HlK3TAOXYv2ItcmbVR9jO1MR0fJg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "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.0", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.4.1", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.0.0" - } - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true - } - } - }, - "eslint-config-semistandard": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-semistandard/-/eslint-config-semistandard-15.0.0.tgz", - "integrity": "sha512-volIMnosUvzyxGkYUA5QvwkahZZLeUx7wcS0+7QumPn+MMEBbV6P7BY1yukamMst0w3Et3QZlCjQEwQ8tQ6nug==", - "dev": true - }, - "eslint-config-standard": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.0.0.tgz", - "integrity": "sha512-bV6e2LFvJEetrLjVAy4KWPOUsIhPWr040c649MigTPR6yUtaGuOt6CEAyNeez2lRiC+2+vjGWa02byjs25EB3A==", - "dev": true - }, - "eslint-config-standard-jsx": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-8.0.0.tgz", - "integrity": "sha512-Abs/WP+638KfkHI1J961yAztpMhYFvEMTqD4GMUZObAO9yOmLaQZlJY6xke1ty1+zhY4G58AuvHo3ht6avAEVQ==", - "dev": true - }, - "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" - } - }, - "eslint-module-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", - "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", - "dev": true, - "requires": { - "debug": "^2.6.8", - "pkg-dir": "^2.0.0" - } - }, - "eslint-plugin-es": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz", - "integrity": "sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw==", - "dev": true, - "requires": { - "eslint-utils": "^1.3.0", - "regexpp": "^2.0.1" - } - }, - "eslint-plugin-import": { - "version": "2.18.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", - "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.0", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.11.0" - }, - "dependencies": { - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - } - } - }, - "eslint-plugin-node": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-9.1.0.tgz", - "integrity": "sha512-ZwQYGm6EoV2cfLpE1wxJWsfnKUIXfM/KM09/TlorkukgCAwmkgajEJnPCmyzoFPQQkmvo5DrW/nyKutNIw36Mw==", - "dev": true, - "requires": { - "eslint-plugin-es": "^1.4.0", - "eslint-utils": "^1.3.1", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-plugin-promise": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", - "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", - "dev": true - }, - "eslint-plugin-react": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz", - "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.1.0", - "object.entries": "^1.1.0", - "object.fromentries": "^2.0.0", - "object.values": "^1.1.0", - "prop-types": "^15.7.2", - "resolve": "^1.10.1" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - } - } - }, - "eslint-plugin-standard": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz", - "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==", - "dev": true - }, "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, - "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.0.0" - } - }, "eslint-visitor-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", "dev": true }, - "espree": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.0.tgz", - "integrity": "sha512-boA7CHRLlVWUSg3iL5Kmlt/xT3Q+sXnKoRYYzj1YeM10A76TEJBbotV5pKbnK42hEUIr121zTv+QLRM5LsCPXQ==", - "dev": true, - "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.1.0" - } - }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", @@ -919,6 +1024,41 @@ "strip-eof": "^1.0.0" } }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -956,62 +1096,113 @@ "vary": "~1.1.2" } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "is-plain-object": "^2.0.4" } } } }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz", - "integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==", + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } } }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "finalhandler": { @@ -1028,12 +1219,6 @@ "unpipe": "~1.0.0" } }, - "find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true - }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -1052,21 +1237,10 @@ "is-buffer": "~2.0.3" } }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, "forwarded": { @@ -1074,6 +1248,15 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -1085,18 +1268,560 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1109,12 +1834,6 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, - "get-stdin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", - "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", - "dev": true - }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -1124,6 +1843,12 @@ "pump": "^3.0.0" } }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", @@ -1138,20 +1863,41 @@ "path-is-absolute": "^1.0.0" } }, - "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", "dev": true, "requires": { - "is-glob": "^4.0.1" + "ini": "^1.3.4" } }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + } }, "graceful-fs": { "version": "4.2.2", @@ -1186,6 +1932,44 @@ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -1210,21 +1994,17 @@ "toidentifier": "1.0.0" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", "dev": true }, - "import-fresh": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", - "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true }, "imurmurhash": { "version": "0.1.4", @@ -1247,72 +2027,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "inquirer": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.1.tgz", - "integrity": "sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^2.4.2", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^4.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "string-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", - "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^5.2.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true }, "invert-kv": { "version": "2.0.0", @@ -1325,12 +2044,47 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, "is-buffer": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", @@ -1343,12 +2097,72 @@ "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", "dev": true }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1370,10 +2184,76 @@ "is-extglob": "^2.1.1" } }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", "dev": true }, "is-regex": { @@ -1385,6 +2265,12 @@ "has": "^1.0.1" } }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -1400,6 +2286,12 @@ "has-symbols": "^1.0.0" } }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -1412,10 +2304,10 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, "js-yaml": { @@ -1434,34 +2326,27 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "jsx-ast-utils": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz", - "integrity": "sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "object.assign": "^4.1.0" - } - }, "just-extend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", "dev": true }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", @@ -1471,25 +2356,15 @@ "invert-kv": "^2.0.0" } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", + "parse-json": "^4.0.0", + "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, @@ -1509,6 +2384,12 @@ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "dev": true + }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -1524,15 +2405,37 @@ "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", @@ -1542,6 +2445,21 @@ "p-defer": "^1.0.0" } }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1558,6 +2476,12 @@ "p-is-promise": "^2.0.0" } }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -1568,6 +2492,27 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -1606,6 +2551,27 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -1676,17 +2642,31 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } }, "negotiator": { "version": "0.6.2", @@ -1739,6 +2719,50 @@ "semver": "^5.7.0" } }, + "nodemon": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.1.tgz", + "integrity": "sha512-/DXLzd/GhiaDXXbGId5BzxP1GlsqtMGM9zTmkWrgXtSqjKmGSbLicM/oAy4FR0YWm14jCHRwnR31AHS2dYFHrg==", + "dev": true, + "requires": { + "chokidar": "^2.1.5", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.6", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.5.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -1751,6 +2775,29 @@ "validate-npm-package-license": "^3.0.1" } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -1771,12 +2818,58 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "object-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==", "dev": true }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, "object.assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", @@ -1789,30 +2882,6 @@ "object-keys": "^1.0.11" } }, - "object.entries": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", - "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "object.fromentries": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", - "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.11.0", - "function-bind": "^1.1.1", - "has": "^1.0.1" - } - }, "object.getownpropertydescriptors": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", @@ -1823,16 +2892,13 @@ "es-abstract": "^1.5.1" } }, - "object.values": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", - "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "isobject": "^3.0.1" } }, "on-finished": { @@ -1852,15 +2918,6 @@ "wrappy": "1" } }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -1870,28 +2927,6 @@ "wordwrap": "~0.0.2" } }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - }, - "dependencies": { - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", @@ -1903,12 +2938,6 @@ "mem": "^4.0.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", @@ -1951,22 +2980,26 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", "dev": true, "requires": { - "callsites": "^3.0.0" + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" } }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, "parseurl": { @@ -1974,6 +3007,18 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -1986,6 +3031,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -2004,12 +3055,12 @@ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "pify": "^2.0.0" + "pify": "^3.0.0" } }, "pathval": { @@ -2018,146 +3069,35 @@ "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, + "pidtree": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz", + "integrity": "sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==", + "dev": true + }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, - "pkg-conf": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", - "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "load-json-file": "^5.2.0" - }, - "dependencies": { - "load-json-file": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "parse-json": "^4.0.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0", - "type-fest": "^0.3.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "dev": true - } - } - }, - "pkg-config": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", - "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", - "dev": true, - "requires": { - "debug-log": "^1.0.0", - "find-root": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - } - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "proxy-addr": { "version": "2.0.5", @@ -2168,6 +3108,18 @@ "ipaddr.js": "1.9.0" } }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "pstree.remy": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", + "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", + "dev": true + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -2178,12 +3130,6 @@ "once": "^1.3.1" } }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", @@ -2215,82 +3161,108 @@ } } }, - "react-is": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", - "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } } }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, "require-directory": { @@ -2314,178 +3286,61 @@ "path-parse": "^1.0.6" } }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", + "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", "dev": true, "requires": { "glob": "^7.1.3" } }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "semistandard": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/semistandard/-/semistandard-14.0.1.tgz", - "integrity": "sha512-/zLjilCminmmEmYkK6/Z2RYKijQ2NDG9V0DMvPG9mHBdlv2jtu/EEFTdiz/rishopglyuHCOEjkSYI4hD8poJA==", - "dev": true, - "requires": { - "eslint": "~6.1.0", - "eslint-config-semistandard": "~15.0.0", - "eslint-config-standard": "~14.0.0", - "eslint-config-standard-jsx": "~8.0.0", - "eslint-plugin-import": "~2.18.0", - "eslint-plugin-node": "~9.1.0", - "eslint-plugin-promise": "~4.2.1", - "eslint-plugin-react": "~7.14.2", - "eslint-plugin-standard": "~4.0.0", - "standard-engine": "^12.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "eslint": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz", - "integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "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", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.4.1", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true - } - } - }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -2530,6 +3385,29 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", @@ -2550,6 +3428,12 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "shell-quote": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.1.tgz", + "integrity": "sha512-2kUqeAGnMAu6YrTPX4E3LfxacH9gKljzVjlkUeSqY0soGwK4KLl7TURXCem712tkhBCeeaFP9QK4dKn88s3Icg==", + "dev": true + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -2582,17 +3466,160 @@ } } }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", @@ -2625,29 +3652,39 @@ "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "standard-engine": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-12.0.0.tgz", - "integrity": "sha512-gJIIRb0LpL7AHyGbN9+hJ4UJns37lxmNTnMGRLC8CFrzQ+oB/K60IQjKNgPBCB2VP60Ypm6f8DFXvhVWdBOO+g==", + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "deglob": "^4.0.0", - "get-stdin": "^7.0.0", - "minimist": "^1.1.0", - "pkg-conf": "^3.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } } } }, @@ -2666,6 +3703,26 @@ "strip-ansi": "^4.0.0" } }, + "string.prototype.padend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", + "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.4.3", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -2702,71 +3759,101 @@ "has-flag": "^3.0.0" } }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "execa": "^0.7.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + } + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" } } } }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } }, "toidentifier": { @@ -2774,19 +3861,81 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1" + } + } + } + }, + "ts-node": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", + "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + }, + "dependencies": { + "diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true + } + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "tslint": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.19.0.tgz", + "integrity": "sha512-1LwwtBxfRJZnUvoS9c0uj8XQtAnyhWr9KlNvDIdB+oXyT+VpsOAaEhEgKi1HrZ8rq0ki/AAnbGSv4KM6/AfVZw==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" } }, "type-detect": { @@ -2795,12 +3944,6 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, - "type-fest": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", - "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", - "dev": true - }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -2810,37 +3953,178 @@ "mime-types": "~2.1.24" } }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "typescript": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", + "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==", "dev": true }, + "typescript-eslint-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/typescript-eslint-parser/-/typescript-eslint-parser-22.0.0.tgz", + "integrity": "sha512-pD8D7oTeRwWvFVxK3PaY6FYAiZsuRXFkIc2+1xkwCT3NduySgCgjeAkR5/dnIWecOiFVcEHf4ypXurF02Q6Z3Q==", + "dev": true, + "requires": { + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0", + "typescript-estree": "18.0.0" + } + }, + "typescript-estree": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/typescript-estree/-/typescript-estree-18.0.0.tgz", + "integrity": "sha512-HxTWrzFyYOPWA91Ij7xL9mNUVpGTKLH2KiaBn28CMbYgX2zgWdJqU9hO7Are+pAPAqY91NxAYoaAyDDZ3rLj2A==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "undefsafe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", + "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "dev": true, + "requires": { + "debug": "^2.2.0" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "punycode": "^2.1.0" + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } } }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, - "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", - "dev": true - }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -2880,6 +4164,15 @@ "string-width": "^1.0.2 || 2" } }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + } + }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", @@ -2938,13 +4231,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { - "mkdirp": "^0.5.1" + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" } }, "ws": { @@ -2955,10 +4250,10 @@ "async-limiter": "^1.0.0" } }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, "y18n": { @@ -2967,6 +4262,12 @@ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, "yargs": { "version": "13.2.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", @@ -3078,6 +4379,12 @@ } } } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/package.json b/package.json index dc8076c..5160569 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "peer", "version": "0.3.0", "description": "PeerJS server component", - "main": "src/index.js", + "main": "dist/peerjs.server.min.js", "bin": { "peerjs": "./bin/peerjs" }, @@ -13,10 +13,23 @@ "author": "Michelle Bu, Eric Zhang", "license": "MIT", "scripts": { - "test": "eslint . && mocha \"test/**/*.js\"", - "start": "bin/peerjs --port ${PORT:=9000}" + "build": "tsc", + "clean": "rimraf ./dist", + "lint": "tslint -c tslint.json -p tsconfig.json --fix", + "tsc": "tsc", + "prebuild": "npm run lint", + "test": "npm run lint && mocha \"test/**/*.js\"", + "start": "bin/peerjs --port ${PORT:=9000}", + "dev:start": "npm-run-all build start", + "dev": "nodemon --watch src -e ts --exec npm run dev:start" + }, + "release": { + "branch": "master" }, "dependencies": { + "@types/cors": "^2.8.6", + "@types/express": "^4.17.1", + "@types/ws": "^6.0.2", "body-parser": "^1.19.0", "cors": "~2.8.4", "express": "^4.17.1", @@ -24,13 +37,20 @@ "ws": "^7.1.2" }, "devDependencies": { + "@types/chai": "^4.1.7", + "@types/mocha": "^5.2.7", + "@types/node": "^10.14.16", "chai": "^4.2.0", - "eslint": "^6.2.1", "mocha": "^6.2.0", - "semistandard": "^14.0.1", - "sinon": "^7.4.1" + "nodemon": "^1.19.1", + "npm-run-all": "^4.1.5", + "rimraf": "^3.0.0", + "sinon": "^7.4.1", + "ts-node": "^8.3.0", + "tslint": "^5.19.0", + "typescript": "^3.5.3" }, "engines": { "node": "^10" } -} +} \ No newline at end of file diff --git a/src/api/index.js b/src/api/index.js deleted file mode 100644 index 86f3a07..0000000 --- a/src/api/index.js +++ /dev/null @@ -1,23 +0,0 @@ -const express = require('express'); -const cors = require('cors'); -const bodyParser = require('body-parser'); -const publicContent = require('../../app.json'); - -module.exports = ({ config, realm, messageHandler }) => { - const authMiddleware = require('./middleware/auth')({ config, realm }); - - const app = express.Router(); - - const jsonParser = bodyParser.json(); - - app.use(cors()); - - app.get('/', (req, res) => { - res.send(publicContent); - }); - - app.use('/:key', require('./v1/public')({ config, realm })); - app.use('/:key/:id/:token', authMiddleware, jsonParser, require('./v1/calls')({ realm, messageHandler })); - - return app; -}; diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 0000000..9b44cc6 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,33 @@ +import bodyParser from "body-parser"; +import cors from "cors"; +import express from "express"; +import publicContent from "../../app.json"; +import { IConfig } from "../../config/"; +import { IMessageHandler } from "../messageHandler"; +import { IRealm } from "../models/realm"; +import { AuthMiddleware } from "./middleware/auth"; +import CallsApi from "./v1/calls"; +import PublicApi from "./v1/public"; + +export const Api = ({ config, realm, messageHandler }: { + config: IConfig, + realm: IRealm, + messageHandler: IMessageHandler +}): express.Router => { + const authMiddleware = new AuthMiddleware(config, realm); + + const app = express.Router(); + + const jsonParser = bodyParser.json(); + + app.use(cors()); + + app.get("/", (_, res) => { + res.send(publicContent); + }); + + app.use("/:key", PublicApi({ config, realm })); + app.use("/:key/:id/:token", authMiddleware.handle, jsonParser, CallsApi({ realm, messageHandler })); + + return app; +}; diff --git a/src/api/middleware/auth/index.js b/src/api/middleware/auth/index.js deleted file mode 100644 index 498bb5f..0000000 --- a/src/api/middleware/auth/index.js +++ /dev/null @@ -1,25 +0,0 @@ -const { Errors } = require('../../../enums'); - -module.exports = ({ config, realm }) => (req, res, next) => { - const { id, token, key } = req.params; - - if (key !== config.key) { - return res.status(401).send(Errors.INVALID_KEY); - } - - if (!id) { - return res.sendStatus(401); - } - - const client = realm.getClientById(id); - - if (!client) { - return res.sendStatus(401); - } - - if (client.getToken() && token !== client.getToken()) { - return res.status(401).send(Errors.INVALID_TOKEN); - } - - next(); -}; diff --git a/src/api/middleware/auth/index.ts b/src/api/middleware/auth/index.ts new file mode 100644 index 0000000..92c7cdf --- /dev/null +++ b/src/api/middleware/auth/index.ts @@ -0,0 +1,35 @@ +import express from "express"; +import { IConfig } from "../../../../config"; +import { Errors } from "../../../enums"; +import { IRealm } from "../../../models/realm"; +import { IMiddleware } from "../middleware"; + +export class AuthMiddleware implements IMiddleware { + + constructor(private readonly config: IConfig, private readonly realm: IRealm) { } + + public handle(req: express.Request, res: express.Response, next: express.NextFunction): any { + const { id, token, key } = req.params; + + if (key !== this.config.key) { + return res.status(401).send(Errors.INVALID_KEY); + } + + if (!id) { + return res.sendStatus(401); + } + + const client = this.realm.getClientById(id); + + if (!client) { + return res.sendStatus(401); + } + + if (client.getToken() && token !== client.getToken()) { + return res.status(401).send(Errors.INVALID_TOKEN); + } + + next(); + } + +} diff --git a/src/api/middleware/middleware.ts b/src/api/middleware/middleware.ts new file mode 100644 index 0000000..9c28f9d --- /dev/null +++ b/src/api/middleware/middleware.ts @@ -0,0 +1,5 @@ +import express from "express"; + +export interface IMiddleware { + handle(req: express.Request, res: express.Response, next: express.NextFunction): any; +} diff --git a/src/api/v1/calls/index.js b/src/api/v1/calls/index.js deleted file mode 100644 index d022cda..0000000 --- a/src/api/v1/calls/index.js +++ /dev/null @@ -1,36 +0,0 @@ -const express = require('express'); - -module.exports = ({ realm, messageHandler }) => { - const app = express.Router(); - - const handle = (req, res, next) => { - const { id } = req.params; - - if (!id) return next(); - - const client = realm.getClientById(id); - - const { type, dst, payload } = req.body; - - const message = { - type, - src: id, - dst, - payload - }; - - messageHandler(client, message); - - res.sendStatus(200); - }; - - app.post('/offer', handle); - - app.post('/candidate', handle); - - app.post('/answer', handle); - - app.post('/leave', handle); - - return app; -}; diff --git a/src/api/v1/calls/index.ts b/src/api/v1/calls/index.ts new file mode 100644 index 0000000..f96aae6 --- /dev/null +++ b/src/api/v1/calls/index.ts @@ -0,0 +1,36 @@ +import express from "express"; +import { IMessageHandler } from "../../../messageHandler"; +import { IMessage } from "../../../models/message"; +import { IRealm } from "../../../models/realm"; + +export default ({ realm, messageHandler }: { realm: IRealm, messageHandler: IMessageHandler }): express.Router => { + const app = express.Router(); + + const handle = (req: express.Request, res: express.Response, next: express.NextFunction): any => { + const { id } = req.params; + + if (!id) { return next(); } + + const client = realm.getClientById(id); + + const { type, dst, payload } = req.body; + + const message: IMessage = { + type, + src: id, + dst, + payload + }; + + messageHandler.handle(client, message); + + res.sendStatus(200); + }; + + app.post("/offer", handle); + app.post("/candidate", handle); + app.post("/answer", handle); + app.post("/leave", handle); + + return app; +}; diff --git a/src/api/v1/public/index.js b/src/api/v1/public/index.ts similarity index 51% rename from src/api/v1/public/index.js rename to src/api/v1/public/index.ts index a47a371..ab8ded9 100644 --- a/src/api/v1/public/index.js +++ b/src/api/v1/public/index.ts @@ -1,16 +1,20 @@ -const express = require('express'); +import express from "express"; +import { IConfig } from "../../../../config"; +import { IRealm } from "../../../models/realm"; -module.exports = ({ config, realm }) => { +export default ({ config, realm }: { + config: IConfig, realm: IRealm +}): express.Router => { const app = express.Router(); // Retrieve guaranteed random ID. - app.get('/id', (req, res) => { - res.contentType = 'text/html'; + app.get("/id", (_, res: express.Response) => { + res.contentType("html"); res.send(realm.generateClientId()); }); // Get a list of all peers for a key, enabled by the `allowDiscovery` flag. - app.get('/peers', (req, res) => { + app.get("/peers", (_, res: express.Response) => { if (config.allow_discovery) { const clientsIds = realm.getClientsIds(); diff --git a/src/enums.js b/src/enums.js deleted file mode 100644 index 93044a4..0000000 --- a/src/enums.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports.Errors = { - INVALID_KEY: 'Invalid key provided', - INVALID_TOKEN: 'Invalid token provided', - INVALID_WS_PARAMETERS: 'No id, token, or key supplied to websocket server', - CONNECTION_LIMIT_EXCEED: 'Server has reached its concurrent user limit' -}; - -module.exports.MessageType = { - OPEN: 'OPEN', - LEAVE: 'LEAVE', - CANDIDATE: 'CANDIDATE', - OFFER: 'OFFER', - ANSWER: 'ANSWER', - EXPIRE: 'EXPIRE', - HEARTBEAT: 'HEARTBEAT', - ID_TAKEN: 'ID-TAKEN', - ERROR: 'ERROR' -}; diff --git a/src/enums.ts b/src/enums.ts new file mode 100644 index 0000000..008c7e6 --- /dev/null +++ b/src/enums.ts @@ -0,0 +1,18 @@ +export enum Errors { + INVALID_KEY = "Invalid key provided", + INVALID_TOKEN = "Invalid token provided", + INVALID_WS_PARAMETERS = "No id, token, or key supplied to websocket server", + CONNECTION_LIMIT_EXCEED = "Server has reached its concurrent user limit" +} + +export enum MessageType { + OPEN = "OPEN", + LEAVE = "LEAVE", + CANDIDATE = "CANDIDATE", + OFFER = "OFFER", + ANSWER = "ANSWER", + EXPIRE = "EXPIRE", + HEARTBEAT = "HEARTBEAT", + ID_TAKEN = "ID-TAKEN", + ERROR = "ERROR" +} diff --git a/src/index.js b/src/index.js deleted file mode 100644 index ea3d9e0..0000000 --- a/src/index.js +++ /dev/null @@ -1,134 +0,0 @@ -const express = require('express'); -const http = require('http'); -const https = require('https'); - -const defaultConfig = require('../config'); -const WebSocketServer = require('./services/webSocketServer'); -const Realm = require('./models/realm'); - -const init = ({ app, server, options }) => { - const config = options; - const realm = new Realm(); - const messageHandler = require('./messageHandler')({ realm }); - const api = require('./api')({ config, realm, messageHandler }); - - const { startMessagesExpiration } = require('./services/messagesExpire')({ realm, config, messageHandler }); - const checkBrokenConnections = require('./services/checkBrokenConnections')({ - realm, config, onClose: (client) => { - app.emit('disconnect', client); - } - }); - - app.use(options.path, api); - - const wss = new WebSocketServer({ - server, - realm, - config: { - ...config, - } - }); - - wss.on('connection', client => { - const messageQueue = realm.getMessageQueueById(client.getId()); - - if (messageQueue) { - let message; - // eslint-disable-next-line no-cond-assign - while (message = messageQueue.readMessage()) { - messageHandler(client, message); - } - realm.clearMessageQueue(client.getId()); - } - - app.emit('connection', client); - }); - - wss.on('message', (client, message) => { - app.emit('message', client, message); - messageHandler(client, message); - }); - - wss.on('close', client => { - app.emit('disconnect', client); - }); - - wss.on('error', error => { - app.emit('error', error); - }); - - startMessagesExpiration(); - - checkBrokenConnections.start(); -}; - -function ExpressPeerServer(server, options) { - const app = express(); - - options = { - ...defaultConfig, - ...options - }; - - if (options.proxied) { - app.set('trust proxy', options.proxied === 'false' ? false : options.proxied); - } - - app.on('mount', () => { - if (!server) { - throw new Error('Server is not passed to constructor - ' + - 'can\'t start PeerServer'); - } - - init({ app, server, options }); - }); - - return app; -} - -function PeerServer(options = {}, callback) { - const app = express(); - - options = { - ...defaultConfig, - ...options - }; - - let path = options.path; - const port = options.port; - - if (path[0] !== '/') { - path = '/' + path; - } - - if (path[path.length - 1] !== '/') { - path += '/'; - } - - let server; - - if (options.ssl && options.ssl.key && options.ssl.cert) { - server = https.createServer(options.ssl, app); - delete options.ssl; - } else { - server = http.createServer(app); - } - - const peerjs = ExpressPeerServer(server, options); - app.use(peerjs); - - if (callback) { - server.listen(port, () => { - callback(server); - }); - } else { - server.listen(port); - } - - return peerjs; -} - -exports = module.exports = { - ExpressPeerServer: ExpressPeerServer, - PeerServer: PeerServer -}; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..4b50679 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,152 @@ +import { IRealm } from "./models/realm"; + +import express from "express"; +import http from "http"; +import https from "https"; + +import { Server } from "net"; +import defaultConfig, { IConfig } from "../config"; +import { Api } from "./api"; +import { MessageHandler } from "./messageHandler"; +import { IClient } from "./models/client"; +import { IMessage } from "./models/message"; +import { Realm } from "./models/realm"; +import { CheckBrokenConnections } from "./services/checkBrokenConnections"; +import { IMessagesExpire, MessagesExpire } from "./services/messagesExpire"; +import { IWebSocketServer, WebSocketServer } from "./services/webSocketServer"; + +const init = ({ app, server, options }: { + app: express.Express, + server: Server, + options: IConfig +}) => { + const config = options; + const realm: IRealm = new Realm(); + const messageHandler = new MessageHandler(realm); + const api = Api({ config, realm, messageHandler }); + + const messagesExpire: IMessagesExpire = new MessagesExpire({ realm, config, messageHandler }); + const checkBrokenConnections = new CheckBrokenConnections({ + realm, + config, + onClose: (client: IClient) => { + app.emit("disconnect", client); + } + }); + + app.use(options.path, api); + + const wss: IWebSocketServer = new WebSocketServer({ + server, + realm, + config: { + ...config, + } + }); + + wss.on("connection", (client: IClient) => { + const messageQueue = realm.getMessageQueueById(client.getId()); + + if (messageQueue) { + let message: IMessage | null; + + // tslint:disable + while (message = messageQueue.readMessage()) { + messageHandler.handle(client, message); + } + realm.clearMessageQueue(client.getId()); + } + + app.emit("connection", client); + }); + + wss.on("message", (client: IClient, message: IMessage) => { + app.emit("message", client, message); + messageHandler.handle(client, message); + }); + + wss.on("close", (client: IClient) => { + app.emit("disconnect", client); + }); + + wss.on("error", (error: Error) => { + app.emit("error", error); + }); + + messagesExpire.startMessagesExpiration(); + checkBrokenConnections.start(); +}; + +function ExpressPeerServer(server: Server, options?: IConfig) { + const app = express(); + + const newOptions: IConfig = { + ...defaultConfig, + ...options + }; + + if (newOptions.proxied) { + app.set("trust proxy", newOptions.proxied === "false" ? false : !!newOptions.proxied); + } + + app.on("mount", () => { + if (!server) { + throw new Error("Server is not passed to constructor - " + + "can't start PeerServer"); + } + + init({ app, server, options: newOptions }); + }); + + return app; +} + +type Optional = { + [P in keyof T]?: (T[P] | undefined); +}; + +function PeerServer(options: Optional = {}, callback?: (server: Server) => void) { + const app = express(); + + const newOptions: IConfig = { + ...defaultConfig, + ...options + }; + + let path = newOptions.path; + const port = newOptions.port; + + if (path[0] !== "/") { + path = "/" + path; + } + + if (path[path.length - 1] !== "/") { + path += "/"; + } + + let server: Server; + + if (newOptions.ssl && newOptions.ssl.key && newOptions.ssl.cert) { + server = https.createServer(options.ssl, app); + // @ts-ignore + delete newOptions.ssl; + } else { + server = http.createServer(app); + } + + const peerjs = ExpressPeerServer(server, newOptions); + app.use(peerjs); + + if (callback) { + server.listen(port, () => callback(server)); + } else { + server.listen(port); + } + + return peerjs; +} + +export { + ExpressPeerServer, + PeerServer +}; diff --git a/src/messageHandler/handler.ts b/src/messageHandler/handler.ts new file mode 100644 index 0000000..b265878 --- /dev/null +++ b/src/messageHandler/handler.ts @@ -0,0 +1,4 @@ +import { IClient } from "../models/client"; +import { IMessage } from "../models/message"; + +export type Handler = (client: IClient, message: IMessage) => boolean; diff --git a/src/messageHandler/handlers/heartbeat/index.js b/src/messageHandler/handlers/heartbeat/index.js deleted file mode 100644 index a74b99d..0000000 --- a/src/messageHandler/handlers/heartbeat/index.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = (client) => { - const nowTime = new Date().getTime(); - client.setLastPing(nowTime); -}; diff --git a/src/messageHandler/handlers/heartbeat/index.ts b/src/messageHandler/handlers/heartbeat/index.ts new file mode 100644 index 0000000..135b730 --- /dev/null +++ b/src/messageHandler/handlers/heartbeat/index.ts @@ -0,0 +1,7 @@ +import { IClient } from "../../../models/client"; + +export default function(client: IClient): boolean { + const nowTime = new Date().getTime(); + client.setLastPing(nowTime); + return true; +} diff --git a/src/messageHandler/handlers/transmission/index.js b/src/messageHandler/handlers/transmission/index.js deleted file mode 100644 index aacdb7f..0000000 --- a/src/messageHandler/handlers/transmission/index.js +++ /dev/null @@ -1,49 +0,0 @@ -const { MessageType } = require('../../../enums'); - -module.exports = ({ realm }) => (client, message) => { - const type = message.type; - const srcId = message.src; - const dstId = message.dst; - - const destinationClient = realm.getClientById(dstId); - - // User is connected! - if (destinationClient) { - try { - if (destinationClient.socket) { - const data = JSON.stringify(message); - - destinationClient.socket.send(data); - } else { - // Neither socket no res available. Peer dead? - throw new Error('Peer dead'); - } - } catch (e) { - // This happens when a peer disconnects without closing connections and - // the associated WebSocket has not closed. - // Tell other side to stop trying. - if (destinationClient.socket) { - destinationClient.socket.close(); - } else { - realm.removeClientById(destinationClient.getId()); - } - - module.exports({ realm })(client, { - type: MessageType.LEAVE, - src: dstId, - dst: srcId - }); - } - } else { - // Wait for this client to connect/reconnect (XHR) for important - // messages. - if (type !== MessageType.LEAVE && type !== MessageType.EXPIRE && dstId) { - realm.addMessageToQueue(dstId, message); - } else if (type === MessageType.LEAVE && !dstId) { - realm.removeClientById(srcId); - } else { - // Unavailable destination specified with message LEAVE or EXPIRE - // Ignore - } - } -}; diff --git a/src/messageHandler/handlers/transmission/index.ts b/src/messageHandler/handlers/transmission/index.ts new file mode 100644 index 0000000..fc24479 --- /dev/null +++ b/src/messageHandler/handlers/transmission/index.ts @@ -0,0 +1,58 @@ +import { MessageType } from "../../../enums"; +import { IClient } from "../../../models/client"; +import { IMessage } from "../../../models/message"; +import { IRealm } from "../../../models/realm"; + +export default function({ realm }: { realm: IRealm }): (client: IClient, message: IMessage) => boolean { + const handle = (client: IClient, message: IMessage) => { + const type = message.type; + const srcId = message.src; + const dstId = message.dst; + + const destinationClient = realm.getClientById(dstId); + + // User is connected! + if (destinationClient) { + try { + if (destinationClient.getSocket()) { + const data = JSON.stringify(message); + + destinationClient.getSocket().send(data); + } else { + // Neither socket no res available. Peer dead? + throw new Error("Peer dead"); + } + } catch (e) { + // This happens when a peer disconnects without closing connections and + // the associated WebSocket has not closed. + // Tell other side to stop trying. + if (destinationClient.getSocket()) { + destinationClient.getSocket().close(); + } else { + realm.removeClientById(destinationClient.getId()); + } + + handle(client, { + type: MessageType.LEAVE, + src: dstId, + dst: srcId + }); + } + } else { + // Wait for this client to connect/reconnect (XHR) for important + // messages. + if (type !== MessageType.LEAVE && type !== MessageType.EXPIRE && dstId) { + realm.addMessageToQueue(dstId, message); + } else if (type === MessageType.LEAVE && !dstId) { + realm.removeClientById(srcId); + } else { + // Unavailable destination specified with message LEAVE or EXPIRE + // Ignore + } + } + + return true; + }; + + return handle; +} diff --git a/src/messageHandler/index.js b/src/messageHandler/index.js deleted file mode 100644 index 447e949..0000000 --- a/src/messageHandler/index.js +++ /dev/null @@ -1,49 +0,0 @@ -const { MessageType } = require('../enums'); - -class MessageHandlers { - constructor() { - this.handlers = {}; - } - - registerHandler(messageType, handler) { - this.handlers[messageType] = handler; - } - - handle(client, message) { - const { type } = message; - - const handler = this.handlers[type]; - - if (!handler) { - return; - } - - handler(client, message); - } -} -module.exports = ({ realm }) => { - const transmissionHandler = require('./handlers/transmission')({ realm }); - const heartbeatHandler = require('./handlers/heartbeat'); - - const messageHandlers = new MessageHandlers(); - - const handleTransmission = (client, message) => { - transmissionHandler(client, { - type: message.type, - src: message.src, - dst: message.dst, - payload: message.payload - }); - }; - - const handleHeartbeat = (client) => heartbeatHandler(client); - - messageHandlers.registerHandler(MessageType.HEARTBEAT, handleHeartbeat); - messageHandlers.registerHandler(MessageType.OFFER, handleTransmission); - messageHandlers.registerHandler(MessageType.ANSWER, handleTransmission); - messageHandlers.registerHandler(MessageType.CANDIDATE, handleTransmission); - messageHandlers.registerHandler(MessageType.LEAVE, handleTransmission); - messageHandlers.registerHandler(MessageType.EXPIRE, handleTransmission); - - return (client, message) => messageHandlers.handle(client, message); -}; diff --git a/src/messageHandler/index.ts b/src/messageHandler/index.ts new file mode 100644 index 0000000..a892c98 --- /dev/null +++ b/src/messageHandler/index.ts @@ -0,0 +1,43 @@ +import { MessageType } from "../enums"; +import { IClient } from "../models/client"; +import { IMessage } from "../models/message"; +import { IRealm } from "../models/realm"; +import { Handler } from "./handler"; +import HeartbeatHandler from "./handlers/heartbeat"; +import TransmissionHandler from "./handlers/transmission"; +import { IMessageHandlers, MessageHandlers } from "./messageHandlers"; + +export interface IMessageHandler { + handle(client: IClient, message: IMessage): boolean; +} + +export class MessageHandler implements IMessageHandler { + private readonly messageHandlers: IMessageHandlers = new MessageHandlers(); + + constructor(realm: IRealm) { + const transmissionHandler: Handler = TransmissionHandler({ realm }); + const heartbeatHandler: Handler = HeartbeatHandler; + + const handleTransmission: Handler = (client: IClient, message: IMessage): boolean => { + return transmissionHandler(client, { + type: message.type, + src: message.src, + dst: message.dst, + payload: message.payload + }); + }; + + const handleHeartbeat = (client: IClient, message: IMessage) => heartbeatHandler(client, message); + + this.messageHandlers.registerHandler(MessageType.HEARTBEAT, handleHeartbeat); + this.messageHandlers.registerHandler(MessageType.OFFER, handleTransmission); + this.messageHandlers.registerHandler(MessageType.ANSWER, handleTransmission); + this.messageHandlers.registerHandler(MessageType.CANDIDATE, handleTransmission); + this.messageHandlers.registerHandler(MessageType.LEAVE, handleTransmission); + this.messageHandlers.registerHandler(MessageType.EXPIRE, handleTransmission); + } + + public handle(client: IClient, message: IMessage): boolean { + return this.messageHandlers.handle(client, message); + } +} diff --git a/src/messageHandler/messageHandlers.ts b/src/messageHandler/messageHandlers.ts new file mode 100644 index 0000000..2a48cb4 --- /dev/null +++ b/src/messageHandler/messageHandlers.ts @@ -0,0 +1,29 @@ +import { MessageType } from "../enums"; +import { IClient } from "../models/client"; +import { IMessage } from "../models/message"; +import { Handler } from "./handler"; + +export interface IMessageHandlers { + registerHandler(messageType: MessageType, handler: Handler): void; + handle(client: IClient, message: IMessage): boolean; +} + +export class MessageHandlers implements IMessageHandlers { + private readonly handlers: Map = new Map(); + + public registerHandler(messageType: MessageType, handler: Handler): void { + if (this.handlers.has(messageType)) { return; } + + this.handlers.set(messageType, handler); + } + + public handle(client: IClient, message: IMessage): boolean { + const { type } = message; + + const handler = this.handlers.get(type); + + if (!handler) { return false; } + + return handler(client, message); + } +} diff --git a/src/models/client.js b/src/models/client.js deleted file mode 100644 index 50cc5ef..0000000 --- a/src/models/client.js +++ /dev/null @@ -1,38 +0,0 @@ -class Client { - constructor({ id, token }) { - this.id = id; - this.token = token; - this.socket = null; - this.lastPing = new Date().getTime(); - } - - getId() { - return this.id; - } - - getToken() { - return this.token; - } - - getSocket() { - return this.socket; - } - - setSocket(socket) { - this.socket = socket; - } - - getLastPing() { - return this.lastPing; - } - - setLastPing(lastPing) { - this.lastPing = lastPing; - } - - send(data) { - this.socket.send(JSON.stringify(data)); - } -} - -module.exports = Client; diff --git a/src/models/client.ts b/src/models/client.ts new file mode 100644 index 0000000..cd991a9 --- /dev/null +++ b/src/models/client.ts @@ -0,0 +1,57 @@ +import { MyWebSocket } from "../services/webSocketServer/webSocket"; + +export interface IClient { + getId(): string; + + getToken(): string; + + getSocket(): MyWebSocket | null; + + setSocket(socket: MyWebSocket): void; + + getLastPing(): number; + + setLastPing(lastPing: number): void; + + send(data: any): void; +} + +export class Client implements IClient { + private readonly id: string; + private readonly token: string; + private socket: MyWebSocket = null; + private lastPing: number = new Date().getTime(); + + constructor({ id, token }: { id: string, token: string }) { + this.id = id; + this.token = token; + } + + public getId(): string { + return this.id; + } + + public getToken(): string { + return this.token; + } + + public getSocket(): MyWebSocket | null { + return this.socket; + } + + public setSocket(socket: MyWebSocket): void { + this.socket = socket; + } + + public getLastPing(): number { + return this.lastPing; + } + + public setLastPing(lastPing: number): void { + this.lastPing = lastPing; + } + + public send(data: any): void { + this.socket.send(JSON.stringify(data)); + } +} diff --git a/src/models/message.ts b/src/models/message.ts new file mode 100644 index 0000000..06c9156 --- /dev/null +++ b/src/models/message.ts @@ -0,0 +1,8 @@ +import { MessageType } from "../enums"; + +export interface IMessage { + readonly type: MessageType; + readonly src: string; + readonly dst: string; + readonly payload?: any; +} diff --git a/src/models/messageQueue.js b/src/models/messageQueue.js deleted file mode 100644 index ec5fdd1..0000000 --- a/src/models/messageQueue.js +++ /dev/null @@ -1,30 +0,0 @@ -class MessageQueue { - constructor (id) { - this._id = id; - this._lastReadAt = new Date().getTime(); - this._messages = []; - } - - getLastReadAt () { - return this._lastReadAt; - } - - addMessage (message) { - this._messages.push(message); - } - - readMessage () { - if (this._messages.length > 0) { - this._lastReadAt = new Date().getTime(); - return this._messages.shift(); - } - - return null; - } - - getMessages () { - return this._messages; - } -} - -module.exports = MessageQueue; diff --git a/src/models/messageQueue.ts b/src/models/messageQueue.ts new file mode 100644 index 0000000..4c0e2ce --- /dev/null +++ b/src/models/messageQueue.ts @@ -0,0 +1,37 @@ +import { IMessage } from "./message"; + +export interface IMessageQueue { + getLastReadAt(): number; + + addMessage(message: IMessage): void; + + readMessage(): IMessage | null; + + getMessages(): IMessage[]; +} + +export class MessageQueue implements IMessageQueue { + private lastReadAt: number = new Date().getTime(); + private readonly messages: IMessage[] = []; + + public getLastReadAt(): number { + return this.lastReadAt; + } + + public addMessage(message: IMessage): void { + this.messages.push(message); + } + + public readMessage(): IMessage | null { + if (this.messages.length > 0) { + this.lastReadAt = new Date().getTime(); + return this.messages.shift(); + } + + return null; + } + + public getMessages(): IMessage[] { + return this.messages; + } +} diff --git a/src/models/realm.js b/src/models/realm.js deleted file mode 100644 index fbc4e84..0000000 --- a/src/models/realm.js +++ /dev/null @@ -1,58 +0,0 @@ -const MessageQueue = require('./messageQueue'); - -class Realm { - constructor () { - this._clients = new Map(); - this._messageQueues = new Map(); - } - - getClientsIds () { - return [...this._clients.keys()]; - } - - getClientById (clientId) { - return this._clients.get(clientId); - } - - setClient (client, id) { - this._clients.set(id, client); - } - - removeClientById (id) { - const client = this.getClientById(id); - - if (!client) return false; - - this._clients.delete(id); - } - - getMessageQueueById (id) { - return this._messageQueues.get(id); - } - - addMessageToQueue (id, message) { - if (!this.getMessageQueueById(id)) { - this._messageQueues.set(id, new MessageQueue(id)); - } - - this.getMessageQueueById(id).addMessage(message); - } - - clearMessageQueue (id) { - this._messageQueues.delete(id); - } - - generateClientId () { - const randomId = () => (Math.random().toString(36) + '0000000000000000000').substr(2, 16); - - let clientId = randomId(); - - while (this.getClientById(clientId)) { - clientId = randomId(); - } - - return clientId; - } -} - -module.exports = Realm; diff --git a/src/models/realm.ts b/src/models/realm.ts new file mode 100644 index 0000000..3f6fd1a --- /dev/null +++ b/src/models/realm.ts @@ -0,0 +1,82 @@ +import { IClient } from "./client"; +import { IMessage } from "./message"; +import { IMessageQueue, MessageQueue } from "./messageQueue"; + +export interface IRealm { + getClientsIds(): string[]; + + getClientById(clientId: string): IClient | undefined; + + getClientsIdsWithQueue(): string[]; + + setClient(client: IClient, id: string): void; + + removeClientById(id: string): boolean; + + getMessageQueueById(id: string): IMessageQueue | undefined; + + addMessageToQueue(id: string, message: IMessage): void; + + clearMessageQueue(id: string): void; + + generateClientId(): string; +} + +export class Realm implements IRealm { + private readonly clients: Map = new Map(); + private readonly messageQueues: Map = new Map(); + + public getClientsIds(): string[] { + return [...this.clients.keys()]; + } + + public getClientById(clientId: string): IClient | undefined { + return this.clients.get(clientId); + } + + public getClientsIdsWithQueue(): string[] { + return [...this.messageQueues.keys()]; + } + + public setClient(client: IClient, id: string): void { + this.clients.set(id, client); + } + + public removeClientById(id: string): boolean { + const client = this.getClientById(id); + + if (!client) { return false; } + + this.clients.delete(id); + + return true; + } + + public getMessageQueueById(id: string): IMessageQueue | undefined { + return this.messageQueues.get(id); + } + + public addMessageToQueue(id: string, message: IMessage): void { + if (!this.getMessageQueueById(id)) { + this.messageQueues.set(id, new MessageQueue()); + } + + this.getMessageQueueById(id).addMessage(message); + } + + public clearMessageQueue(id: string): void { + this.messageQueues.delete(id); + } + + public generateClientId(): string { + const randomId = () => (Math.random().toString(36) + "0000000000000000000").substr(2, 16); + + let clientId = randomId(); + + while (this.getClientById(clientId)) { + clientId = randomId(); + } + + return clientId; + } +} diff --git a/src/services/checkBrokenConnections/index.js b/src/services/checkBrokenConnections/index.js deleted file mode 100644 index fe66fef..0000000 --- a/src/services/checkBrokenConnections/index.js +++ /dev/null @@ -1,57 +0,0 @@ -const DEFAULT_CHECK_INTERVAL = 300; - -module.exports = ({ realm, config, checkInterval = DEFAULT_CHECK_INTERVAL, onClose = () => { } }) => { - const checkConnections = () => { - const clientsIds = realm.getClientsIds(); - - const now = new Date().getTime(); - const aliveTimeout = config.alive_timeout; - - for (const clientId of clientsIds) { - const client = realm.getClientById(clientId); - const timeSinceLastPing = now - client.getLastPing(); - - if (timeSinceLastPing < aliveTimeout) continue; - - try { - client.getSocket().close(); - // eslint-disable-next-line no-empty - } catch (e) { } finally { - realm.clearMessageQueue(clientId); - realm.removeClientById(clientId); - client.setSocket(null); - - if (onClose) onClose(client); - } - } - }; - - let timeoutId; - - const start = () => { - if (timeoutId) { - clearTimeout(timeoutId); - } - - timeoutId = setTimeout(() => { - checkConnections(); - - timeoutId = null; - - start(); - }, checkInterval); - }; - - const stop = () => { - if (timeoutId) { - clearTimeout(timeoutId); - timeoutId = null; - } - }; - - return { - start, - stop, - CHECK_INTERVAL: checkInterval - }; -}; diff --git a/src/services/checkBrokenConnections/index.ts b/src/services/checkBrokenConnections/index.ts new file mode 100644 index 0000000..f4629f9 --- /dev/null +++ b/src/services/checkBrokenConnections/index.ts @@ -0,0 +1,73 @@ +import { IConfig } from "../../../config"; +import { IClient } from "../../models/client"; +import { IRealm } from "../../models/realm"; + +const DEFAULT_CHECK_INTERVAL = 300; + +export class CheckBrokenConnections { + + public readonly checkInterval: number; + private timeoutId: NodeJS.Timeout; + private readonly realm: IRealm; + private readonly config: IConfig; + private readonly onClose?: (client: IClient) => void; + + constructor({ realm, config, checkInterval = DEFAULT_CHECK_INTERVAL, onClose }: { + realm: IRealm, + config: IConfig, + checkInterval?: number, + onClose?: (client: IClient) => void + }) { + this.realm = realm; + this.config = config; + this.onClose = onClose; + this.checkInterval = checkInterval; + } + + public start(): void { + if (this.timeoutId) { + clearTimeout(this.timeoutId); + } + + this.timeoutId = setTimeout(() => { + this.checkConnections(); + + this.timeoutId = null; + + this.start(); + }, this.checkInterval); + } + public stop(): void { + if (this.timeoutId) { + clearTimeout(this.timeoutId); + this.timeoutId = null; + } + } + private checkConnections(): void { + const clientsIds = this.realm.getClientsIds(); + + const now = new Date().getTime(); + const aliveTimeout = this.config.alive_timeout; + + for (const clientId of clientsIds) { + const client = this.realm.getClientById(clientId); + const timeSinceLastPing = now - client.getLastPing(); + + if (timeSinceLastPing < aliveTimeout) { continue; } + + try { + if (client.getSocket()) { + client.getSocket().close(); + } + } catch (e) { + // @ts-nocheck + } finally { + this.realm.clearMessageQueue(clientId); + this.realm.removeClientById(clientId); + client.setSocket(null); + + if (this.onClose) { this.onClose(client); } + } + } + } +} diff --git a/src/services/messagesExpire/index.js b/src/services/messagesExpire/index.js deleted file mode 100644 index b4d2b8c..0000000 --- a/src/services/messagesExpire/index.js +++ /dev/null @@ -1,63 +0,0 @@ -const { MessageType } = require('../../enums'); - -module.exports = ({ realm, config, messageHandler }) => { - const pruneOutstanding = () => { - const destinationClientsIds = realm._messageQueues.keys(); - - const now = new Date().getTime(); - const maxDiff = config.expire_timeout; - - const seen = {}; - - for (const destinationClientId of destinationClientsIds) { - const messageQueue = realm.getMessageQueueById(destinationClientId); - const lastReadDiff = now - messageQueue.getLastReadAt(); - - if (lastReadDiff < maxDiff) continue; - - const messages = messageQueue.getMessages(); - - for (const message of messages) { - if (!seen[message.src]) { - messageHandler(null, { - type: MessageType.EXPIRE, - src: message.dst, - dst: message.src - }); - seen[message.src] = true; - } - } - - realm.clearMessageQueue(destinationClientId); - } - }; - - let timeoutId; - - const startMessagesExpiration = () => { - if (timeoutId) { - clearTimeout(timeoutId); - } - - // Clean up outstanding messages - timeoutId = setTimeout(() => { - pruneOutstanding(); - - timeoutId = null; - - startMessagesExpiration(); - }, config.cleanup_out_msgs); - }; - - const stopMessagesExpiration = () => { - if (timeoutId) { - clearTimeout(timeoutId); - timeoutId = null; - } - }; - - return { - startMessagesExpiration, - stopMessagesExpiration - }; -}; diff --git a/src/services/messagesExpire/index.ts b/src/services/messagesExpire/index.ts new file mode 100644 index 0000000..b39c16b --- /dev/null +++ b/src/services/messagesExpire/index.ts @@ -0,0 +1,81 @@ +import { IConfig } from "../../../config"; +import { MessageType } from "../../enums"; +import { IMessageHandler } from "../../messageHandler"; +import { IRealm } from "../../models/realm"; + +export interface IMessagesExpire { + startMessagesExpiration(): void; + stopMessagesExpiration(): void; +} + +export class MessagesExpire implements IMessagesExpire { + private readonly realm: IRealm; + private readonly config: IConfig; + private readonly messageHandler: IMessageHandler; + + private timeoutId: NodeJS.Timeout = null; + + constructor({ realm, config, messageHandler }: { + realm: IRealm; + config: IConfig; + messageHandler: IMessageHandler; + }) { + this.realm = realm; + this.config = config; + this.messageHandler = messageHandler; + } + + public startMessagesExpiration(): void { + if (this.timeoutId) { + clearTimeout(this.timeoutId); + } + + // Clean up outstanding messages + this.timeoutId = setTimeout(() => { + this.pruneOutstanding(); + + this.timeoutId = null; + + this.startMessagesExpiration(); + }, this.config.cleanup_out_msgs); + } + + public stopMessagesExpiration(): void { + if (this.timeoutId) { + clearTimeout(this.timeoutId); + this.timeoutId = null; + } + } + + private pruneOutstanding(): void { + const destinationClientsIds = this.realm.getClientsIdsWithQueue(); + + const now = new Date().getTime(); + const maxDiff = this.config.expire_timeout; + + const seen: { [id: string]: boolean } = {}; + + for (const destinationClientId of destinationClientsIds) { + const messageQueue = this.realm.getMessageQueueById(destinationClientId); + const lastReadDiff = now - messageQueue.getLastReadAt(); + + if (lastReadDiff < maxDiff) { continue; } + + const messages = messageQueue.getMessages(); + + for (const message of messages) { + if (!seen[message.src]) { + this.messageHandler.handle(null, { + type: MessageType.EXPIRE, + src: message.dst, + dst: message.src + }); + + seen[message.src] = true; + } + } + + this.realm.clearMessageQueue(destinationClientId); + } + } +} diff --git a/src/services/webSocketServer/index.js b/src/services/webSocketServer/index.js deleted file mode 100644 index bfe1b6c..0000000 --- a/src/services/webSocketServer/index.js +++ /dev/null @@ -1,114 +0,0 @@ -const WSS = require('ws').Server; -const url = require('url'); -const EventEmitter = require('events'); -const { MessageType, Errors } = require('../../enums'); -const Client = require('../../models/client'); - -class WebSocketServer extends EventEmitter { - constructor({ server, realm, config }) { - super(); - this.setMaxListeners(0); - this.realm = realm; - this.config = config; - - let path = this.config.path; - path = path + (path[path.length - 1] !== '/' ? '/' : '') + 'peerjs'; - - this._wss = new WSS({ path, server }); - - this._wss.on('connection', (socket, req) => this._onSocketConnection(socket, req)); - this._wss.on('error', (error) => this._onSocketError(error)); - } - - _onSocketConnection(socket, req) { - const { query = {} } = url.parse(req.url, true); - - const { id, token, key } = query; - - if (!id || !token || !key) { - return this._sendErrorAndClose(socket, Errors.INVALID_WS_PARAMETERS); - } - - if (key !== this.config.key) { - return this._sendErrorAndClose(socket, Errors.INVALID_KEY); - } - - const client = this.realm.getClientById(id); - - if (client) { - if (token !== client.getToken()) { - // ID-taken, invalid token - socket.send(JSON.stringify({ - type: MessageType.ID_TAKEN, - payload: { msg: 'ID is taken' } - })); - - return socket.close(); - } - - return this._configureWS(socket, client); - } - - this._registerClient({ socket, id, token }); - } - - _onSocketError(error) { - // handle error - this.emit('error', error); - } - - _registerClient({ socket, id, token }) { - // Check concurrent limit - const clientsCount = this.realm.getClientsIds().length; - - if (clientsCount >= this.config.concurrent_limit) { - return this._sendErrorAndClose(socket, Errors.CONNECTION_LIMIT_EXCEED); - } - - const newClient = new Client({ id, token }); - this.realm.setClient(newClient, id); - socket.send(JSON.stringify({ type: MessageType.OPEN })); - - this._configureWS(socket, newClient); - } - - _configureWS(socket, client) { - client.setSocket(socket); - - // Cleanup after a socket closes. - socket.on('close', () => { - if (client.socket === socket) { - this.realm.removeClientById(client.getId()); - this.emit('close', client); - } - }); - - // Handle messages from peers. - socket.on('message', (data) => { - try { - const message = JSON.parse(data); - - message.src = client.getId(); - - this.emit('message', client, message); - } catch (e) { - this.emit('error', e); - } - }); - - this.emit('connection', client); - } - - _sendErrorAndClose(socket, msg) { - socket.send( - JSON.stringify({ - type: MessageType.ERROR, - payload: { msg } - }) - ); - - socket.close(); - } -} - -module.exports = WebSocketServer; diff --git a/src/services/webSocketServer/index.ts b/src/services/webSocketServer/index.ts new file mode 100644 index 0000000..5c59e19 --- /dev/null +++ b/src/services/webSocketServer/index.ts @@ -0,0 +1,137 @@ +import EventEmitter from "events"; +import { IncomingMessage } from "http"; +import url from "url"; +import WebSocketLib from "ws"; +import { IConfig } from "../../../config"; +import { Errors, MessageType } from "../../enums"; +import { Client, IClient } from "../../models/client"; +import { IRealm } from "../../models/realm"; +import { MyWebSocket } from "./webSocket"; + +export interface IWebSocketServer extends EventEmitter { + readonly path: string; +} + +interface IAuthParams { + id?: string; + token?: string; + key?: string; +} + +export class WebSocketServer extends EventEmitter implements IWebSocketServer { + + public readonly path: string; + private readonly realm: IRealm; + private readonly config: IConfig; + private readonly webSocketServer: WebSocketLib.Server; + + constructor({ server, realm, config }: { server: any, realm: IRealm, config: IConfig }) { + super(); + this.setMaxListeners(0); + this.realm = realm; + this.config = config; + + const path = this.config.path; + this.path = path + (path[path.length - 1] !== "/" ? "/" : "") + "peerjs"; + + this.webSocketServer = new WebSocketLib.Server({ path, server }); + + this.webSocketServer.on("connection", (socket: MyWebSocket, req) => this._onSocketConnection(socket, req)); + this.webSocketServer.on("error", (error: Error) => this._onSocketError(error)); + } + + private _onSocketConnection(socket: MyWebSocket, req: IncomingMessage): void { + const { query = {} } = url.parse(req.url, true); + + const { id, token, key }: IAuthParams = query; + + if (!id || !token || !key) { + return this._sendErrorAndClose(socket, Errors.INVALID_WS_PARAMETERS); + } + + if (key !== this.config.key) { + return this._sendErrorAndClose(socket, Errors.INVALID_KEY); + } + + const client = this.realm.getClientById(id); + + if (client) { + if (token !== client.getToken()) { + // ID-taken, invalid token + socket.send(JSON.stringify({ + type: MessageType.ID_TAKEN, + payload: { msg: "ID is taken" } + })); + + return socket.close(); + } + + return this._configureWS(socket, client); + } + + this._registerClient({ socket, id, token }); + } + + private _onSocketError(error: Error): void { + // handle error + this.emit("error", error); + } + + private _registerClient({ socket, id, token }: + { + socket: MyWebSocket; + id: string; + token: string; + }): void { + // Check concurrent limit + const clientsCount = this.realm.getClientsIds().length; + + if (clientsCount >= this.config.concurrent_limit) { + return this._sendErrorAndClose(socket, Errors.CONNECTION_LIMIT_EXCEED); + } + + const newClient: IClient = new Client({ id, token }); + this.realm.setClient(newClient, id); + socket.send(JSON.stringify({ type: MessageType.OPEN })); + + this._configureWS(socket, newClient); + } + + private _configureWS(socket: MyWebSocket, client: IClient): void { + client.setSocket(socket); + + // Cleanup after a socket closes. + socket.on("close", () => { + if (client.getSocket() === socket) { + this.realm.removeClientById(client.getId()); + this.emit("close", client); + } + }); + + // Handle messages from peers. + socket.on("message", (data: WebSocketLib.Data) => { + try { + const message = JSON.parse(data as string); + + message.src = client.getId(); + + this.emit("message", client, message); + } catch (e) { + this.emit("error", e); + } + }); + + this.emit("connection", client); + } + + private _sendErrorAndClose(socket: MyWebSocket, msg: Errors): void { + socket.send( + JSON.stringify({ + type: MessageType.ERROR, + payload: { msg } + }) + ); + + socket.close(); + } +} diff --git a/src/services/webSocketServer/webSocket.ts b/src/services/webSocketServer/webSocket.ts new file mode 100644 index 0000000..1e04565 --- /dev/null +++ b/src/services/webSocketServer/webSocket.ts @@ -0,0 +1,4 @@ +import EventEmitter from "events"; +import WebSocketLib from "ws"; + +export type MyWebSocket = WebSocketLib & EventEmitter; diff --git a/test/messageHandler/handlers/heartbeat/index.js b/test/messageHandler/handlers/heartbeat/index.js index de76b79..bd3ce5d 100644 --- a/test/messageHandler/handlers/heartbeat/index.js +++ b/test/messageHandler/handlers/heartbeat/index.js @@ -1,4 +1,4 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; const Client = require('../../../../src/models/client'); const heartbeatHandler = require('../../../../src/messageHandler/handlers/heartbeat'); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..677ac8b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "lib": [ + "es5", + "es6", + "es7", + "es2017" + ], + "target": "es2016", + "module": "commonjs", + "esModuleInterop": true, + "downlevelIteration": true, + "moduleResolution": "node", + "noImplicitAny": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "outDir": "dist", + "sourceMap": false, + }, + "include": [ + "./src/**/*", + "./config/**/*", + ], + "exclude": [ + "./test/", + "./node_modules/", + "./bin/" + ] +} \ No newline at end of file diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..b3bc555 --- /dev/null +++ b/tslint.json @@ -0,0 +1,20 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:recommended" + ], + "jsRules": {}, + "rules": { + "trailing-comma": [ + false + ], + "object-literal-sort-keys": false + }, + "rulesDirectory": [], + "linterOptions": { + "exclude": [ + "./bin/", + "./test/" + ] + } +} \ No newline at end of file From 1daa092eea38d8433de48872db27ed9da2b8a861 Mon Sep 17 00:00:00 2001 From: afrokick Date: Fri, 23 Aug 2019 16:04:19 +0300 Subject: [PATCH 2/6] fix tests --- dist/src/config/index.js | 18 +++++++++++++++++ dist/src/index.js | 4 ++-- .../handlers/heartbeat/index.js | 5 ++--- dist/src/messageHandler/handlers/index.js | 6 ++++++ .../handlers/transmission/index.js | 5 ++--- dist/src/messageHandler/index.js | 10 +++------- .../services/checkBrokenConnections/index.js | 2 +- package.json | 2 +- src/api/index.ts | 2 +- src/api/middleware/auth/index.ts | 2 +- src/api/v1/public/index.ts | 2 +- {config => src/config}/index.ts | 2 +- src/index.ts | 6 ++---- .../handlers/heartbeat/index.ts | 4 ++-- src/messageHandler/handlers/index.ts | 2 ++ .../handlers/transmission/index.ts | 4 ++-- src/messageHandler/index.ts | 3 +-- src/services/checkBrokenConnections/index.ts | 6 ++++-- src/services/messagesExpire/index.ts | 2 +- src/services/webSocketServer/index.ts | 2 +- .../handlers/heartbeat/index.js | 8 ++++---- test/models/realm.js | 4 ++-- test/services/checkBrokenConnections/index.js | 20 +++++++++---------- tsconfig.json | 3 +-- 24 files changed, 71 insertions(+), 53 deletions(-) create mode 100644 dist/src/config/index.js create mode 100644 dist/src/messageHandler/handlers/index.js rename {config => src/config}/index.ts (97%) create mode 100644 src/messageHandler/handlers/index.ts diff --git a/dist/src/config/index.js b/dist/src/config/index.js new file mode 100644 index 0000000..b95d622 --- /dev/null +++ b/dist/src/config/index.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const defaultConfig = { + port: 9000, + expire_timeout: 5000, + alive_timeout: 60000, + key: "peerjs", + path: "/myapp", + concurrent_limit: 5000, + allow_discovery: false, + proxied: false, + cleanup_out_msgs: 1000, + ssl: { + key: "", + cert: "" + } +}; +exports.default = defaultConfig; diff --git a/dist/src/index.js b/dist/src/index.js index 948f4e4..8ea5bfa 100644 --- a/dist/src/index.js +++ b/dist/src/index.js @@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); const express_1 = __importDefault(require("express")); const http_1 = __importDefault(require("http")); const https_1 = __importDefault(require("https")); -const config_1 = __importDefault(require("../config")); const api_1 = require("./api"); +const config_1 = __importDefault(require("./config")); const messageHandler_1 = require("./messageHandler"); const realm_1 = require("./models/realm"); const checkBrokenConnections_1 = require("./services/checkBrokenConnections"); @@ -30,7 +30,7 @@ const init = ({ app, server, options }) => { const wss = new webSocketServer_1.WebSocketServer({ server, realm, - config: Object.assign({}, config) + config }); wss.on("connection", (client) => { const messageQueue = realm.getMessageQueueById(client.getId()); diff --git a/dist/src/messageHandler/handlers/heartbeat/index.js b/dist/src/messageHandler/handlers/heartbeat/index.js index 80c7b6a..22269ab 100644 --- a/dist/src/messageHandler/handlers/heartbeat/index.js +++ b/dist/src/messageHandler/handlers/heartbeat/index.js @@ -1,8 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -function default_1(client) { +exports.HeartbeatHandler = (client) => { const nowTime = new Date().getTime(); client.setLastPing(nowTime); return true; -} -exports.default = default_1; +}; diff --git a/dist/src/messageHandler/handlers/index.js b/dist/src/messageHandler/handlers/index.js new file mode 100644 index 0000000..f053a44 --- /dev/null +++ b/dist/src/messageHandler/handlers/index.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var heartbeat_1 = require("./heartbeat"); +exports.HeartbeatHandler = heartbeat_1.HeartbeatHandler; +var transmission_1 = require("./transmission"); +exports.TransmissionHandler = transmission_1.TransmissionHandler; diff --git a/dist/src/messageHandler/handlers/transmission/index.js b/dist/src/messageHandler/handlers/transmission/index.js index f099da5..1a6d0d3 100644 --- a/dist/src/messageHandler/handlers/transmission/index.js +++ b/dist/src/messageHandler/handlers/transmission/index.js @@ -1,7 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const enums_1 = require("../../../enums"); -function default_1({ realm }) { +exports.TransmissionHandler = ({ realm }) => { const handle = (client, message) => { const type = message.type; const srcId = message.src; @@ -53,5 +53,4 @@ function default_1({ realm }) { return true; }; return handle; -} -exports.default = default_1; +}; diff --git a/dist/src/messageHandler/index.js b/dist/src/messageHandler/index.js index 0cdaa9f..b3acd87 100644 --- a/dist/src/messageHandler/index.js +++ b/dist/src/messageHandler/index.js @@ -1,17 +1,13 @@ "use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", { value: true }); const enums_1 = require("../enums"); -const heartbeat_1 = __importDefault(require("./handlers/heartbeat")); -const transmission_1 = __importDefault(require("./handlers/transmission")); +const handlers_1 = require("./handlers"); const messageHandlers_1 = require("./messageHandlers"); class MessageHandler { constructor(realm) { this.messageHandlers = new messageHandlers_1.MessageHandlers(); - const transmissionHandler = transmission_1.default({ realm }); - const heartbeatHandler = heartbeat_1.default; + const transmissionHandler = handlers_1.TransmissionHandler({ realm }); + const heartbeatHandler = handlers_1.HeartbeatHandler; const handleTransmission = (client, message) => { return transmissionHandler(client, { type: message.type, diff --git a/dist/src/services/checkBrokenConnections/index.js b/dist/src/services/checkBrokenConnections/index.js index 0d8d7fe..60a96da 100644 --- a/dist/src/services/checkBrokenConnections/index.js +++ b/dist/src/services/checkBrokenConnections/index.js @@ -27,7 +27,7 @@ class CheckBrokenConnections { checkConnections() { const clientsIds = this.realm.getClientsIds(); const now = new Date().getTime(); - const aliveTimeout = this.config.alive_timeout; + const { alive_timeout: aliveTimeout } = this.config; for (const clientId of clientsIds) { const client = this.realm.getClientById(clientId); const timeSinceLastPing = now - client.getLastPing(); diff --git a/package.json b/package.json index 5160569..8aec916 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "lint": "tslint -c tslint.json -p tsconfig.json --fix", "tsc": "tsc", "prebuild": "npm run lint", - "test": "npm run lint && mocha \"test/**/*.js\"", + "test": "npm run lint && npm run build && mocha \"test/**/*.js\"", "start": "bin/peerjs --port ${PORT:=9000}", "dev:start": "npm-run-all build start", "dev": "nodemon --watch src -e ts --exec npm run dev:start" diff --git a/src/api/index.ts b/src/api/index.ts index 9b44cc6..f1539af 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -2,7 +2,7 @@ import bodyParser from "body-parser"; import cors from "cors"; import express from "express"; import publicContent from "../../app.json"; -import { IConfig } from "../../config/"; +import { IConfig } from "../config"; import { IMessageHandler } from "../messageHandler"; import { IRealm } from "../models/realm"; import { AuthMiddleware } from "./middleware/auth"; diff --git a/src/api/middleware/auth/index.ts b/src/api/middleware/auth/index.ts index 92c7cdf..c46e206 100644 --- a/src/api/middleware/auth/index.ts +++ b/src/api/middleware/auth/index.ts @@ -1,5 +1,5 @@ import express from "express"; -import { IConfig } from "../../../../config"; +import { IConfig } from "../../../config"; import { Errors } from "../../../enums"; import { IRealm } from "../../../models/realm"; import { IMiddleware } from "../middleware"; diff --git a/src/api/v1/public/index.ts b/src/api/v1/public/index.ts index ab8ded9..b968102 100644 --- a/src/api/v1/public/index.ts +++ b/src/api/v1/public/index.ts @@ -1,5 +1,5 @@ import express from "express"; -import { IConfig } from "../../../../config"; +import { IConfig } from "../../../config"; import { IRealm } from "../../../models/realm"; export default ({ config, realm }: { diff --git a/config/index.ts b/src/config/index.ts similarity index 97% rename from config/index.ts rename to src/config/index.ts index cfff64c..3683e73 100644 --- a/config/index.ts +++ b/src/config/index.ts @@ -8,7 +8,7 @@ export interface IConfig { readonly allow_discovery: boolean; readonly proxied: boolean | string; readonly cleanup_out_msgs: number; - readonly ssl: { + readonly ssl?: { key: string; cert: string; }; diff --git a/src/index.ts b/src/index.ts index 4b50679..849e33f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,8 +5,8 @@ import http from "http"; import https from "https"; import { Server } from "net"; -import defaultConfig, { IConfig } from "../config"; import { Api } from "./api"; +import defaultConfig, { IConfig } from "./config"; import { MessageHandler } from "./messageHandler"; import { IClient } from "./models/client"; import { IMessage } from "./models/message"; @@ -39,9 +39,7 @@ const init = ({ app, server, options }: { const wss: IWebSocketServer = new WebSocketServer({ server, realm, - config: { - ...config, - } + config }); wss.on("connection", (client: IClient) => { diff --git a/src/messageHandler/handlers/heartbeat/index.ts b/src/messageHandler/handlers/heartbeat/index.ts index 135b730..6d8fcdf 100644 --- a/src/messageHandler/handlers/heartbeat/index.ts +++ b/src/messageHandler/handlers/heartbeat/index.ts @@ -1,7 +1,7 @@ import { IClient } from "../../../models/client"; -export default function(client: IClient): boolean { +export const HeartbeatHandler = (client: IClient): boolean => { const nowTime = new Date().getTime(); client.setLastPing(nowTime); return true; -} +}; diff --git a/src/messageHandler/handlers/index.ts b/src/messageHandler/handlers/index.ts new file mode 100644 index 0000000..45095d3 --- /dev/null +++ b/src/messageHandler/handlers/index.ts @@ -0,0 +1,2 @@ +export { HeartbeatHandler } from "./heartbeat"; +export { TransmissionHandler } from "./transmission"; diff --git a/src/messageHandler/handlers/transmission/index.ts b/src/messageHandler/handlers/transmission/index.ts index fc24479..7be3cb6 100644 --- a/src/messageHandler/handlers/transmission/index.ts +++ b/src/messageHandler/handlers/transmission/index.ts @@ -3,7 +3,7 @@ import { IClient } from "../../../models/client"; import { IMessage } from "../../../models/message"; import { IRealm } from "../../../models/realm"; -export default function({ realm }: { realm: IRealm }): (client: IClient, message: IMessage) => boolean { +export const TransmissionHandler = ({ realm }: { realm: IRealm }): (client: IClient, message: IMessage) => boolean => { const handle = (client: IClient, message: IMessage) => { const type = message.type; const srcId = message.src; @@ -55,4 +55,4 @@ export default function({ realm }: { realm: IRealm }): (client: IClient, message }; return handle; -} +}; diff --git a/src/messageHandler/index.ts b/src/messageHandler/index.ts index a892c98..cb75920 100644 --- a/src/messageHandler/index.ts +++ b/src/messageHandler/index.ts @@ -3,8 +3,7 @@ import { IClient } from "../models/client"; import { IMessage } from "../models/message"; import { IRealm } from "../models/realm"; import { Handler } from "./handler"; -import HeartbeatHandler from "./handlers/heartbeat"; -import TransmissionHandler from "./handlers/transmission"; +import { HeartbeatHandler, TransmissionHandler } from "./handlers"; import { IMessageHandlers, MessageHandlers } from "./messageHandlers"; export interface IMessageHandler { diff --git a/src/services/checkBrokenConnections/index.ts b/src/services/checkBrokenConnections/index.ts index f4629f9..29f94f4 100644 --- a/src/services/checkBrokenConnections/index.ts +++ b/src/services/checkBrokenConnections/index.ts @@ -1,4 +1,4 @@ -import { IConfig } from "../../../config"; +import { IConfig } from "../../config"; import { IClient } from "../../models/client"; import { IRealm } from "../../models/realm"; @@ -37,17 +37,19 @@ export class CheckBrokenConnections { this.start(); }, this.checkInterval); } + public stop(): void { if (this.timeoutId) { clearTimeout(this.timeoutId); this.timeoutId = null; } } + private checkConnections(): void { const clientsIds = this.realm.getClientsIds(); const now = new Date().getTime(); - const aliveTimeout = this.config.alive_timeout; + const { alive_timeout: aliveTimeout } = this.config; for (const clientId of clientsIds) { const client = this.realm.getClientById(clientId); diff --git a/src/services/messagesExpire/index.ts b/src/services/messagesExpire/index.ts index b39c16b..4d8ebe7 100644 --- a/src/services/messagesExpire/index.ts +++ b/src/services/messagesExpire/index.ts @@ -1,4 +1,4 @@ -import { IConfig } from "../../../config"; +import { IConfig } from "../../config"; import { MessageType } from "../../enums"; import { IMessageHandler } from "../../messageHandler"; import { IRealm } from "../../models/realm"; diff --git a/src/services/webSocketServer/index.ts b/src/services/webSocketServer/index.ts index 5c59e19..ae0ddf2 100644 --- a/src/services/webSocketServer/index.ts +++ b/src/services/webSocketServer/index.ts @@ -2,7 +2,7 @@ import EventEmitter from "events"; import { IncomingMessage } from "http"; import url from "url"; import WebSocketLib from "ws"; -import { IConfig } from "../../../config"; +import { IConfig } from "../../config"; import { Errors, MessageType } from "../../enums"; import { Client, IClient } from "../../models/client"; import { IRealm } from "../../models/realm"; diff --git a/test/messageHandler/handlers/heartbeat/index.js b/test/messageHandler/handlers/heartbeat/index.js index bd3ce5d..b5c39c2 100644 --- a/test/messageHandler/handlers/heartbeat/index.js +++ b/test/messageHandler/handlers/heartbeat/index.js @@ -1,6 +1,6 @@ -import { expect } from 'chai'; -const Client = require('../../../../src/models/client'); -const heartbeatHandler = require('../../../../src/messageHandler/handlers/heartbeat'); +const { expect } = require('chai'); +const { Client } = require('../../../../dist/src/models/client'); +const { HeartbeatHandler } = require('../../../../dist/src/messageHandler/handlers'); describe('Heartbeat handler', () => { it('should update last ping time', () => { @@ -9,7 +9,7 @@ describe('Heartbeat handler', () => { const nowTime = new Date().getTime(); - heartbeatHandler(client); + HeartbeatHandler(client); expect(client.getLastPing()).to.be.closeTo(nowTime, 2); }); diff --git a/test/models/realm.js b/test/models/realm.js index 16e0bd8..b8fbd63 100644 --- a/test/models/realm.js +++ b/test/models/realm.js @@ -1,6 +1,6 @@ const { expect } = require('chai'); -const Realm = require('../../src/models/realm'); -const Client = require('../../src/models/client'); +const { Realm } = require('../../dist/src/models/realm'); +const { Client } = require('../../dist/src/models/client'); describe('Realm', () => { describe('#generateClientId', () => { diff --git a/test/services/checkBrokenConnections/index.js b/test/services/checkBrokenConnections/index.js index 1d77ad5..6ac94fd 100644 --- a/test/services/checkBrokenConnections/index.js +++ b/test/services/checkBrokenConnections/index.js @@ -1,13 +1,13 @@ const { expect } = require('chai'); -const Client = require('../../../src/models/client'); -const Realm = require('../../../src/models/realm'); -const checkBrokenConnectionsBuilder = require('../../../src/services/checkBrokenConnections'); +const { Client } = require('../../../dist/src/models/client'); +const { Realm } = require('../../../dist/src/models/realm'); +const { CheckBrokenConnections } = require('../../../dist/src/services/checkBrokenConnections'); describe('checkBrokenConnections service', () => { it('should remove client after 2 checks', (done) => { const realm = new Realm(); - const doubleCheckTime = 55;//~ equals to checkBrokenConnections.CHECK_INTERVAL * 2 - const checkBrokenConnections = checkBrokenConnectionsBuilder({ realm, config: { alive_timeout: doubleCheckTime }, checkInterval: 30 }); + const doubleCheckTime = 55;//~ equals to checkBrokenConnections.checkInterval * 2 + const checkBrokenConnections = new CheckBrokenConnections({ realm, config: { alive_timeout: doubleCheckTime }, checkInterval: 30 }); const client = new Client({ id: 'id', token: '' }); realm.setClient(client, 'id'); @@ -17,13 +17,13 @@ describe('checkBrokenConnections service', () => { expect(realm.getClientById('id')).to.be.undefined; checkBrokenConnections.stop(); done(); - }, checkBrokenConnections.CHECK_INTERVAL * 2 + 3); + }, checkBrokenConnections.checkInterval * 2 + 10); }); it('should remove client after 1 ping', (done) => { const realm = new Realm(); - const doubleCheckTime = 55;//~ equals to checkBrokenConnections.CHECK_INTERVAL * 2 - const checkBrokenConnections = checkBrokenConnectionsBuilder({ realm, config: { alive_timeout: doubleCheckTime }, checkInterval: 30 }); + const doubleCheckTime = 55;//~ equals to checkBrokenConnections.checkInterval * 2 + const checkBrokenConnections = new CheckBrokenConnections({ realm, config: { alive_timeout: doubleCheckTime }, checkInterval: 30 }); const client = new Client({ id: 'id', token: '' }); realm.setClient(client, 'id'); @@ -37,7 +37,7 @@ describe('checkBrokenConnections service', () => { expect(realm.getClientById('id')).to.be.undefined; checkBrokenConnections.stop(); done(); - }, checkBrokenConnections.CHECK_INTERVAL * 2 + 10); - }, checkBrokenConnections.CHECK_INTERVAL); + }, checkBrokenConnections.checkInterval * 2 + 10); + }, checkBrokenConnections.checkInterval); }); }); diff --git a/tsconfig.json b/tsconfig.json index 677ac8b..187507c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,11 +21,10 @@ }, "include": [ "./src/**/*", - "./config/**/*", ], "exclude": [ "./test/", "./node_modules/", - "./bin/" + "./bin/", ] } \ No newline at end of file From 42a626629b7b568720090df14b56508183f560f2 Mon Sep 17 00:00:00 2001 From: afrokick Date: Fri, 23 Aug 2019 16:47:34 +0300 Subject: [PATCH 3/6] add eslint for ts --- .eslintignore | 2 + .eslintrc.json | 22 + package-lock.json | 762 ++++++++++++++++-- package.json | 10 +- src/services/checkBrokenConnections/index.ts | 6 +- .../handlers/heartbeat/{index.js => index.ts} | 6 +- test/models/{realm.js => realm.ts} | 6 +- .../{index.js => index.ts} | 8 +- tslint.json | 20 - 9 files changed, 739 insertions(+), 103 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.json rename test/messageHandler/handlers/heartbeat/{index.js => index.ts} (64%) rename test/models/{realm.js => realm.ts} (89%) rename test/services/checkBrokenConnections/{index.js => index.ts} (86%) delete mode 100644 tslint.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..26fb431 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +src/ +dist/ \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..a55ef24 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,22 @@ +{ + "parser": "@typescript-eslint/parser", + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ], + "env": { + "node": true, + "es6": true, + "mocha": true + }, + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "no-var": "error", + "no-console": "off", + "@typescript-eslint/camelcase": "off" + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e4ace55..ef5f636 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,6 +99,12 @@ "@types/express": "*" } }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.1.tgz", @@ -118,6 +124,12 @@ "@types/range-parser": "*" } }, + "@types/json-schema": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz", + "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==", + "dev": true + }, "@types/mime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", @@ -156,6 +168,71 @@ "@types/node": "*" } }, + "@typescript-eslint/eslint-plugin": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.0.0.tgz", + "integrity": "sha512-Mo45nxTTELODdl7CgpZKJISvLb+Fu64OOO2ZFc2x8sYSnUpFrBUW3H+H/ZGYmEkfnL6VkdtOSxgdt+Av79j0sA==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.0.0", + "eslint-utils": "^1.4.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^2.0.1", + "tsutils": "^3.14.0" + }, + "dependencies": { + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.0.0.tgz", + "integrity": "sha512-XGJG6GNBXIEx/mN4eTRypN/EUmsd0VhVGQ1AG+WTgdvjHl0G8vHhVBHrd/5oI6RRYBRnedNymSYWW1HAdivtmg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.0.0", + "eslint-scope": "^4.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.0.0.tgz", + "integrity": "sha512-ibyMBMr0383ZKserIsp67+WnNVoM402HKkxqXGlxEZsXtnGGurbnY90pBO3e0nBUM7chEEOcxUhgw9aPq7fEBA==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.0.0", + "@typescript-eslint/typescript-estree": "2.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.0.0.tgz", + "integrity": "sha512-NXbmzA3vWrSgavymlzMWNecgNOuiMMp62MO3kI7awZRLRcsA1QrYWo6q08m++uuAGVbXH/prZi2y1AWuhSu63w==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -171,6 +248,30 @@ "negotiator": "0.6.2" } }, + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "dev": true + }, + "acorn-jsx": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "dev": true + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -186,6 +287,12 @@ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", "dev": true }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -284,6 +391,12 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", @@ -469,12 +582,6 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -497,6 +604,12 @@ "unset-value": "^1.0.0" } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -545,6 +658,12 @@ } } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -629,6 +748,21 @@ "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", "dev": true }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", @@ -671,12 +805,6 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true - }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -810,6 +938,12 @@ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -876,6 +1010,15 @@ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -961,6 +1104,105 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "eslint": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.2.1.tgz", + "integrity": "sha512-ES7BzEzr0Q6m5TK9i+/iTpKjclXitOdDK4vT07OqbkBT2/VcN/gO9EL1C4HlK3TAOXYv2ItcmbVR9jO1MR0fJg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "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.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + } + } + }, "eslint-scope": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", @@ -971,18 +1213,47 @@ "estraverse": "^4.1.1" } }, + "eslint-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, "eslint-visitor-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", "dev": true }, + "espree": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.0.tgz", + "integrity": "sha512-boA7CHRLlVWUSg3iL5Kmlt/xT3Q+sXnKoRYYzj1YeM10A76TEJBbotV5pKbnK42hEUIr121zTv+QLRM5LsCPXQ==", + "dev": true, + "requires": { + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.1.0" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", @@ -1117,6 +1388,17 @@ } } }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -1182,6 +1464,42 @@ } } }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -1237,6 +1555,34 @@ "is-buffer": "~2.0.3" } }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -1822,6 +2168,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1863,6 +2215,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", @@ -1872,6 +2233,12 @@ "ini": "^1.3.4" } }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "got": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", @@ -1994,12 +2361,37 @@ "toidentifier": "1.0.0" } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", "dev": true }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", @@ -2033,6 +2425,44 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", @@ -2250,6 +2680,12 @@ "isobject": "^3.0.1" } }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, "is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", @@ -2326,6 +2762,18 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "just-extend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", @@ -2356,6 +2804,16 @@ "invert-kv": "^2.0.0" } }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -2642,6 +3100,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, "nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", @@ -2668,6 +3132,12 @@ "to-regex": "^3.0.1" } }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -2918,6 +3388,23 @@ "wrappy": "1" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + } + } + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -2927,6 +3414,28 @@ "wordwrap": "~0.0.2" } }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", @@ -2938,6 +3447,12 @@ "mem": "^4.0.0" } }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", @@ -2992,6 +3507,15 @@ "semver": "^5.1.0" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -3087,6 +3611,12 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", @@ -3099,6 +3629,12 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -3130,6 +3666,12 @@ "once": "^1.3.1" } }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", @@ -3228,6 +3770,12 @@ "safe-regex": "^1.1.0" } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "registry-auth-token": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", @@ -3286,12 +3834,28 @@ "path-parse": "^1.0.6" } }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -3307,6 +3871,24 @@ "glob": "^7.1.3" } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -3466,6 +4048,17 @@ } } }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -3759,6 +4352,46 @@ "has-flag": "^3.0.0" } }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "term-size": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", @@ -3802,12 +4435,33 @@ } } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", "dev": true }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", @@ -3908,34 +4562,13 @@ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true }, - "tslint": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.19.0.tgz", - "integrity": "sha512-1LwwtBxfRJZnUvoS9c0uj8XQtAnyhWr9KlNvDIdB+oXyT+VpsOAaEhEgKi1HrZ8rq0ki/AAnbGSv4KM6/AfVZw==", + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^3.2.0", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - } - }, - "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" + "prelude-ls": "~1.1.2" } }, "type-detect": { @@ -3959,35 +4592,6 @@ "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==", "dev": true }, - "typescript-eslint-parser": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/typescript-eslint-parser/-/typescript-eslint-parser-22.0.0.tgz", - "integrity": "sha512-pD8D7oTeRwWvFVxK3PaY6FYAiZsuRXFkIc2+1xkwCT3NduySgCgjeAkR5/dnIWecOiFVcEHf4ypXurF02Q6Z3Q==", - "dev": true, - "requires": { - "eslint-scope": "^4.0.0", - "eslint-visitor-keys": "^1.0.0", - "typescript-estree": "18.0.0" - } - }, - "typescript-estree": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/typescript-estree/-/typescript-estree-18.0.0.tgz", - "integrity": "sha512-HxTWrzFyYOPWA91Ij7xL9mNUVpGTKLH2KiaBn28CMbYgX2zgWdJqU9hO7Are+pAPAqY91NxAYoaAyDDZ3rLj2A==", - "dev": true, - "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true - } - } - }, "undefsafe": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", @@ -4093,6 +4697,15 @@ "xdg-basedir": "^3.0.0" } }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -4125,6 +4738,12 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -4231,6 +4850,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", diff --git a/package.json b/package.json index 8aec916..4cae464 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,10 @@ "scripts": { "build": "tsc", "clean": "rimraf ./dist", - "lint": "tslint -c tslint.json -p tsconfig.json --fix", + "lint": "eslint --ext .js,.ts .", "tsc": "tsc", "prebuild": "npm run lint", - "test": "npm run lint && npm run build && mocha \"test/**/*.js\"", + "test": "npm run lint && mocha -r ts-node/register \"test/**/*\"", "start": "bin/peerjs --port ${PORT:=9000}", "dev:start": "npm-run-all build start", "dev": "nodemon --watch src -e ts --exec npm run dev:start" @@ -40,17 +40,19 @@ "@types/chai": "^4.1.7", "@types/mocha": "^5.2.7", "@types/node": "^10.14.16", + "@typescript-eslint/eslint-plugin": "^2.0.0", + "@typescript-eslint/parser": "^2.0.0", "chai": "^4.2.0", + "eslint": "^6.2.1", "mocha": "^6.2.0", "nodemon": "^1.19.1", "npm-run-all": "^4.1.5", "rimraf": "^3.0.0", "sinon": "^7.4.1", "ts-node": "^8.3.0", - "tslint": "^5.19.0", "typescript": "^3.5.3" }, "engines": { "node": "^10" } -} \ No newline at end of file +} diff --git a/src/services/checkBrokenConnections/index.ts b/src/services/checkBrokenConnections/index.ts index 29f94f4..06f600b 100644 --- a/src/services/checkBrokenConnections/index.ts +++ b/src/services/checkBrokenConnections/index.ts @@ -4,17 +4,19 @@ import { IRealm } from "../../models/realm"; const DEFAULT_CHECK_INTERVAL = 300; +type CustomConfig = Pick; + export class CheckBrokenConnections { public readonly checkInterval: number; private timeoutId: NodeJS.Timeout; private readonly realm: IRealm; - private readonly config: IConfig; + private readonly config: CustomConfig; private readonly onClose?: (client: IClient) => void; constructor({ realm, config, checkInterval = DEFAULT_CHECK_INTERVAL, onClose }: { realm: IRealm, - config: IConfig, + config: CustomConfig, checkInterval?: number, onClose?: (client: IClient) => void }) { diff --git a/test/messageHandler/handlers/heartbeat/index.js b/test/messageHandler/handlers/heartbeat/index.ts similarity index 64% rename from test/messageHandler/handlers/heartbeat/index.js rename to test/messageHandler/handlers/heartbeat/index.ts index b5c39c2..c13d7c0 100644 --- a/test/messageHandler/handlers/heartbeat/index.js +++ b/test/messageHandler/handlers/heartbeat/index.ts @@ -1,6 +1,6 @@ -const { expect } = require('chai'); -const { Client } = require('../../../../dist/src/models/client'); -const { HeartbeatHandler } = require('../../../../dist/src/messageHandler/handlers'); +import { expect } from 'chai'; +import { Client } from '../../../../src/models/client'; +import { HeartbeatHandler } from '../../../../src/messageHandler/handlers'; describe('Heartbeat handler', () => { it('should update last ping time', () => { diff --git a/test/models/realm.js b/test/models/realm.ts similarity index 89% rename from test/models/realm.js rename to test/models/realm.ts index b8fbd63..7ca8876 100644 --- a/test/models/realm.js +++ b/test/models/realm.ts @@ -1,6 +1,6 @@ -const { expect } = require('chai'); -const { Realm } = require('../../dist/src/models/realm'); -const { Client } = require('../../dist/src/models/client'); +import { expect } from 'chai'; +import { Realm } from '../../src/models/realm'; +import { Client } from '../../src/models/client'; describe('Realm', () => { describe('#generateClientId', () => { diff --git a/test/services/checkBrokenConnections/index.js b/test/services/checkBrokenConnections/index.ts similarity index 86% rename from test/services/checkBrokenConnections/index.js rename to test/services/checkBrokenConnections/index.ts index 6ac94fd..e81c49c 100644 --- a/test/services/checkBrokenConnections/index.js +++ b/test/services/checkBrokenConnections/index.ts @@ -1,7 +1,7 @@ -const { expect } = require('chai'); -const { Client } = require('../../../dist/src/models/client'); -const { Realm } = require('../../../dist/src/models/realm'); -const { CheckBrokenConnections } = require('../../../dist/src/services/checkBrokenConnections'); +import { expect } from 'chai'; +import { Client } from '../../../src/models/client'; +import { Realm } from '../../../src/models/realm'; +import { CheckBrokenConnections } from '../../../src/services/checkBrokenConnections'; describe('checkBrokenConnections service', () => { it('should remove client after 2 checks', (done) => { diff --git a/tslint.json b/tslint.json deleted file mode 100644 index b3bc555..0000000 --- a/tslint.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": { - "trailing-comma": [ - false - ], - "object-literal-sort-keys": false - }, - "rulesDirectory": [], - "linterOptions": { - "exclude": [ - "./bin/", - "./test/" - ] - } -} \ No newline at end of file From 17e0177670be20b0f48218193154276750cba22b Mon Sep 17 00:00:00 2001 From: afrokick Date: Sun, 15 Dec 2019 13:27:56 +0300 Subject: [PATCH 4/6] fix uuid --- package-lock.json | 17 +++++++++++++---- package.json | 3 ++- src/models/realm.ts | 7 +++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index b327dae..fe10007 100644 --- a/package-lock.json +++ b/package-lock.json @@ -160,6 +160,15 @@ "@types/mime": "*" } }, + "@types/uuid": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.6.tgz", + "integrity": "sha512-cCdlC/1kGEZdEglzOieLDYBxHsvEOIg7kp/2FYyVR9Pxakq+Qf/inL3RKQ+PA8gOlI/NnL+fXmQH12nwcGzsHw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/ws": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.2.tgz", @@ -4738,10 +4747,10 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, - "uuid4": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/uuid4/-/uuid4-1.1.4.tgz", - "integrity": "sha512-Gr1q2k40LpF8CokcnQFjPDsdslzJbTCTBG5xQIEflUov431gFkY5KduiGIeKYAamkQnNn4IfdHJbLnl9Bib8TQ==" + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" }, "v8-compile-cache": { "version": "2.1.0", diff --git a/package.json b/package.json index 47dc2e8..4c8c956 100644 --- a/package.json +++ b/package.json @@ -34,13 +34,14 @@ "cors": "~2.8.4", "express": "^4.17.1", "optimist": "~0.6.1", - "uuid4": "^1.1.4", + "uuid": "3.3.3", "ws": "^7.1.2" }, "devDependencies": { "@types/chai": "^4.1.7", "@types/mocha": "^5.2.7", "@types/node": "^10.14.16", + "@types/uuid": "^3.4.6", "@typescript-eslint/eslint-plugin": "^2.0.0", "@typescript-eslint/parser": "^2.0.0", "chai": "^4.2.0", diff --git a/src/models/realm.ts b/src/models/realm.ts index 3f6fd1a..7b3ce19 100644 --- a/src/models/realm.ts +++ b/src/models/realm.ts @@ -1,3 +1,4 @@ +import uuidv4 from "uuid/v4"; import { IClient } from "./client"; import { IMessage } from "./message"; import { IMessageQueue, MessageQueue } from "./messageQueue"; @@ -69,12 +70,10 @@ export class Realm implements IRealm { } public generateClientId(): string { - const randomId = () => (Math.random().toString(36) + "0000000000000000000").substr(2, 16); - - let clientId = randomId(); + let clientId = uuidv4(); while (this.getClientById(clientId)) { - clientId = randomId(); + clientId = uuidv4(); } return clientId; From ed6379c1601c7fc330c3a047d933d7b25b39fabb Mon Sep 17 00:00:00 2001 From: afrokick Date: Sun, 15 Dec 2019 13:48:45 +0300 Subject: [PATCH 5/6] update ts to 3.7.3 --- .eslintrc.json | 3 +- dist/src/index.js | 4 +- dist/src/models/realm.js | 9 +- package-lock.json | 832 ++++++++++++++++++++------------------- package.json | 38 +- tsconfig.json | 15 +- 6 files changed, 459 insertions(+), 442 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index a55ef24..000419f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -17,6 +17,7 @@ "rules": { "no-var": "error", "no-console": "off", - "@typescript-eslint/camelcase": "off" + "@typescript-eslint/camelcase": "off", + "@typescript-eslint/interface-name-prefix": "off" } } \ No newline at end of file diff --git a/dist/src/index.js b/dist/src/index.js index 8ea5bfa..292c507 100644 --- a/dist/src/index.js +++ b/dist/src/index.js @@ -59,7 +59,7 @@ const init = ({ app, server, options }) => { }; function ExpressPeerServer(server, options) { const app = express_1.default(); - const newOptions = Object.assign({}, config_1.default, options); + const newOptions = Object.assign(Object.assign({}, config_1.default), options); if (newOptions.proxied) { app.set("trust proxy", newOptions.proxied === "false" ? false : !!newOptions.proxied); } @@ -75,7 +75,7 @@ function ExpressPeerServer(server, options) { exports.ExpressPeerServer = ExpressPeerServer; function PeerServer(options = {}, callback) { const app = express_1.default(); - const newOptions = Object.assign({}, config_1.default, options); + const newOptions = Object.assign(Object.assign({}, config_1.default), options); let path = newOptions.path; const port = newOptions.port; if (path[0] !== "/") { diff --git a/dist/src/models/realm.js b/dist/src/models/realm.js index 3682847..63f09e1 100644 --- a/dist/src/models/realm.js +++ b/dist/src/models/realm.js @@ -1,5 +1,9 @@ "use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); +const v4_1 = __importDefault(require("uuid/v4")); const messageQueue_1 = require("./messageQueue"); class Realm { constructor() { @@ -39,10 +43,9 @@ class Realm { this.messageQueues.delete(id); } generateClientId() { - const randomId = () => (Math.random().toString(36) + "0000000000000000000").substr(2, 16); - let clientId = randomId(); + let clientId = v4_1.default(); while (this.getClientById(clientId)) { - clientId = randomId(); + clientId = v4_1.default(); } return clientId; } diff --git a/package-lock.json b/package-lock.json index fe10007..7c57bca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,14 +22,6 @@ "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" - }, - "dependencies": { - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - } } }, "@sinonjs/commons": { @@ -42,9 +34,9 @@ } }, "@sinonjs/formatio": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", - "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", + "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", "dev": true, "requires": { "@sinonjs/commons": "^1", @@ -170,70 +162,93 @@ } }, "@types/ws": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.2.tgz", - "integrity": "sha512-22XiR1ox9LftTaAtn/c5JCninwc7moaqbkJfaDUb7PkaUitcf5vbTZHdq9dxSMviCm9C3W85rzB8e6yNR70apQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", + "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", "requires": { "@types/node": "*" } }, "@typescript-eslint/eslint-plugin": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.0.0.tgz", - "integrity": "sha512-Mo45nxTTELODdl7CgpZKJISvLb+Fu64OOO2ZFc2x8sYSnUpFrBUW3H+H/ZGYmEkfnL6VkdtOSxgdt+Av79j0sA==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.11.0.tgz", + "integrity": "sha512-G2HHA1vpMN0EEbUuWubiCCfd0R3a30BB+UdvnFkxwZIxYEGOrWEXDv8tBFO9f44CWc47Xv9lLM3VSn4ORLI2bA==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "2.0.0", - "eslint-utils": "^1.4.0", + "@typescript-eslint/experimental-utils": "2.11.0", + "eslint-utils": "^1.4.3", "functional-red-black-tree": "^1.0.1", - "regexpp": "^2.0.1", - "tsutils": "^3.14.0" - }, - "dependencies": { - "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" } }, "@typescript-eslint/experimental-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.0.0.tgz", - "integrity": "sha512-XGJG6GNBXIEx/mN4eTRypN/EUmsd0VhVGQ1AG+WTgdvjHl0G8vHhVBHrd/5oI6RRYBRnedNymSYWW1HAdivtmg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.11.0.tgz", + "integrity": "sha512-YxcA/y0ZJaCc/fB/MClhcDxHI0nOBB7v2/WxBju2cOTanX7jO9ttQq6Fy4yW9UaY5bPd9xL3cun3lDVqk67sPQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.0.0", - "eslint-scope": "^4.0.0" + "@typescript-eslint/typescript-estree": "2.11.0", + "eslint-scope": "^5.0.0" } }, "@typescript-eslint/parser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.0.0.tgz", - "integrity": "sha512-ibyMBMr0383ZKserIsp67+WnNVoM402HKkxqXGlxEZsXtnGGurbnY90pBO3e0nBUM7chEEOcxUhgw9aPq7fEBA==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.11.0.tgz", + "integrity": "sha512-DyGXeqhb3moMioEFZIHIp7oXBBh7dEfPTzGrlyP0Mi9ScCra4SWEGs3kPd18mG7Sy9Wy8z88zmrw5tSGL6r/6A==", "dev": true, "requires": { "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.0.0", - "@typescript-eslint/typescript-estree": "2.0.0", - "eslint-visitor-keys": "^1.0.0" + "@typescript-eslint/experimental-utils": "2.11.0", + "@typescript-eslint/typescript-estree": "2.11.0", + "eslint-visitor-keys": "^1.1.0" } }, "@typescript-eslint/typescript-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.0.0.tgz", - "integrity": "sha512-NXbmzA3vWrSgavymlzMWNecgNOuiMMp62MO3kI7awZRLRcsA1QrYWo6q08m++uuAGVbXH/prZi2y1AWuhSu63w==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.11.0.tgz", + "integrity": "sha512-HGY4+d4MagO6cKMcKfIKaTMxcAv7dEVnji2Zi+vi5VV8uWAM631KjAB5GxFcexMYrwKT0EekRiiGK1/Sd7VFGA==", "dev": true, "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", "lodash.unescape": "4.0.1", - "semver": "^6.2.0" + "semver": "^6.3.0", + "tsutils": "^3.17.1" }, "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -258,15 +273,15 @@ } }, "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", - "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, "ajv": { @@ -297,10 +312,13 @@ "dev": true }, "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", + "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } }, "ansi-regex": { "version": "3.0.0", @@ -339,9 +357,9 @@ } }, "arg": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz", - "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", + "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==", "dev": true }, "argparse": { @@ -758,12 +776,12 @@ "dev": true }, "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "restore-cursor": "^3.1.0" } }, "cli-width": { @@ -773,22 +791,50 @@ "dev": true }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -876,9 +922,9 @@ "dev": true }, "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", + "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", "requires": { "object-assign": "^4", "vary": "^1" @@ -1049,9 +1095,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "encodeurl": { @@ -1059,15 +1105,6 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -1114,9 +1151,9 @@ "dev": true }, "eslint": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.2.1.tgz", - "integrity": "sha512-ES7BzEzr0Q6m5TK9i+/iTpKjclXitOdDK4vT07OqbkBT2/VcN/gO9EL1C4HlK3TAOXYv2ItcmbVR9jO1MR0fJg==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz", + "integrity": "sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -1126,19 +1163,19 @@ "debug": "^4.0.1", "doctrine": "^3.0.0", "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.2", + "eslint-utils": "^1.4.3", "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.0", + "espree": "^6.1.2", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", - "globals": "^11.7.0", + "globals": "^12.1.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.4.1", + "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", @@ -1147,7 +1184,7 @@ "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", + "optionator": "^0.8.3", "progress": "^2.0.0", "regexpp": "^2.0.1", "semver": "^6.1.2", @@ -1173,22 +1210,18 @@ "ms": "^2.1.1" } }, - "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -1213,9 +1246,9 @@ } }, "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -1223,12 +1256,12 @@ } }, "eslint-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", - "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { @@ -1238,13 +1271,13 @@ "dev": true }, "espree": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.0.tgz", - "integrity": "sha512-boA7CHRLlVWUSg3iL5Kmlt/xT3Q+sXnKoRYYzj1YeM10A76TEJBbotV5pKbnK42hEUIr121zTv+QLRM5LsCPXQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", "dev": true, "requires": { - "acorn": "^7.0.0", - "acorn-jsx": "^5.0.0", + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", "eslint-visitor-keys": "^1.1.0" } }, @@ -1279,9 +1312,9 @@ "dev": true }, "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "etag": { @@ -1289,21 +1322,6 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -1480,9 +1498,9 @@ "dev": true }, "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { @@ -1492,9 +1510,9 @@ "dev": true }, "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -2195,15 +2213,6 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -2225,9 +2234,9 @@ } }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2243,10 +2252,13 @@ } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", + "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } }, "got": { "version": "6.7.1", @@ -2392,9 +2404,9 @@ "dev": true }, "import-fresh": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", - "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -2435,32 +2447,60 @@ "dev": true }, "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", + "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==", "dev": true, "requires": { - "ansi-escapes": "^3.2.0", + "ansi-escapes": "^4.2.1", "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", + "cli-cursor": "^3.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", "run-async": "^2.2.0", "rxjs": "^6.4.0", - "string-width": "^2.1.0", + "string-width": "^4.1.0", "strip-ansi": "^5.1.0", "through": "^2.3.6" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -2468,16 +2508,18 @@ "dev": true, "requires": { "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } } } } }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, "ipaddr.js": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", @@ -2525,9 +2567,9 @@ } }, "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", "dev": true }, "is-callable": { @@ -2755,6 +2797,12 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", @@ -2804,15 +2852,6 @@ "package-json": "^4.0.0" } }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -2903,15 +2942,6 @@ "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", "dev": true }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -2932,17 +2962,6 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -3057,9 +3076,9 @@ } }, "mocha": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.0.tgz", - "integrity": "sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.2.tgz", + "integrity": "sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A==", "dev": true, "requires": { "ansi-colors": "3.2.3", @@ -3082,9 +3101,9 @@ "supports-color": "6.0.0", "which": "1.3.1", "wide-align": "1.1.3", - "yargs": "13.2.2", - "yargs-parser": "13.0.0", - "yargs-unparser": "1.5.0" + "yargs": "13.3.0", + "yargs-parser": "13.1.1", + "yargs-unparser": "1.6.0" }, "dependencies": { "debug": { @@ -3110,9 +3129,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, "nan": { @@ -3159,9 +3178,9 @@ "dev": true }, "nise": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.1.tgz", - "integrity": "sha512-edFWm0fsFG2n318rfEnKlTZTkjlbVOFF9XIA+fj+Ed+Qz1laYW2lobwavWoMzGrYDHH1EpiNJgDfvGnkZztR/g==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.2.tgz", + "integrity": "sha512-/6RhOUlicRCbE9s+94qCUsyE+pKlVJ5AhIv+jEE7ESKwnbXqulKZ1FYU+XAtHHWE9TinYvAxDUJAb912PwPoWA==", "dev": true, "requires": { "@sinonjs/formatio": "^3.2.1", @@ -3178,9 +3197,9 @@ "dev": true }, "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, "requires": { "isarray": "0.0.1" @@ -3286,12 +3305,6 @@ "path-key": "^2.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3334,6 +3347,12 @@ } } }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, "object-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", @@ -3362,13 +3381,57 @@ } }, "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz", + "integrity": "sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } } }, "object.pick": { @@ -3398,20 +3461,12 @@ } }, "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "dev": true, "requires": { - "mimic-fn": "^1.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - } + "mimic-fn": "^2.1.0" } }, "optimist": { @@ -3424,36 +3479,17 @@ } }, "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", + "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - }, - "dependencies": { - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" + "word-wrap": "~1.2.3" } }, "os-tmpdir": { @@ -3462,24 +3498,12 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, "p-limit": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", @@ -3665,16 +3689,6 @@ "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", "dev": true }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -3780,9 +3794,9 @@ } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", + "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", "dev": true }, "registry-auth-token": { @@ -3856,12 +3870,12 @@ "dev": true }, "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { - "onetime": "^2.0.0", + "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, @@ -3890,9 +3904,9 @@ } }, "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -4032,17 +4046,17 @@ "dev": true }, "sinon": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.4.1.tgz", - "integrity": "sha512-7s9buHGHN/jqoy/v4bJgmt0m1XEkCEd/tqdHXumpBp0JSujaT4Ng84JU5wDdK4E85ZMq78NuDe0I3NAqXY8TFg==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.5.0.tgz", + "integrity": "sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q==", "dev": true, "requires": { "@sinonjs/commons": "^1.4.0", "@sinonjs/formatio": "^3.2.1", - "@sinonjs/samsam": "^3.3.2", + "@sinonjs/samsam": "^3.3.3", "diff": "^3.5.0", "lolex": "^4.2.0", - "nise": "^1.5.1", + "nise": "^1.5.2", "supports-color": "^5.5.0" }, "dependencies": { @@ -4207,9 +4221,9 @@ } }, "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -4316,6 +4330,26 @@ "function-bind": "^1.0.2" } }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -4379,6 +4413,12 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -4545,9 +4585,9 @@ } }, "ts-node": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", - "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.5.4.tgz", + "integrity": "sha512-izbVCRV68EasEPQ8MSIGBNK9dc/4sYJJKYA+IarMQct1RtEot6Xp0bXuClsbUSnKpg50ho+aOAx8en5c+y4OFw==", "dev": true, "requires": { "arg": "^4.1.0", @@ -4571,6 +4611,15 @@ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -4586,6 +4635,12 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -4596,9 +4651,9 @@ } }, "typescript": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz", - "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz", + "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==", "dev": true }, "undefsafe": { @@ -4806,54 +4861,58 @@ "string-width": "^2.1.1" } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" }, "dependencies": { "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^4.1.0" } } } @@ -4911,22 +4970,21 @@ "dev": true }, "yargs": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", - "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", "dev": true, "requires": { - "cliui": "^4.0.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.0.0" + "yargs-parser": "^13.1.1" }, "dependencies": { "ansi-regex": { @@ -4935,6 +4993,12 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -4958,9 +5022,9 @@ } }, "yargs-parser": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", - "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -4968,58 +5032,14 @@ } }, "yargs-unparser": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", - "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", "dev": true, "requires": { "flat": "^4.1.0", - "lodash": "^4.17.11", - "yargs": "^12.0.5" - }, - "dependencies": { - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } + "lodash": "^4.17.15", + "yargs": "^13.3.0" } }, "yn": { diff --git a/package.json b/package.json index 4c8c956..f4f1b03 100644 --- a/package.json +++ b/package.json @@ -27,32 +27,32 @@ "branch": "master" }, "dependencies": { - "@types/cors": "^2.8.6", - "@types/express": "^4.17.1", - "@types/ws": "^6.0.2", - "body-parser": "^1.19.0", - "cors": "~2.8.4", - "express": "^4.17.1", - "optimist": "~0.6.1", + "@types/cors": "2.8.6", + "@types/express": "4.17.1", + "@types/ws": "6.0.4", + "body-parser": "1.19.0", + "cors": "2.8.4", + "express": "4.17.1", + "optimist": "0.6.1", "uuid": "3.3.3", - "ws": "^7.1.2" + "ws": "7.1.2" }, "devDependencies": { "@types/chai": "^4.1.7", "@types/mocha": "^5.2.7", "@types/node": "^10.14.16", - "@types/uuid": "^3.4.6", - "@typescript-eslint/eslint-plugin": "^2.0.0", - "@typescript-eslint/parser": "^2.0.0", + "@types/uuid": "3.4.6", + "@typescript-eslint/eslint-plugin": "^2.11.0", + "@typescript-eslint/parser": "^2.11.0", "chai": "^4.2.0", - "eslint": "^6.2.1", - "mocha": "^6.2.0", - "nodemon": "^1.19.1", - "npm-run-all": "^4.1.5", - "rimraf": "^3.0.0", - "sinon": "^7.4.1", - "ts-node": "^8.3.0", - "typescript": "^3.5.3" + "eslint": "^6.7.2", + "mocha": "^6.2.2", + "nodemon": "1.19.1", + "npm-run-all": "4.1.5", + "rimraf": "3.0.0", + "sinon": "7.5.0", + "ts-node": "8.5.4", + "typescript": "3.7.3" }, "engines": { "node": ">=10" diff --git a/tsconfig.json b/tsconfig.json index 187507c..65ed033 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,7 @@ { "compilerOptions": { "lib": [ - "es5", - "es6", - "es7", - "es2017" + "esnext" ], "target": "es2016", "module": "commonjs", @@ -16,15 +13,11 @@ "noUnusedParameters": true, "resolveJsonModule": true, "skipLibCheck": true, - "outDir": "dist", "sourceMap": false, + "outDir": "dist" }, - "include": [ - "./src/**/*", - ], "exclude": [ - "./test/", - "./node_modules/", - "./bin/", + "test", + "bin", ] } \ No newline at end of file From 7c23ed83514f1dc58764ba638943c20afd4c3de6 Mon Sep 17 00:00:00 2001 From: afrokick Date: Sun, 15 Dec 2019 14:17:37 +0300 Subject: [PATCH 6/6] fix warnings --- dist/src/api/v1/calls/index.js | 6 ++++-- dist/src/index.js | 7 +------ .../messageHandler/handlers/heartbeat/index.js | 6 ++++-- .../handlers/transmission/index.js | 9 +++++---- dist/src/messageHandler/messageHandlers.js | 6 ++---- dist/src/models/client.js | 3 ++- dist/src/models/realm.js | 3 +-- .../services/checkBrokenConnections/index.js | 16 +++++----------- dist/src/services/messagesExpire/index.js | 5 ++--- src/api/v1/calls/index.ts | 8 ++++++-- src/index.ts | 10 +++------- src/messageHandler/handler.ts | 2 +- src/messageHandler/handlers/heartbeat/index.ts | 9 ++++++--- .../handlers/transmission/index.ts | 13 +++++++------ src/messageHandler/index.ts | 8 ++++---- src/messageHandler/messageHandlers.ts | 8 ++++---- src/models/client.ts | 10 +++++----- src/models/messageQueue.ts | 2 +- src/models/realm.ts | 4 ++-- src/services/checkBrokenConnections/index.ts | 17 +++++++---------- src/services/messagesExpire/index.ts | 10 +++++----- src/services/webSocketServer/index.ts | 4 ++-- tsconfig.json | 4 ++++ 23 files changed, 83 insertions(+), 87 deletions(-) diff --git a/dist/src/api/v1/calls/index.js b/dist/src/api/v1/calls/index.js index 807208c..17ae5e3 100644 --- a/dist/src/api/v1/calls/index.js +++ b/dist/src/api/v1/calls/index.js @@ -8,10 +8,12 @@ exports.default = ({ realm, messageHandler }) => { const app = express_1.default.Router(); const handle = (req, res, next) => { const { id } = req.params; - if (!id) { + if (!id) return next(); - } const client = realm.getClientById(id); + if (!client) { + throw new Error(`client not found:${id}`); + } const { type, dst, payload } = req.body; const message = { type, diff --git a/dist/src/index.js b/dist/src/index.js index 292c507..7137006 100644 --- a/dist/src/index.js +++ b/dist/src/index.js @@ -95,12 +95,7 @@ function PeerServer(options = {}, callback) { } const peerjs = ExpressPeerServer(server, newOptions); app.use(peerjs); - if (callback) { - server.listen(port, () => callback(server)); - } - else { - server.listen(port); - } + server.listen(port, () => { var _a; return (_a = callback) === null || _a === void 0 ? void 0 : _a(server); }); return peerjs; } exports.PeerServer = PeerServer; diff --git a/dist/src/messageHandler/handlers/heartbeat/index.js b/dist/src/messageHandler/handlers/heartbeat/index.js index 22269ab..d292fec 100644 --- a/dist/src/messageHandler/handlers/heartbeat/index.js +++ b/dist/src/messageHandler/handlers/heartbeat/index.js @@ -1,7 +1,9 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HeartbeatHandler = (client) => { - const nowTime = new Date().getTime(); - client.setLastPing(nowTime); + if (client) { + const nowTime = new Date().getTime(); + client.setLastPing(nowTime); + } return true; }; diff --git a/dist/src/messageHandler/handlers/transmission/index.js b/dist/src/messageHandler/handlers/transmission/index.js index 1a6d0d3..390eb6e 100644 --- a/dist/src/messageHandler/handlers/transmission/index.js +++ b/dist/src/messageHandler/handlers/transmission/index.js @@ -9,10 +9,11 @@ exports.TransmissionHandler = ({ realm }) => { const destinationClient = realm.getClientById(dstId); // User is connected! if (destinationClient) { + const socket = destinationClient.getSocket(); try { - if (destinationClient.getSocket()) { + if (socket) { const data = JSON.stringify(message); - destinationClient.getSocket().send(data); + socket.send(data); } else { // Neither socket no res available. Peer dead? @@ -23,8 +24,8 @@ exports.TransmissionHandler = ({ realm }) => { // This happens when a peer disconnects without closing connections and // the associated WebSocket has not closed. // Tell other side to stop trying. - if (destinationClient.getSocket()) { - destinationClient.getSocket().close(); + if (socket) { + socket.close(); } else { realm.removeClientById(destinationClient.getId()); diff --git a/dist/src/messageHandler/messageHandlers.js b/dist/src/messageHandler/messageHandlers.js index 167f3d6..01b1e06 100644 --- a/dist/src/messageHandler/messageHandlers.js +++ b/dist/src/messageHandler/messageHandlers.js @@ -5,17 +5,15 @@ class MessageHandlers { this.handlers = new Map(); } registerHandler(messageType, handler) { - if (this.handlers.has(messageType)) { + if (this.handlers.has(messageType)) return; - } this.handlers.set(messageType, handler); } handle(client, message) { const { type } = message; const handler = this.handlers.get(type); - if (!handler) { + if (!handler) return false; - } return handler(client, message); } } diff --git a/dist/src/models/client.js b/dist/src/models/client.js index 084d0b6..79473e4 100644 --- a/dist/src/models/client.js +++ b/dist/src/models/client.js @@ -26,7 +26,8 @@ class Client { this.lastPing = lastPing; } send(data) { - this.socket.send(JSON.stringify(data)); + var _a; + (_a = this.socket) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify(data)); } } exports.Client = Client; diff --git a/dist/src/models/realm.js b/dist/src/models/realm.js index 63f09e1..53fc672 100644 --- a/dist/src/models/realm.js +++ b/dist/src/models/realm.js @@ -24,9 +24,8 @@ class Realm { } removeClientById(id) { const client = this.getClientById(id); - if (!client) { + if (!client) return false; - } this.clients.delete(id); return true; } diff --git a/dist/src/services/checkBrokenConnections/index.js b/dist/src/services/checkBrokenConnections/index.js index 60a96da..f0e7115 100644 --- a/dist/src/services/checkBrokenConnections/index.js +++ b/dist/src/services/checkBrokenConnections/index.js @@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const DEFAULT_CHECK_INTERVAL = 300; class CheckBrokenConnections { constructor({ realm, config, checkInterval = DEFAULT_CHECK_INTERVAL, onClose }) { + this.timeoutId = null; this.realm = realm; this.config = config; this.onClose = onClose; @@ -25,30 +26,23 @@ class CheckBrokenConnections { } } checkConnections() { + var _a, _b, _c; const clientsIds = this.realm.getClientsIds(); const now = new Date().getTime(); const { alive_timeout: aliveTimeout } = this.config; for (const clientId of clientsIds) { const client = this.realm.getClientById(clientId); const timeSinceLastPing = now - client.getLastPing(); - if (timeSinceLastPing < aliveTimeout) { + if (timeSinceLastPing < aliveTimeout) continue; - } try { - if (client.getSocket()) { - client.getSocket().close(); - } - } - catch (e) { - // @ts-nocheck + (_a = client.getSocket()) === null || _a === void 0 ? void 0 : _a.close(); } finally { this.realm.clearMessageQueue(clientId); this.realm.removeClientById(clientId); client.setSocket(null); - if (this.onClose) { - this.onClose(client); - } + (_c = (_b = this).onClose) === null || _c === void 0 ? void 0 : _c.call(_b, client); } } } diff --git a/dist/src/services/messagesExpire/index.js b/dist/src/services/messagesExpire/index.js index 7e63c3b..9e9d6f2 100644 --- a/dist/src/services/messagesExpire/index.js +++ b/dist/src/services/messagesExpire/index.js @@ -33,13 +33,12 @@ class MessagesExpire { for (const destinationClientId of destinationClientsIds) { const messageQueue = this.realm.getMessageQueueById(destinationClientId); const lastReadDiff = now - messageQueue.getLastReadAt(); - if (lastReadDiff < maxDiff) { + if (lastReadDiff < maxDiff) continue; - } const messages = messageQueue.getMessages(); for (const message of messages) { if (!seen[message.src]) { - this.messageHandler.handle(null, { + this.messageHandler.handle(undefined, { type: enums_1.MessageType.EXPIRE, src: message.dst, dst: message.src diff --git a/src/api/v1/calls/index.ts b/src/api/v1/calls/index.ts index f96aae6..ea42f8c 100644 --- a/src/api/v1/calls/index.ts +++ b/src/api/v1/calls/index.ts @@ -3,16 +3,20 @@ import { IMessageHandler } from "../../../messageHandler"; import { IMessage } from "../../../models/message"; import { IRealm } from "../../../models/realm"; -export default ({ realm, messageHandler }: { realm: IRealm, messageHandler: IMessageHandler }): express.Router => { +export default ({ realm, messageHandler }: { realm: IRealm, messageHandler: IMessageHandler; }): express.Router => { const app = express.Router(); const handle = (req: express.Request, res: express.Response, next: express.NextFunction): any => { const { id } = req.params; - if (!id) { return next(); } + if (!id) return next(); const client = realm.getClientById(id); + if (!client) { + throw new Error(`client not found:${id}`); + } + const { type, dst, payload } = req.body; const message: IMessage = { diff --git a/src/index.ts b/src/index.ts index 849e33f..7e4b7e9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,7 +18,7 @@ import { IWebSocketServer, WebSocketServer } from "./services/webSocketServer"; const init = ({ app, server, options }: { app: express.Express, server: Server, - options: IConfig + options: IConfig; }) => { const config = options; const realm: IRealm = new Realm(); @@ -125,7 +125,7 @@ function PeerServer(options: Optional = {}, callback?: (server: Server) let server: Server; if (newOptions.ssl && newOptions.ssl.key && newOptions.ssl.cert) { - server = https.createServer(options.ssl, app); + server = https.createServer(options.ssl!, app); // @ts-ignore delete newOptions.ssl; } else { @@ -135,11 +135,7 @@ function PeerServer(options: Optional = {}, callback?: (server: Server) const peerjs = ExpressPeerServer(server, newOptions); app.use(peerjs); - if (callback) { - server.listen(port, () => callback(server)); - } else { - server.listen(port); - } + server.listen(port, () => callback?.(server)); return peerjs; } diff --git a/src/messageHandler/handler.ts b/src/messageHandler/handler.ts index b265878..4c81fde 100644 --- a/src/messageHandler/handler.ts +++ b/src/messageHandler/handler.ts @@ -1,4 +1,4 @@ import { IClient } from "../models/client"; import { IMessage } from "../models/message"; -export type Handler = (client: IClient, message: IMessage) => boolean; +export type Handler = (client: IClient | undefined, message: IMessage) => boolean; diff --git a/src/messageHandler/handlers/heartbeat/index.ts b/src/messageHandler/handlers/heartbeat/index.ts index 6d8fcdf..43bf35e 100644 --- a/src/messageHandler/handlers/heartbeat/index.ts +++ b/src/messageHandler/handlers/heartbeat/index.ts @@ -1,7 +1,10 @@ import { IClient } from "../../../models/client"; -export const HeartbeatHandler = (client: IClient): boolean => { - const nowTime = new Date().getTime(); - client.setLastPing(nowTime); +export const HeartbeatHandler = (client: IClient | undefined): boolean => { + if (client) { + const nowTime = new Date().getTime(); + client.setLastPing(nowTime); + } + return true; }; diff --git a/src/messageHandler/handlers/transmission/index.ts b/src/messageHandler/handlers/transmission/index.ts index 7be3cb6..defa00f 100644 --- a/src/messageHandler/handlers/transmission/index.ts +++ b/src/messageHandler/handlers/transmission/index.ts @@ -3,8 +3,8 @@ import { IClient } from "../../../models/client"; import { IMessage } from "../../../models/message"; import { IRealm } from "../../../models/realm"; -export const TransmissionHandler = ({ realm }: { realm: IRealm }): (client: IClient, message: IMessage) => boolean => { - const handle = (client: IClient, message: IMessage) => { +export const TransmissionHandler = ({ realm }: { realm: IRealm; }): (client: IClient | undefined, message: IMessage) => boolean => { + const handle = (client: IClient | undefined, message: IMessage) => { const type = message.type; const srcId = message.src; const dstId = message.dst; @@ -13,11 +13,12 @@ export const TransmissionHandler = ({ realm }: { realm: IRealm }): (client: ICli // User is connected! if (destinationClient) { + const socket = destinationClient.getSocket(); try { - if (destinationClient.getSocket()) { + if (socket) { const data = JSON.stringify(message); - destinationClient.getSocket().send(data); + socket.send(data); } else { // Neither socket no res available. Peer dead? throw new Error("Peer dead"); @@ -26,8 +27,8 @@ export const TransmissionHandler = ({ realm }: { realm: IRealm }): (client: ICli // This happens when a peer disconnects without closing connections and // the associated WebSocket has not closed. // Tell other side to stop trying. - if (destinationClient.getSocket()) { - destinationClient.getSocket().close(); + if (socket) { + socket.close(); } else { realm.removeClientById(destinationClient.getId()); } diff --git a/src/messageHandler/index.ts b/src/messageHandler/index.ts index cb75920..de03c45 100644 --- a/src/messageHandler/index.ts +++ b/src/messageHandler/index.ts @@ -7,7 +7,7 @@ import { HeartbeatHandler, TransmissionHandler } from "./handlers"; import { IMessageHandlers, MessageHandlers } from "./messageHandlers"; export interface IMessageHandler { - handle(client: IClient, message: IMessage): boolean; + handle(client: IClient | undefined, message: IMessage): boolean; } export class MessageHandler implements IMessageHandler { @@ -17,7 +17,7 @@ export class MessageHandler implements IMessageHandler { const transmissionHandler: Handler = TransmissionHandler({ realm }); const heartbeatHandler: Handler = HeartbeatHandler; - const handleTransmission: Handler = (client: IClient, message: IMessage): boolean => { + const handleTransmission: Handler = (client: IClient | undefined, message: IMessage): boolean => { return transmissionHandler(client, { type: message.type, src: message.src, @@ -26,7 +26,7 @@ export class MessageHandler implements IMessageHandler { }); }; - const handleHeartbeat = (client: IClient, message: IMessage) => heartbeatHandler(client, message); + const handleHeartbeat = (client: IClient | undefined, message: IMessage) => heartbeatHandler(client, message); this.messageHandlers.registerHandler(MessageType.HEARTBEAT, handleHeartbeat); this.messageHandlers.registerHandler(MessageType.OFFER, handleTransmission); @@ -36,7 +36,7 @@ export class MessageHandler implements IMessageHandler { this.messageHandlers.registerHandler(MessageType.EXPIRE, handleTransmission); } - public handle(client: IClient, message: IMessage): boolean { + public handle(client: IClient | undefined, message: IMessage): boolean { return this.messageHandlers.handle(client, message); } } diff --git a/src/messageHandler/messageHandlers.ts b/src/messageHandler/messageHandlers.ts index 2a48cb4..4aa82d9 100644 --- a/src/messageHandler/messageHandlers.ts +++ b/src/messageHandler/messageHandlers.ts @@ -5,24 +5,24 @@ import { Handler } from "./handler"; export interface IMessageHandlers { registerHandler(messageType: MessageType, handler: Handler): void; - handle(client: IClient, message: IMessage): boolean; + handle(client: IClient | undefined, message: IMessage): boolean; } export class MessageHandlers implements IMessageHandlers { private readonly handlers: Map = new Map(); public registerHandler(messageType: MessageType, handler: Handler): void { - if (this.handlers.has(messageType)) { return; } + if (this.handlers.has(messageType)) return; this.handlers.set(messageType, handler); } - public handle(client: IClient, message: IMessage): boolean { + public handle(client: IClient | undefined, message: IMessage): boolean { const { type } = message; const handler = this.handlers.get(type); - if (!handler) { return false; } + if (!handler) return false; return handler(client, message); } diff --git a/src/models/client.ts b/src/models/client.ts index cd991a9..4dee3ca 100644 --- a/src/models/client.ts +++ b/src/models/client.ts @@ -7,7 +7,7 @@ export interface IClient { getSocket(): MyWebSocket | null; - setSocket(socket: MyWebSocket): void; + setSocket(socket: MyWebSocket | null): void; getLastPing(): number; @@ -19,10 +19,10 @@ export interface IClient { export class Client implements IClient { private readonly id: string; private readonly token: string; - private socket: MyWebSocket = null; + private socket: MyWebSocket | null = null; private lastPing: number = new Date().getTime(); - constructor({ id, token }: { id: string, token: string }) { + constructor({ id, token }: { id: string, token: string; }) { this.id = id; this.token = token; } @@ -39,7 +39,7 @@ export class Client implements IClient { return this.socket; } - public setSocket(socket: MyWebSocket): void { + public setSocket(socket: MyWebSocket | null): void { this.socket = socket; } @@ -52,6 +52,6 @@ export class Client implements IClient { } public send(data: any): void { - this.socket.send(JSON.stringify(data)); + this.socket?.send(JSON.stringify(data)); } } diff --git a/src/models/messageQueue.ts b/src/models/messageQueue.ts index 4c0e2ce..1b5a94c 100644 --- a/src/models/messageQueue.ts +++ b/src/models/messageQueue.ts @@ -25,7 +25,7 @@ export class MessageQueue implements IMessageQueue { public readMessage(): IMessage | null { if (this.messages.length > 0) { this.lastReadAt = new Date().getTime(); - return this.messages.shift(); + return this.messages.shift()!; } return null; diff --git a/src/models/realm.ts b/src/models/realm.ts index 7b3ce19..cd4d0c9 100644 --- a/src/models/realm.ts +++ b/src/models/realm.ts @@ -46,7 +46,7 @@ export class Realm implements IRealm { public removeClientById(id: string): boolean { const client = this.getClientById(id); - if (!client) { return false; } + if (!client) return false; this.clients.delete(id); @@ -62,7 +62,7 @@ export class Realm implements IRealm { this.messageQueues.set(id, new MessageQueue()); } - this.getMessageQueueById(id).addMessage(message); + this.getMessageQueueById(id)!.addMessage(message); } public clearMessageQueue(id: string): void { diff --git a/src/services/checkBrokenConnections/index.ts b/src/services/checkBrokenConnections/index.ts index 06f600b..9ef3c4e 100644 --- a/src/services/checkBrokenConnections/index.ts +++ b/src/services/checkBrokenConnections/index.ts @@ -9,7 +9,7 @@ type CustomConfig = Pick; export class CheckBrokenConnections { public readonly checkInterval: number; - private timeoutId: NodeJS.Timeout; + private timeoutId: NodeJS.Timeout | null = null; private readonly realm: IRealm; private readonly config: CustomConfig; private readonly onClose?: (client: IClient) => void; @@ -18,7 +18,7 @@ export class CheckBrokenConnections { realm: IRealm, config: CustomConfig, checkInterval?: number, - onClose?: (client: IClient) => void + onClose?: (client: IClient) => void; }) { this.realm = realm; this.config = config; @@ -54,23 +54,20 @@ export class CheckBrokenConnections { const { alive_timeout: aliveTimeout } = this.config; for (const clientId of clientsIds) { - const client = this.realm.getClientById(clientId); + const client = this.realm.getClientById(clientId)!; const timeSinceLastPing = now - client.getLastPing(); - if (timeSinceLastPing < aliveTimeout) { continue; } + if (timeSinceLastPing < aliveTimeout) continue; try { - if (client.getSocket()) { - client.getSocket().close(); - } - } catch (e) { - // @ts-nocheck + client.getSocket()?.close(); } finally { this.realm.clearMessageQueue(clientId); this.realm.removeClientById(clientId); + client.setSocket(null); - if (this.onClose) { this.onClose(client); } + this.onClose?.(client); } } } diff --git a/src/services/messagesExpire/index.ts b/src/services/messagesExpire/index.ts index 4d8ebe7..9c3722b 100644 --- a/src/services/messagesExpire/index.ts +++ b/src/services/messagesExpire/index.ts @@ -13,7 +13,7 @@ export class MessagesExpire implements IMessagesExpire { private readonly config: IConfig; private readonly messageHandler: IMessageHandler; - private timeoutId: NodeJS.Timeout = null; + private timeoutId: NodeJS.Timeout | null = null; constructor({ realm, config, messageHandler }: { realm: IRealm; @@ -53,19 +53,19 @@ export class MessagesExpire implements IMessagesExpire { const now = new Date().getTime(); const maxDiff = this.config.expire_timeout; - const seen: { [id: string]: boolean } = {}; + const seen: Record = {}; for (const destinationClientId of destinationClientsIds) { - const messageQueue = this.realm.getMessageQueueById(destinationClientId); + const messageQueue = this.realm.getMessageQueueById(destinationClientId)!; const lastReadDiff = now - messageQueue.getLastReadAt(); - if (lastReadDiff < maxDiff) { continue; } + if (lastReadDiff < maxDiff) continue; const messages = messageQueue.getMessages(); for (const message of messages) { if (!seen[message.src]) { - this.messageHandler.handle(null, { + this.messageHandler.handle(undefined, { type: MessageType.EXPIRE, src: message.dst, dst: message.src diff --git a/src/services/webSocketServer/index.ts b/src/services/webSocketServer/index.ts index ae0ddf2..d345a31 100644 --- a/src/services/webSocketServer/index.ts +++ b/src/services/webSocketServer/index.ts @@ -25,7 +25,7 @@ export class WebSocketServer extends EventEmitter implements IWebSocketServer { private readonly config: IConfig; private readonly webSocketServer: WebSocketLib.Server; - constructor({ server, realm, config }: { server: any, realm: IRealm, config: IConfig }) { + constructor({ server, realm, config }: { server: any, realm: IRealm, config: IConfig; }) { super(); this.setMaxListeners(0); this.realm = realm; @@ -41,7 +41,7 @@ export class WebSocketServer extends EventEmitter implements IWebSocketServer { } private _onSocketConnection(socket: MyWebSocket, req: IncomingMessage): void { - const { query = {} } = url.parse(req.url, true); + const { query = {} } = url.parse(req.url!, true); const { id, token, key }: IAuthParams = query; diff --git a/tsconfig.json b/tsconfig.json index 65ed033..3c7af7a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ ], "target": "es2016", "module": "commonjs", + "strict": true, "esModuleInterop": true, "downlevelIteration": true, "moduleResolution": "node", @@ -16,6 +17,9 @@ "sourceMap": false, "outDir": "dist" }, + "include": [ + "./src/**/*", + ], "exclude": [ "test", "bin",