From 8632a3d0797a04f474a9b87cce657c0555fb7092 Mon Sep 17 00:00:00 2001 From: Sebastien Clement Date: Mon, 9 Nov 2020 12:42:26 +0100 Subject: [PATCH] :pencil2: Clean code with prettier --- .../rootfs/opt/nextcloud_backup/.eslintrc.js | 13 +- .../rootfs/opt/nextcloud_backup/app.js | 79 +- .../opt/nextcloud_backup/config/winston.js | 18 +- .../opt/nextcloud_backup/package-lock.json | 1406 ++++++++++++----- .../rootfs/opt/nextcloud_backup/package.json | 7 +- .../rootfs/opt/nextcloud_backup/routes/api.js | 215 ++- .../opt/nextcloud_backup/routes/index.js | 8 +- .../opt/nextcloud_backup/tools/cronTools.js | 98 +- .../nextcloud_backup/tools/hassioApiTools.js | 155 +- .../opt/nextcloud_backup/tools/pathTools.js | 7 +- .../nextcloud_backup/tools/settingsTools.js | 15 +- .../opt/nextcloud_backup/tools/status.js | 24 +- .../opt/nextcloud_backup/tools/toolbox.js | 22 +- .../opt/nextcloud_backup/tools/webdavTools.js | 496 +++--- 14 files changed, 1528 insertions(+), 1035 deletions(-) diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/.eslintrc.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/.eslintrc.js index 3e58bfa..32b4933 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/.eslintrc.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/.eslintrc.js @@ -2,19 +2,14 @@ module.exports = { "env": { "browser": true, "commonjs": true, - "es6": true, + "es2021": true, "node": true }, - "extends": "eslint:recommended", - "globals": { - "Atomics": "readonly", - "SharedArrayBuffer": "readonly" - }, + "extends": ["eslint:recommended","prettier"], "parserOptions": { - "ecmaVersion": 2018 + "ecmaVersion": 12 }, "rules": { "no-unused-vars": "warn" - } -}; \ No newline at end of file +}; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/app.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/app.js index 4b76b4a..9737c72 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/app.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/app.js @@ -1,30 +1,31 @@ -const createError = require('http-errors'); -const express = require('express'); -const path = require('path'); -const cookieParser = require('cookie-parser'); -const logger = require('morgan'); +const createError = require("http-errors"); +const express = require("express"); +const path = require("path"); +const cookieParser = require("cookie-parser"); +const logger = require("morgan"); - -const indexRouter = require('./routes/index'); -const apiRouter = require('./routes/api'); +const indexRouter = require("./routes/index"); +const apiRouter = require("./routes/api"); const app = express(); // view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'ejs'); +app.set("views", path.join(__dirname, "views")); +app.set("view engine", "ejs"); -app.use(logger('dev', { - skip: function (req, res) { - return res.statusCode = 304 - } -})); +app.use( + logger("dev", { + skip: function (req, res) { + return (res.statusCode = 304); + }, + }) +); app.use(express.json()); -app.use(express.urlencoded({extended: false})); +app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); +app.use(express.static(path.join(__dirname, "public"))); -app.use('/', indexRouter); -app.use('/api', apiRouter); +app.use("/", indexRouter); +app.use("/api", apiRouter); // catch 404 and forward to error handler app.use(function (req, res, next) { @@ -35,43 +36,43 @@ app.use(function (req, res, next) { app.use(function (err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; - res.locals.error = req.app.get('env') === 'development' ? err : {}; + res.locals.error = req.app.get("env") === "development" ? err : {}; // render the error page res.status(err.status || 500); - res.render('error'); + res.render("error"); }); -const fs = require('fs'); -const newlog = require('./config/winston'); -if (!fs.existsSync('/data')) - fs.mkdirSync('/data'); -const statusTools = require('./tools/status'); +const fs = require("fs"); +const newlog = require("./config/winston"); +if (!fs.existsSync("/data")) fs.mkdirSync("/data"); +const statusTools = require("./tools/status"); statusTools.init(); newlog.info("Satus : \x1b[32mGo !\x1b[0m"); -const hassioApiTools = require('./tools/hassioApiTools'); +const hassioApiTools = require("./tools/hassioApiTools"); hassioApiTools.getSnapshots().then( () => { - newlog.info("Hassio API : \x1b[32mGo !\x1b[0m") - - }, (err) => { - newlog.error("Hassio API : \x1b[31;1mFAIL !\x1b[0m") + newlog.info("Hassio API : \x1b[32mGo !\x1b[0m"); + }, + (err) => { + newlog.error("Hassio API : \x1b[31;1mFAIL !\x1b[0m"); newlog.error("... " + err); - }); + } +); -const WebdavTools = require('./tools/webdavTools'); +const WebdavTools = require("./tools/webdavTools"); const webdav = new WebdavTools().getInstance(); webdav.confIsValid().then( () => { - newlog.info("Nextcloud connection : \x1b[32mGo !\x1b[0m") - }, (err) => { - newlog.error("Nextcloud connection : \x1b[31;1mFAIL !\x1b[0m") + newlog.info("Nextcloud connection : \x1b[32mGo !\x1b[0m"); + }, + (err) => { + newlog.error("Nextcloud connection : \x1b[31;1mFAIL !\x1b[0m"); newlog.error("... " + err); } -) +); -const cronTools = require('./tools/cronTools'); +const cronTools = require("./tools/cronTools"); cronTools.startCron(); - module.exports = app; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/config/winston.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/config/winston.js index 424cffc..206e7b8 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/config/winston.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/config/winston.js @@ -1,18 +1,17 @@ -const appRoot = require('app-root-path'); -const winston = require('winston'); - +const appRoot = require("app-root-path"); +const winston = require("winston"); const logger = winston.createLogger({ - level: 'debug', + level: "debug", format: winston.format.combine( winston.format.timestamp({ - format: 'YYYY-MM-DD HH:mm:ss' + format: "YYYY-MM-DD HH:mm:ss", }), // winston.format.errors({ stack: true }), // winston.format.splat(), winston.format.colorize(), - winston.format.printf(({level, message, timestamp}) => { + winston.format.printf(({ level, message, timestamp }) => { return `[${timestamp}] [${level}]: ${message}`; }) ), @@ -21,10 +20,9 @@ const logger = winston.createLogger({ // - Write to all logs with level `info` and below to `quick-start-combined.log`. // - Write all logs error (and below) to `quick-start-error.log`. // - new winston.transports.Console({handleExceptions: true}), + new winston.transports.Console({ handleExceptions: true }), // new winston.transports.File({filename: '/data/NCB.log', handleExceptions: true}) - ] + ], }); - -module.exports = logger; \ No newline at end of file +module.exports = logger; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/package-lock.json b/nextcloud_backup/rootfs/opt/nextcloud_backup/package-lock.json index d5a49f0..d6e0c2a 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/package-lock.json +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/package-lock.json @@ -5,23 +5,77 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha1-vAeC9tafe31JUxIZaZuYj2aaj50=", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, "requires": { - "@babel/highlight": "^7.0.0" + "@babel/highlight": "^7.10.4" } }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha1-VtETEr2SSPphlZHQJHK+boyzJUA=", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { + "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@eslint/eslintrc": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.1.tgz", + "integrity": "sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "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 + } } }, "@sindresorhus/is": { @@ -53,6 +107,12 @@ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==" }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, "@types/keyv": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", @@ -84,48 +144,45 @@ } }, "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-jsx": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", - "integrity": "sha1-KUrbcbVzmLBoABXwo4xWPuHbU4Q=", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", "dev": true }, "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha1-086gTWsBeyiUrWkED+yLYj60vVI=", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, - "ansi-escapes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", - "integrity": "sha1-pM4rM9ayFLeVDYWVwhLxKsnMVp0=", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -139,7 +196,7 @@ "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "~1.0.2" @@ -150,10 +207,85 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "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.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha1-bIw/uCfdQ+45GPJ7gngqt2WKb9k=", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, "async": { @@ -246,44 +378,73 @@ "responselike": "^2.0.0" } }, + "call-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", + "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha1-s2MKvYlDQy9Us/BRkjjjPNffL3M=", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha1-kAlISfCTfy7twkJdDSip5fDLrZ4=", - "dev": true - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha1-JkMFp65JDR0Dvwybp8kl0XU68wc=", - "dev": true, - "requires": { - "restore-cursor": "^3.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=", - "dev": true - }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", @@ -355,6 +516,12 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -398,24 +565,14 @@ } }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q=", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=", - "dev": true - } + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "debug": { @@ -488,7 +645,7 @@ "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha1-rd6+rXKmV023g2OdyHoSF3OXOWE=", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -505,9 +662,9 @@ "integrity": "sha1-OjLGPRzRbREmbNRwOxT+xOdKtPY=" }, "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc=", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "enabled": { @@ -531,11 +688,37 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "env-variable": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.6.tgz", "integrity": "sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg==" }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + } + } + }, "es-abstract": { "version": "1.17.0-next.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0-next.1.tgz", @@ -576,22 +759,24 @@ "dev": true }, "eslint": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz", - "integrity": "sha1-wXcHykrXstivmGoz/rpx4Yqf7NE=", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.13.0.tgz", + "integrity": "sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.2.1", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.0", + "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", @@ -600,119 +785,265 @@ "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "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", + "levn": "^0.4.1", + "lodash": "^4.17.19", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha1-O3ImAlUQnGtYnO4FDx1RYTlmR5E=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true } } }, - "eslint-config-google": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", - "integrity": "sha1-T1+HWbpuEbQkKUohnb+hjFCLzBo=", + "eslint-config-eslint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-eslint/-/eslint-config-eslint-6.0.0.tgz", + "integrity": "sha512-dZ+eNtuU8V6+SbXgXjUf11/7Bv4EXzIqn4DxA3Ou1YklwFz31veKYTjzF9uYejUQQjOMpLHTEKWMGSmHAoh4wg==", "dev": true }, - "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha1-6HyIh8c+jR7ITxylkWRcNYv8j7k=", + "eslint-config-prettier": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", + "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "get-stdin": "^6.0.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.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": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha1-dP7HxU0Hdrb2fgJRBAtYBlZOmB8=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha1-4qgs6oT/JGrW+1f5veW0ZiFFnsI=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "espree": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", - "integrity": "sha1-bCcmUJMrT5HDcU5ee19eLs9HJi0=", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", "dev": true, "requires": { - "acorn": "^7.1.0", - "acorn-jsx": "^5.1.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" } }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=", + "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": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha1-OYrT88WiSUi+dyXoPRGn3ijNvR0=", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "etag": { @@ -757,38 +1088,16 @@ "vary": "~1.1.2" } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha1-ywP3QL764D6k0oPK7SdBqD8zVJU=", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, "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=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "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": { @@ -807,19 +1116,10 @@ "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" }, - "figures": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", - "integrity": "sha1-SxmN0H2NcVMGQoZK8tRd2eRZxOw=", - "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": "sha1-yg9u+m3T1WEzP7FFFQZcL6/fQ5w=", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", "dev": true, "requires": { "flat-cache": "^2.0.1" @@ -839,10 +1139,19 @@ "unpipe": "~1.0.0" } }, + "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" + } + }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha1-XSltbwS9pEpGMKMBQTvbwuwIXsA=", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", "dev": true, "requires": { "flatted": "^2.0.0", @@ -851,9 +1160,9 @@ } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha1-aeV8qo8OrLwoHS4stFjUb9tEngg=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, "follow-redirects": { @@ -911,6 +1220,23 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "get-intrinsic": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", + "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -922,7 +1248,7 @@ "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha1-FB8zuBp8JJLhJVlDB0gMRmeSeKY=", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -934,18 +1260,18 @@ } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha1-X0wdHnSNMM1zrSlEs1d6gbCB6MI=", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "globals": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", - "integrity": "sha1-HlZO5cTd7SqwmLD4jyRwKjxWvhM=", + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "requires": { "type-fest": "^0.8.1" @@ -969,6 +1295,12 @@ "responselike": "^2.0.0" } }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -988,6 +1320,12 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, "hot-patcher": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/hot-patcher/-/hot-patcher-0.5.0.tgz", @@ -1029,13 +1367,13 @@ "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha1-dQ49tYYgh7RzfrrIIH/9HvJ7Jfw=", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha1-Yz/2GFBueTr1rJG/SLcmd+FcvmY=", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", "dev": true, "requires": { "parent-module": "^1.0.0", @@ -1063,27 +1401,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "inquirer": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", - "integrity": "sha1-nisDLd532h2124BHWLj+o6lwUZo=", - "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" - } - }, "ipaddr.js": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", @@ -1104,6 +1421,15 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" }, + "is-core-module": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", @@ -1116,24 +1442,24 @@ "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": "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw=", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "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-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", "dev": true }, "is-regex": { @@ -1149,6 +1475,12 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -1171,13 +1503,13 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=", + "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", - "integrity": "sha1-r/FRswv9+o5J4F2iLnQV6d+jeEc=", + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -1192,7 +1524,7 @@ "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { @@ -1201,6 +1533,15 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, "keyv": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.1.tgz", @@ -1218,13 +1559,35 @@ } }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "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=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.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" } }, "lodash": { @@ -1294,12 +1657,6 @@ "mime-db": "1.42.0" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs=", - "dev": true - }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -1358,12 +1715,6 @@ "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": "sha1-FjDEKyJR/4HiooPelqVJfqkuXg0=", - "dev": true - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -1375,11 +1726,25 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs=" }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y=", - "dev": true + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } }, "normalize-url": { "version": "4.5.0", @@ -1416,6 +1781,18 @@ "es-abstract": "^1.17.0-next.1" } }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -1442,54 +1819,78 @@ "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha1-//DzyRYX/mK7UBiWNumayKbfe+U=", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha1-hPodA2/p08fiHZmIS2ARZ+yPtJU=", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, - "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-cancelable": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==" }, + "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 + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha1-aR0nCeeMefrjoVZiJFLQB2LKqqI=", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { "callsites": "^3.0.0" } }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ=" }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1497,9 +1898,15 @@ "dev": true }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, "path-posix": { @@ -1512,10 +1919,34 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "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=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "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" + } + }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "process-nextick-args": { @@ -1526,7 +1957,7 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha1-foz42PW48jnBvGi+tOt4Vn1XLvg=", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "proxy-addr": { @@ -1550,7 +1981,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, "qs": { @@ -1584,6 +2015,27 @@ "unpipe": "1.0.0" } }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "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" + } + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -1595,9 +2047,9 @@ } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha1-jRnTHPYySCtYkEn4KB+T28uk0H8=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, "requires-port": { @@ -1605,6 +2057,16 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, + "resolve": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", + "dev": true, + "requires": { + "is-core-module": "^2.0.0", + "path-parse": "^1.0.6" + } + }, "resolve-alpn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", @@ -1613,7 +2075,7 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "responselike": { @@ -1624,43 +2086,15 @@ "lowercase-keys": "^2.0.0" } }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha1-OfZ8VLOnpYzqUjbZXPADQjljH34=", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha1-stEE/g2Psnz54KHNqCYt04M8bKs=", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "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" - } - }, - "rxjs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", - "integrity": "sha1-UQ4mMX9NuRp+sd532d2boKSJmjo=", - "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", @@ -1679,7 +2113,7 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0=", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, "send": { @@ -1719,24 +2153,18 @@ "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=" }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "simple-swizzle": { @@ -1750,22 +2178,46 @@ "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha1-ys12k0YaY3pXiNkqfdT7oGjoFjY=", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, "requires": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } } }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", + "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", + "dev": true + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -1783,23 +2235,94 @@ "integrity": "sha1-u3PURtonlhBu/MG2AaJT1sRr0Ic=" }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha1-lSGCxGzHssMT0VluYjmSvRY7crU=", + "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": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-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 + }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha1-CxVx3XZpzNTz4G4U7x7tJiJa5TI=", + "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": "^5.0.0" + "ansi-regex": "^4.1.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz", + "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" } } } @@ -1822,6 +2345,71 @@ "function-bind": "^1.1.1" } }, + "string.prototype.trimstart": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz", + "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "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.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "is-callable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "dev": true + }, + "is-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", + "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -1838,32 +2426,30 @@ } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=", + "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": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=", - "dev": true - } + "ansi-regex": "^5.0.0" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha1-hXE5dakfuHvxswXMp3OV5A0qZKc=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -1872,38 +2458,13 @@ "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha1-EpLRlQDOP4YFOwXw6Ofko7shB54=", + "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": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha1-InZ74htirxCBV0MG9prFG2IgOWE=", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } } }, "text-hex": { @@ -1917,45 +2478,36 @@ "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": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "triple-beam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha1-w8GflZc/sKYpc/sJ2Q2WHuQ+XIo=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" } }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha1-CeJJ696FHTseSNJ8EFREZn8XuD0=", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, "type-is": { @@ -1973,9 +2525,9 @@ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -2020,11 +2572,21 @@ "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" }, "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha1-4U3jezGm0ZT1aQ1n78Tn9vxqsw4=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "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", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -2047,9 +2609,9 @@ } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -2107,7 +2669,7 @@ "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha1-YQY29rH3A4kb00dxzLF/uTtHB5w=", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "wrappy": { @@ -2118,7 +2680,7 @@ "write": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha1-CADhRSO5I6OH5BUSPIZWFqrg9cM=", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", "dev": true, "requires": { "mkdirp": "^0.5.1" diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/package.json b/nextcloud_backup/rootfs/opt/nextcloud_backup/package.json index 8cdf90b..a824710 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/package.json +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/package.json @@ -22,7 +22,10 @@ "winston": "^3.2.1" }, "devDependencies": { - "eslint": "^6.7.2", - "eslint-config-google": "^0.14.0" + "eslint": "^7.13.0", + "eslint-config-eslint": "^6.0.0", + "eslint-config-prettier": "^6.15.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-node": "^11.1.0" } } diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js index 05e012d..1ba43c0 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/api.js @@ -1,122 +1,106 @@ -const express = require('express'); +const express = require("express"); const router = express.Router(); -const moment = require('moment'); -const statusTools = require('../tools/status'); -const WebdavTools = require('../tools/webdavTools') +const moment = require("moment"); +const statusTools = require("../tools/status"); +const WebdavTools = require("../tools/webdavTools"); const webdav = new WebdavTools().getInstance(); -const settingsTools = require('../tools/settingsTools'); -const pathTools = require('../tools/pathTools'); -const hassioApiTools = require('../tools/hassioApiTools'); -const humanFileSize = require('../tools/toolbox').humanFileSize; +const settingsTools = require("../tools/settingsTools"); +const pathTools = require("../tools/pathTools"); +const hassioApiTools = require("../tools/hassioApiTools"); +const humanFileSize = require("../tools/toolbox").humanFileSize; -const cronTools = require('../tools/cronTools'); +const cronTools = require("../tools/cronTools"); -const logger = require('../config/winston'); +const logger = require("../config/winston"); - - - - -router.get('/status', (req, res, next) => { +router.get("/status", (req, res, next) => { cronTools.updatetNextDate(); let status = statusTools.getStatus(); res.json(status); }); - - - - -router.get('/formated-local-snap', function(req, res, next) { +router.get("/formated-local-snap", function (req, res, next) { hassioApiTools.getSnapshots().then( (snaps) => { snaps.sort((a, b) => { - if (moment(a.date).isBefore(moment(b.date))){ + if (moment(a.date).isBefore(moment(b.date))) { return 1; - } - else - { + } else { return -1; } - - }) - res.render('localSnaps', { snaps: snaps, moment: moment }); + }); + res.render("localSnaps", { snaps: snaps, moment: moment }); }, (err) => { logger.error(err); res.status(500); - res.send(''); + res.send(""); + } + ); +}); + +router.get("/formated-backup-manual", function (req, res, next) { + webdav + .getFolderContent(webdav.getConf().back_dir + pathTools.manual) + .then((contents) => { + contents.sort((a, b) => { + if (moment(a.lastmod).isBefore(moment(b.lastmod))) return 1; + else return -1; + }); + res.render("backupSnaps", { backups: contents, moment: moment, humanFileSize: humanFileSize }); }) - -}); - -router.get('/formated-backup-manual', function(req, res, next) { - webdav.getFolderContent( webdav.getConf().back_dir + pathTools.manual) - .then((contents) => { - contents.sort((a, b) => { - if (moment(a.lastmod).isBefore(moment(b.lastmod))) - return 1; - else - return -1; - }) - res.render('backupSnaps',{backups: contents, moment: moment, humanFileSize: humanFileSize}); - }).catch(()=>{ - res.send(); - }); - -}); - -router.get('/formated-backup-auto', function(req, res, next) { - let url = webdav.getConf().back_dir + pathTools.auto - webdav.getFolderContent( url ) - .then((contents) => { - contents.sort((a, b) => { - if (moment(a.lastmod).isBefore(moment(b.lastmod))) - return 1; - else - return -1; - }) - res.render('backupSnaps',{backups: contents, moment: moment, humanFileSize: humanFileSize}); - }).catch(()=>{ + .catch(() => { res.send(); }); }); +router.get("/formated-backup-auto", function (req, res, next) { + let url = webdav.getConf().back_dir + pathTools.auto; + webdav + .getFolderContent(url) + .then((contents) => { + contents.sort((a, b) => { + if (moment(a.lastmod).isBefore(moment(b.lastmod))) return 1; + else return -1; + }); + res.render("backupSnaps", { backups: contents, moment: moment, humanFileSize: humanFileSize }); + }) + .catch(() => { + res.send(); + }); +}); - -router.post('/nextcloud-settings', function(req, res, next) { +router.post("/nextcloud-settings", function (req, res, next) { let settings = req.body; if (settings.ssl != null && settings.host != null && settings.host != "" && settings.username != null && settings.password != null) { webdav.setConf(settings); - webdav.confIsValid().then(() => { - res.status(201); - res.send(); - }).catch((err) => { - res.status(406); - res.json({ message: err }); - }); - - } - else { + webdav + .confIsValid() + .then(() => { + res.status(201); + res.send(); + }) + .catch((err) => { + res.status(406); + res.json({ message: err }); + }); + } else { res.status(400); res.send(); } }); -router.get('/nextcloud-settings', function(req, res, next) { +router.get("/nextcloud-settings", function (req, res, next) { let conf = webdav.getConf(); if (conf == null) { res.status(404); res.send(); - } - else { + } else { res.json(conf); } }); - - -router.post('/manual-backup', function(req, res, next) { +router.post("/manual-backup", function (req, res, next) { let id = req.query.id; let name = req.query.name; let status = statusTools.getStatus(); @@ -126,84 +110,81 @@ router.post('/manual-backup', function(req, res, next) { return; } - hassioApiTools.downloadSnapshot(id) + hassioApiTools + .downloadSnapshot(id) .then(() => { - webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.manual + name + '.tar'); + webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.manual + name + ".tar"); res.status(201); res.send(); }) .catch(() => { - res.status(500) + res.status(500); res.send(); - }) - + }); }); -router.post('/new-backup', function(req, res, next) { - +router.post("/new-backup", function (req, res, next) { let status = statusTools.getStatus(); if (status.status === "creating" && status.status === "upload" && status.status === "download") { res.status(503); res.send(); return; } - let name = 'Manual-' + moment().format('YYYY-MM-DD_HH-mm'); - hassioApiTools.createNewBackup(name).then((id) => { - hassioApiTools.downloadSnapshot(id) - .then(() => { - webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.manual + name + '.tar'); - }).catch(() => { - - }) - }).catch(() => { - - }) + let name = "Manual-" + moment().format("YYYY-MM-DD_HH-mm"); + hassioApiTools + .createNewBackup(name) + .then((id) => { + hassioApiTools + .downloadSnapshot(id) + .then(() => { + webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.manual + name + ".tar"); + }) + .catch(() => {}); + }) + .catch(() => {}); res.status(201); res.send(); }); - -router.get('/backup-settings', function(req, res, next) { +router.get("/backup-settings", function (req, res, next) { res.send(settingsTools.getSettings()); }); -router.post('/backup-settings', function(req, res, next) { +router.post("/backup-settings", function (req, res, next) { if (cronTools.checkConfig(req.body)) { settingsTools.setSettings(req.body); cronTools.startCron(); res.send(); - } - else { + } else { res.status(400); res.send(); } }); -router.post('/clean-now', function(req, res, next){ - webdav.clean().then(()=>{ - hassioApiTools.clean().catch(); - }).catch(()=>{ - hassioApiTools.clean().catch(); - }); +router.post("/clean-now", function (req, res, next) { + webdav + .clean() + .then(() => { + hassioApiTools.clean().catch(); + }) + .catch(() => { + hassioApiTools.clean().catch(); + }); res.status(201); - res.send() + res.send(); }); - -router.post('/restore', function(req, res, next){ - if(req.body['path'] != null){ - webdav.downloadFile(req.body['path'] ).then((path)=>{ +router.post("/restore", function (req, res, next) { + if (req.body["path"] != null) { + webdav.downloadFile(req.body["path"]).then((path) => { hassioApiTools.uploadSnapshot(path); }); res.status(200); - res.send() - } - else{ + res.send(); + } else { res.status(400); - res.send() + res.send(); } }); - - module.exports = router; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/index.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/index.js index 6135607..f680d97 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/index.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/routes/index.js @@ -1,11 +1,9 @@ -const express = require('express'); +const express = require("express"); const router = express.Router(); - /* GET home page. */ -router.get('/', function(req, res, next) { - res.render('index'); +router.get("/", function (req, res, next) { + res.render("index"); }); - module.exports = router; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js index 1f98f5d..13ba178 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/cronTools.js @@ -1,43 +1,36 @@ -const settingsTools = require('./settingsTools'); +const settingsTools = require("./settingsTools"); -const WebdavTools = require('./webdavTools'); +const WebdavTools = require("./webdavTools"); const webdav = new WebdavTools().getInstance(); -const hassioApiTools = require('./hassioApiTools'); +const hassioApiTools = require("./hassioApiTools"); -const statusTools = require('./status'); +const statusTools = require("./status"); -const pathTools = require('./pathTools'); - -const CronJob = require('cron').CronJob; -const moment = require('moment'); -const logger = require('../config/winston'); +const pathTools = require("./pathTools"); +const CronJob = require("cron").CronJob; +const moment = require("moment"); +const logger = require("../config/winston"); function checkConfig(conf) { if (conf.cron_base != null) { - if (conf.cron_base === '1' || conf.cron_base === '2' || conf.cron_base === '3') { + if (conf.cron_base === "1" || conf.cron_base === "2" || conf.cron_base === "3") { if (conf.cron_hour != null && conf.cron_hour.match(/\d\d:\d\d/)) { - if (conf.cron_base === '1') - return true; - } - else - return false; + if (conf.cron_base === "1") return true; + } else return false; } - if (conf.cron_base === '2') { + if (conf.cron_base === "2") { return conf.cron_weekday != null && conf.cron_weekday >= 0 && conf.cron_weekday <= 6; } - if (conf.cron_base === '3') { + if (conf.cron_base === "3") { return conf.cron_month_day != null && conf.cron_month_day >= 1 && conf.cron_month_day <= 28; } - if (conf.cron_base === '0') - return true - } - else - return false; + if (conf.cron_base === "0") return true; + } else return false; return false; } @@ -52,19 +45,18 @@ function updatetNextDate() { cronContainer.updatetNextDate(); } - class CronContainer { constructor() { this.cronJob = null; - this.cronClean = null + this.cronClean = null; } init() { let settings = settingsTools.getSettings(); let cronStr = ""; if (this.cronClean == null) { - logger.info("Starting auto clean cron..."); - this.cronClean = new CronJob('0 1 * * *', this._clean, null, false, Intl.DateTimeFormat().resolvedOptions().timeZone); + logger.info("Starting auto clean cron..."); + this.cronClean = new CronJob("0 1 * * *", this._clean, null, false, Intl.DateTimeFormat().resolvedOptions().timeZone); this.cronClean.start(); } if (this.cronJob != null) { @@ -78,28 +70,26 @@ class CronContainer { } switch (settings.cron_base) { - case '0': + case "0": logger.warn("No Cron settings available."); return; - case '1': { - let splited = settings.cron_hour.split(':'); + case "1": { + let splited = settings.cron_hour.split(":"); cronStr = "" + splited[1] + " " + splited[0] + " * * *"; break; } - case '2': { - let splited = settings.cron_hour.split(':'); + case "2": { + let splited = settings.cron_hour.split(":"); cronStr = "" + splited[1] + " " + splited[0] + " * * " + settings.cron_weekday; break; } - case '3': { - let splited = settings.cron_hour.split(':'); + case "3": { + let splited = settings.cron_hour.split(":"); cronStr = "" + splited[1] + " " + splited[0] + " " + settings.cron_month_day + " * *"; break; } - - } logger.info("Starting Cron..."); this.cronJob = new CronJob(cronStr, this._createBackup, null, false, Intl.DateTimeFormat().resolvedOptions().timeZone); @@ -109,32 +99,30 @@ class CronContainer { updatetNextDate() { let date; - if (this.cronJob == null) - date = "Not configured"; - else - date = this.cronJob.nextDate().format('MMM D, YYYY HH:mm'); + if (this.cronJob == null) date = "Not configured"; + else date = this.cronJob.nextDate().format("MMM D, YYYY HH:mm"); let status = statusTools.getStatus(); status.next_backup = date; statusTools.setStatus(status); } _createBackup() { - logger.debug('Cron triggered !'); + logger.debug("Cron triggered !"); let status = statusTools.getStatus(); - if (status.status === "creating" || status.status === "upload" || status.status === "download") - return; + if (status.status === "creating" || status.status === "upload" || status.status === "download") return; - let name = 'Auto-' + moment().format('YYYY-MM-DD_HH-mm'); - hassioApiTools.createNewBackup(name).then((id) => { - hassioApiTools.downloadSnapshot(id) - .then(() => { - webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.auto + name + '.tar'); - }).catch(() => { - - }) - }).catch(() => { - - }) + let name = "Auto-" + moment().format("YYYY-MM-DD_HH-mm"); + hassioApiTools + .createNewBackup(name) + .then((id) => { + hassioApiTools + .downloadSnapshot(id) + .then(() => { + webdav.uploadFile(id, webdav.getConf().back_dir + pathTools.auto + name + ".tar"); + }) + .catch(() => {}); + }) + .catch(() => {}); } _clean() { @@ -146,11 +134,9 @@ class CronContainer { if (autoCleanCloud != null && autoCleanCloud === "true") { webdav.clean().catch(() => {}); } - } } - class Singleton { constructor() { if (!Singleton.instance) { @@ -165,4 +151,4 @@ class Singleton { exports.checkConfig = checkConfig; exports.startCron = startCron; -exports.updatetNextDate = updatetNextDate; \ No newline at end of file +exports.updatetNextDate = updatetNextDate; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/hassioApiTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/hassioApiTools.js index aade5f0..3e2d40a 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/hassioApiTools.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/hassioApiTools.js @@ -1,25 +1,25 @@ -const statusTools = require('./status'); -const fs = require('fs'); -const settingsTools = require('./settingsTools'); -const moment = require('moment'); -const logger = require('../config/winston'); -const stream = require('stream'); -const {promisify} = require('util'); +const fs = require("fs"); + +const moment = require("moment"); +const stream = require("stream"); +const { promisify } = require("util"); + const pipeline = promisify(stream.pipeline); -const got = require ('got'); -const FormData = require('form-data'); - -const create_snap_timeout = 90 * 60 * 1000 - +const got = require("got"); +const FormData = require("form-data"); +const statusTools = require("./status"); +const settingsTools = require("./settingsTools"); +const logger = require("../config/winston"); +const create_snap_timeout = 90 * 60 * 1000; function getSnapshots() { return new Promise((resolve, reject) => { let token = process.env.HASSIO_TOKEN; let status = statusTools.getStatus(); let option = { - headers: { 'X-HASSIO-KEY': token }, - responseType: 'json' + headers: { "X-HASSIO-KEY": token }, + responseType: "json", }; got("http://hassio/snapshots", option) @@ -42,41 +42,43 @@ function getSnapshots() { reject(error.message); }); }); - } function downloadSnapshot(id) { return new Promise((resolve, reject) => { logger.info(`Downloading snapshot ${id}...`); - if (!fs.existsSync('./temp/')) - fs.mkdirSync('./temp/'); - let tmp_file = `./temp/${id}.tar` + if (!fs.existsSync("./temp/")) fs.mkdirSync("./temp/"); + let tmp_file = `./temp/${id}.tar`; let stream = fs.createWriteStream(tmp_file); let token = process.env.HASSIO_TOKEN; let status = statusTools.getStatus(); - checkSnap(id).then(() => { + checkSnap(id) + .then(() => { status.status = "download"; status.progress = 0; statusTools.setStatus(status); let option = { - headers: { 'X-HASSIO-KEY': token }, + headers: { "X-HASSIO-KEY": token }, }; - pipeline(got.stream.get(`http://hassio/snapshots/${id}/download`, option) - .on('downloadProgress', e => { + pipeline( + got.stream.get(`http://hassio/snapshots/${id}/download`, option).on("downloadProgress", (e) => { let percent = Math.round(e.percent * 100) / 100; if (status.progress != percent) { status.progress = percent; statusTools.setStatus(status); } - }), stream) - .then((res)=>{ - logger.info('Download success !') + }), + stream + ) + .then((res) => { + logger.info("Download success !"); status.progress = 1; statusTools.setStatus(status); - logger.debug("Snapshot dl size : " + (fs.statSync(tmp_file).size / 1024 / 1024)); + logger.debug("Snapshot dl size : " + fs.statSync(tmp_file).size / 1024 / 1024); resolve(); - }).catch((err)=>{ + }) + .catch((err) => { fs.unlinkSync(tmp_file); status.status = "error"; status.message = "Fail to download Hassio snapshot (" + err.message + ")"; @@ -84,8 +86,9 @@ function downloadSnapshot(id) { statusTools.setStatus(status); logger.error(status.message); reject(err.message); - }) - }).catch((err) => { + }); + }) + .catch((err) => { status.status = "error"; status.message = "Fail to download Hassio snapshot. Not found ?"; status.error_code = 7; @@ -93,18 +96,18 @@ function downloadSnapshot(id) { logger.error(status.message); reject(); }); - }); } function dellSnap(id) { return new Promise((resolve, reject) => { - checkSnap(id).then(() => { + checkSnap(id) + .then(() => { let token = process.env.HASSIO_TOKEN; let option = { - headers: { 'X-HASSIO-KEY': token }, - responseType: 'json' + headers: { "X-HASSIO-KEY": token }, + responseType: "json", }; got.post(`http://hassio/snapshots/${id}/remove`, option) @@ -114,48 +117,45 @@ function dellSnap(id) { .catch((error) => { reject(); }); - }).catch(() => { - reject(); }) - }) - + .catch(() => { + reject(); + }); + }); } function checkSnap(id) { return new Promise((resolve, reject) => { let token = process.env.HASSIO_TOKEN; let option = { - headers: { 'X-HASSIO-KEY': token }, - responseType: 'json' + headers: { "X-HASSIO-KEY": token }, + responseType: "json", }; got(`http://hassio/snapshots/${id}/info`, option) .then((result) => { - logger.debug(`Snapshot size: ${result.body.data.size}`) + logger.debug(`Snapshot size: ${result.body.data.size}`); resolve(); }) .catch((error) => { reject(); }); }); - } - function createNewBackup(name) { return new Promise((resolve, reject) => { let status = statusTools.getStatus(); status.status = "creating"; status.progress = -1; statusTools.setStatus(status); - logger.info("Creating new snapshot...") + logger.info("Creating new snapshot..."); let token = process.env.HASSIO_TOKEN; let option = { - headers: { 'X-HASSIO-KEY': token }, - responseType: 'json', + headers: { "X-HASSIO-KEY": token }, + responseType: "json", timeout: create_snap_timeout, - json: { name: name } - + json: { name: name }, }; got.post(`http://hassio/snapshots/new/full`, option) @@ -171,75 +171,71 @@ function createNewBackup(name) { logger.error(status.message); reject(status.message); }); - - - }); } function clean() { let limit = settingsTools.getSettings().auto_clean_local_keep; - if (limit == null) - limit = 5; + if (limit == null) limit = 5; return new Promise((resolve, reject) => { - getSnapshots().then(async (snaps) => { + getSnapshots() + .then(async (snaps) => { if (snaps.length < limit) { resolve(); return; } snaps.sort((a, b) => { - if (moment(a.date).isBefore(moment(b.date))) - return 1; - else - return -1; + if (moment(a.date).isBefore(moment(b.date))) return 1; + else return -1; }); let toDel = snaps.slice(limit); for (let i in toDel) { - await dellSnap(toDel[i].slug) + await dellSnap(toDel[i].slug); } - logger.info('Local clean done.') + logger.info("Local clean done."); resolve(); - }).catch(() => { + }) + .catch(() => { reject(); }); - }) + }); } - - function uploadSnapshot(path) { - return new Promise( (resolve, reject) => { + return new Promise((resolve, reject) => { let status = statusTools.getStatus(); status.status = "upload-b"; status.progress = 0; status.message = null; status.error_code = null; statusTools.setStatus(status); - logger.info('Uploading backup...'); - let stream = fs.createReadStream(path); + logger.info("Uploading backup..."); + let stream = fs.createReadStream(path); let token = process.env.HASSIO_TOKEN; - + let form = new FormData(); - form.append('file', stream) - + form.append("file", stream); + let options = { body: form, username: this.username, password: this.password, - headers: { 'X-HASSIO-KEY': token }, - } + headers: { "X-HASSIO-KEY": token }, + }; - got.stream.post(`http://hassio/snapshots/new/upload`, options).on('uploadProgress', e => { + got.stream + .post(`http://hassio/snapshots/new/upload`, options) + .on("uploadProgress", (e) => { let percent = e.percent; if (status.progress != percent) { status.progress = percent; statusTools.setStatus(status); } if (percent >= 1) { - logger.info('Upload done...'); + logger.info("Upload done..."); } - }).on('response', res => { - + }) + .on("response", (res) => { if (res.statusCode != 200) { status.status = "error"; status.error_code = 4; @@ -258,8 +254,8 @@ function uploadSnapshot(path) { fs.unlinkSync(path); resolve(); } - }).on('error', err => { - + }) + .on("error", (err) => { fs.unlinkSync(path); status.status = "error"; status.error_code = 4; @@ -268,14 +264,11 @@ function uploadSnapshot(path) { logger.error(status.message); reject(status.message); }); - }); } - - exports.getSnapshots = getSnapshots; exports.downloadSnapshot = downloadSnapshot; exports.createNewBackup = createNewBackup; exports.uploadSnapshot = uploadSnapshot; -exports.clean = clean; \ No newline at end of file +exports.clean = clean; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/pathTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/pathTools.js index 0cc1c3d..7e227a9 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/pathTools.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/pathTools.js @@ -1,5 +1,4 @@ - -let default_root = '/Hassio Backup/'; + let default_root = "/Hassio Backup/"; exports.default_root = default_root; -exports.manual = 'Manual/'; -exports.auto = 'Auto/'; \ No newline at end of file +exports.manual = "Manual/"; +exports.auto = "Auto/"; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/settingsTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/settingsTools.js index 88c48f0..134ab9b 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/settingsTools.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/settingsTools.js @@ -1,26 +1,19 @@ -const fs = require('fs'); +const fs = require("fs"); const settingsPath = "/data/backup_conf.json"; - -function getSettings(){ - +function getSettings() { if (!fs.existsSync(settingsPath)) { return {}; - } - else{ + } else { let rawSettings = fs.readFileSync(settingsPath); return JSON.parse(rawSettings); } } - -function setSettings(settings){ +function setSettings(settings) { fs.writeFileSync(settingsPath, JSON.stringify(settings)); } - exports.getSettings = getSettings; exports.setSettings = setSettings; - - diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/status.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/status.js index 301501d..83ba0cd 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/status.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/status.js @@ -1,31 +1,27 @@ -const fs = require('fs'); +const fs = require("fs"); -const statusPath = '/data/status.json'; +const statusPath = "/data/status.json"; let baseStatus = { status: "idle", last_backup: null, - next_backup: null + next_backup: null, }; - - function init() { if (!fs.existsSync(statusPath)) { fs.writeFileSync(statusPath, JSON.stringify(baseStatus)); - } - else{ + } else { let content = getStatus(); - if(content.status !== "idle"){ + if (content.status !== "idle") { content.status = "idle"; content.message = null; - setStatus(content) + setStatus(content); } } } - -function getStatus(){ +function getStatus() { if (!fs.existsSync(statusPath)) { fs.writeFileSync(statusPath, JSON.stringify(baseStatus)); } @@ -34,12 +30,10 @@ function getStatus(){ return JSON.parse(content); } -function setStatus(state){ +function setStatus(state) { fs.writeFileSync(statusPath, JSON.stringify(state)); } - - exports.init = init; exports.getStatus = getStatus; -exports.setStatus = setStatus; \ No newline at end of file +exports.setStatus = setStatus; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/toolbox.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/toolbox.js index 8ee7eb0..e9001ef 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/toolbox.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/toolbox.js @@ -1,23 +1,21 @@ - // Found on Stackoverflow, perfect code :D https://stackoverflow.com/a/14919494/8654475 -function humanFileSize(bytes, si=false, dp=1) { +function humanFileSize(bytes, si = false, dp = 1) { const thresh = si ? 1000 : 1024; - + if (Math.abs(bytes) < thresh) { - return bytes + ' B'; + return bytes + " B"; } - - const units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; + + const units = si ? ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] : ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]; let u = -1; - const r = 10**dp; - + const r = 10 ** dp; + do { bytes /= thresh; ++u; } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1); - - - return bytes.toFixed(dp) + ' ' + units[u]; + + return bytes.toFixed(dp) + " " + units[u]; } -exports.humanFileSize = humanFileSize \ No newline at end of file +exports.humanFileSize = humanFileSize; diff --git a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js index b0655ce..c787922 100644 --- a/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js +++ b/nextcloud_backup/rootfs/opt/nextcloud_backup/tools/webdavTools.js @@ -1,20 +1,20 @@ const { createClient } = require("webdav"); const fs = require("fs"); -const moment = require('moment'); -const https = require('https') +const moment = require("moment"); +const https = require("https"); -const statusTools = require('./status'); +const statusTools = require("./status"); const endpoint = "/remote.php/webdav"; const configPath = "/data/webdav_conf.json"; -const path = require('path'); -const settingsTools = require('./settingsTools'); -const pathTools = require('./pathTools'); -const hassioApiTools = require('./hassioApiTools'); -const logger = require('../config/winston'); +const path = require("path"); +const settingsTools = require("./settingsTools"); +const pathTools = require("./pathTools"); +const hassioApiTools = require("./hassioApiTools"); +const logger = require("../config/winston"); -const got = require ('got'); -const stream = require('stream'); -const {promisify} = require('util'); +const got = require("got"); +const stream = require("stream"); +const { promisify } = require("util"); const pipeline = promisify(stream.pipeline); class WebdavTools { @@ -24,7 +24,7 @@ class WebdavTools { this.username = null; this.password = null; } - + init(ssl, host, username, password, accept_selfsigned_cert) { return new Promise((resolve, reject) => { let status = statusTools.getStatus(); @@ -32,78 +32,85 @@ class WebdavTools { this.baseUrl = (ssl === "true" ? "https" : "http") + "://" + host + endpoint; this.username = username; this.password = password; - let agent_option = ssl === "true" ? { rejectUnauthorized: accept_selfsigned_cert === "false" } : {} + let agent_option = ssl === "true" ? { rejectUnauthorized: accept_selfsigned_cert === "false" } : {}; try { - this.client = createClient(this.baseUrl, { username: username, password: password, httpsAgent: new https.Agent(agent_option) }) ; - - this.client.getDirectoryContents("/").then(() => { - if (status.error_code == 3) { - status.status = "idle"; - status.message = null; - status.error_code = null; + this.client = createClient(this.baseUrl, { username: username, password: password, httpsAgent: new https.Agent(agent_option) }); + + this.client + .getDirectoryContents("/") + .then(() => { + if (status.error_code == 3) { + status.status = "idle"; + status.message = null; + status.error_code = null; + statusTools.setStatus(status); + } + logger.debug("Nextcloud connection: \x1b[32mSuccess !\x1b[0m"); + this.initFolder().then(() => { + resolve(); + }); + }) + .catch((error) => { + status.status = "error"; + status.error_code = 3; + status.message = "Can't connect to Nextcloud (" + error + ") !"; statusTools.setStatus(status); - } - logger.debug("Nextcloud connection: \x1b[32mSuccess !\x1b[0m"); - this.initFolder().then(() => { - resolve(); + this.client = null; + logger.error("Can't connect to Nextcloud (" + error + ") !"); + reject("Can't connect to Nextcloud (" + error + ") !"); }); - - }).catch((error) => { - status.status = "error"; - status.error_code = 3; - status.message = "Can't connect to Nextcloud (" + error + ") !" - statusTools.setStatus(status); - this.client = null; - logger.error("Can't connect to Nextcloud (" + error + ") !"); - reject("Can't connect to Nextcloud (" + error + ") !"); - }); } catch (err) { status.status = "error"; status.error_code = 3; - status.message = "Can't connect to Nextcloud (" + err + ") !" + status.message = "Can't connect to Nextcloud (" + err + ") !"; statusTools.setStatus(status); this.client = null; logger.error("Can't connect to Nextcloud (" + err + ") !"); reject("Can't connect to Nextcloud (" + err + ") !"); } - }); } - async __createRoot(){ - let root_splited = this.getConf().back_dir.split('/').splice(1) - let path = '/' - for(let elem of root_splited){ - if(elem != ''){ - path = path + elem + '/' + async __createRoot() { + let root_splited = this.getConf().back_dir.split("/").splice(1); + let path = "/"; + for (let elem of root_splited) { + if (elem != "") { + path = path + elem + "/"; try { - await this.client.createDirectory(path) - logger.debug(`Path ${path} created.`) + await this.client.createDirectory(path); + logger.debug(`Path ${path} created.`); } catch (error) { - if(error.response.status == 405) - logger.debug(`Path ${path} already exist.`) - else - logger.error(error) + if (error.response.status == 405) logger.debug(`Path ${path} already exist.`); + else logger.error(error); } } - } } - + initFolder() { return new Promise((resolve) => { - this.__createRoot().catch((err) => { logger.error(err)}).then(() => { - this.client.createDirectory(this.getConf().back_dir + pathTools.auto).catch(() => { }).then(() => { - this.client.createDirectory(this.getConf().back_dir + pathTools.manual).catch(() => { }).then(() => { - resolve(); - }) + this.__createRoot() + .catch((err) => { + logger.error(err); }) - }); + .then(() => { + this.client + .createDirectory(this.getConf().back_dir + pathTools.auto) + .catch(() => {}) + .then(() => { + this.client + .createDirectory(this.getConf().back_dir + pathTools.manual) + .catch(() => {}) + .then(() => { + resolve(); + }); + }); + }); }); - } /** - * Check if theh webdav config is valid, if yes, start init of webdav client - */ + * Check if theh webdav config is valid, if yes, start init of webdav client + */ confIsValid() { return new Promise((resolve, reject) => { let status = statusTools.getStatus(); @@ -117,309 +124,294 @@ class WebdavTools { statusTools.setStatus(status); } // Check if self_signed option exist - if( conf.self_signed == null || conf.self_signed == ''){ + if (conf.self_signed == null || conf.self_signed == "") { conf.self_signed = "false"; this.setConf(conf); } - this.init(conf.ssl, conf.host, conf.username, conf.password, conf.self_signed).then(() => { - resolve(); - }).catch((err) => { - reject(err); - }); - - } - else { + this.init(conf.ssl, conf.host, conf.username, conf.password, conf.self_signed) + .then(() => { + resolve(); + }) + .catch((err) => { + reject(err); + }); + } else { status.status = "error"; status.error_code = 2; - status.message = "Nextcloud config invalid !" + status.message = "Nextcloud config invalid !"; statusTools.setStatus(status); logger.error(status.message); reject("Nextcloud config invalid !"); } - - if(conf.back_dir == null || conf.back_dir == ''){ - logger.info('Backup dir is null, initializing it.'); + + if (conf.back_dir == null || conf.back_dir == "") { + logger.info("Backup dir is null, initializing it."); conf.back_dir = pathTools.default_root; this.setConf(conf); - } - else{ - if(!conf.back_dir.startsWith('/')){ - logger.warn('Backup dir not starting with \'/\', fixing this...'); - conf.back_dir=`/${conf.back_dir}`; + } else { + if (!conf.back_dir.startsWith("/")) { + logger.warn("Backup dir not starting with '/', fixing this..."); + conf.back_dir = `/${conf.back_dir}`; this.setConf(conf); } - if(!conf.back_dir.endsWith('/')){ - logger.warn('Backup dir not ending with \'/\', fixing this...'); - conf.back_dir=`${conf.back_dir}/`; + if (!conf.back_dir.endsWith("/")) { + logger.warn("Backup dir not ending with '/', fixing this..."); + conf.back_dir = `${conf.back_dir}/`; this.setConf(conf); } } - } - else { + } else { status.status = "error"; status.error_code = 2; - status.message = "Nextcloud config not found !" + status.message = "Nextcloud config not found !"; statusTools.setStatus(status); logger.error(status.message); reject("Nextcloud config not found !"); } - }); } - + getConf() { if (fs.existsSync(configPath)) { let content = JSON.parse(fs.readFileSync(configPath)); return content; - } - else - return null; + } else return null; } - + setConf(conf) { fs.writeFileSync(configPath, JSON.stringify(conf)); } - - + uploadFile(id, path) { return new Promise((resolve, reject) => { if (this.client == null) { - this.confIsValid().then(() => { - this._startUpload(id, path); - }).catch((err) => { - reject(err); - }) - } - else - this._startUpload(id, path); + this.confIsValid() + .then(() => { + this._startUpload(id, path); + }) + .catch((err) => { + reject(err); + }); + } else this._startUpload(id, path); }); } - + _startUpload(id, path) { - return new Promise( (resolve, reject) => { + return new Promise((resolve, reject) => { let status = statusTools.getStatus(); status.status = "upload"; status.progress = 0; status.message = null; status.error_code = null; statusTools.setStatus(status); - logger.info('Uploading snap...'); - let tmpFile = `./temp/${id}.tar` - let stream = fs.createReadStream(tmpFile); - let conf = this.getConf() + logger.info("Uploading snap..."); + let tmpFile = `./temp/${id}.tar`; + let stream = fs.createReadStream(tmpFile); + let conf = this.getConf(); let options = { body: stream, username: this.username, password: this.password, + }; + if (conf.ssl === "true") { + options["https"] = { rejectUnauthorized: conf.self_signed === "false" }; } - if(conf.ssl === 'true'){ - options["https"] = { rejectUnauthorized: conf.self_signed === "false" } - } - - got.stream.put(this.baseUrl + encodeURI(path), options).on('uploadProgress', e => { - let percent = e.percent; - if (status.progress != percent) { - status.progress = percent; - statusTools.setStatus(status); - } - if (percent >= 1) { - logger.info('Upload done...'); - } - }).on('response', res => { - - if (res.statusCode != 201 && res.statusCode != 204) { + + got.stream + .put(this.baseUrl + encodeURI(path), options) + .on("uploadProgress", (e) => { + let percent = e.percent; + if (status.progress != percent) { + status.progress = percent; + statusTools.setStatus(status); + } + if (percent >= 1) { + logger.info("Upload done..."); + } + }) + .on("response", (res) => { + if (res.statusCode != 201 && res.statusCode != 204) { + status.status = "error"; + status.error_code = 4; + status.message = `Fail to upload snapshot to nextcloud (Status code: ${res.statusCode})!`; + statusTools.setStatus(status); + logger.error(status.message); + fs.unlinkSync(tmpFile); + reject(status.message); + } else { + logger.info(`...Upload finish ! (status: ${res.statusCode})`); + status.status = "idle"; + status.progress = -1; + status.message = null; + status.error_code = null; + status.last_backup = moment().format("MMM D, YYYY HH:mm"); + statusTools.setStatus(status); + cleanTempFolder(); + let autoCleanCloud = settingsTools.getSettings().auto_clean_backup; + if (autoCleanCloud != null && autoCleanCloud == "true") { + this.clean().catch(); + } + let autoCleanlocal = settingsTools.getSettings().auto_clean_local; + if (autoCleanlocal != null && autoCleanlocal == "true") { + hassioApiTools.clean(); + } + resolve(); + } + }) + .on("error", (err) => { + fs.unlinkSync(tmpFile); status.status = "error"; status.error_code = 4; - status.message = `Fail to upload snapshot to nextcloud (Status code: ${res.statusCode})!`; + status.message = `Fail to upload snapshot to nextcloud (${err}) !`; statusTools.setStatus(status); logger.error(status.message); - fs.unlinkSync(tmpFile); reject(status.message); - } else { - logger.info(`...Upload finish ! (status: ${res.statusCode})`); - status.status = "idle"; - status.progress = -1; - status.message = null; - status.error_code = null; - status.last_backup = moment().format('MMM D, YYYY HH:mm'); - statusTools.setStatus(status); - cleanTempFolder(); - let autoCleanCloud = settingsTools.getSettings().auto_clean_backup; - if (autoCleanCloud != null && autoCleanCloud == "true") { - this.clean().catch(); - } - let autoCleanlocal = settingsTools.getSettings().auto_clean_local; - if (autoCleanlocal != null && autoCleanlocal == "true") { - hassioApiTools.clean(); - } - resolve(); - } - }).on('error', err => { - - fs.unlinkSync(tmpFile); - status.status = "error"; - status.error_code = 4; - status.message = `Fail to upload snapshot to nextcloud (${err}) !`; - statusTools.setStatus(status); - logger.error(status.message); - reject(status.message); - }); - + }); }); } - + downloadFile(path) { return new Promise((resolve, reject) => { if (this.client == null) { - this.confIsValid().then(() => { - this._startDownload(path) - .then((path)=> resolve(path)) - .catch(()=> reject()); - }).catch((err) => { - reject(err); - }) - } - else - this._startDownload(path) - .then((path)=> resolve(path)) - .catch(()=> reject()); + this.confIsValid() + .then(() => { + this._startDownload(path) + .then((path) => resolve(path)) + .catch(() => reject()); + }) + .catch((err) => { + reject(err); + }); + } else + this._startDownload(path) + .then((path) => resolve(path)) + .catch(() => reject()); }); } _startDownload(path) { - return new Promise( (resolve, reject) => { + return new Promise((resolve, reject) => { let status = statusTools.getStatus(); status.status = "download-b"; status.progress = 0; status.message = null; status.error_code = null; statusTools.setStatus(status); - - logger.info('Downloading backup...'); - - let tmpFile = `./temp/restore_${moment().format('MMM-DD-YYYY_HH_mm')}.tar` - let stream = fs.createWriteStream(tmpFile); - let conf = this.getConf() + + logger.info("Downloading backup..."); + + let tmpFile = `./temp/restore_${moment().format("MMM-DD-YYYY_HH_mm")}.tar`; + let stream = fs.createWriteStream(tmpFile); + let conf = this.getConf(); let options = { username: this.username, password: this.password, + }; + if (conf.ssl === "true") { + options["https"] = { rejectUnauthorized: conf.self_signed === "false" }; } - if(conf.ssl === 'true'){ - options["https"] = { rejectUnauthorized: conf.self_signed === "false" } - } - + pipeline( - got.stream.get(this.baseUrl + encodeURI(path), options) - .on('downloadProgress', e => { + got.stream.get(this.baseUrl + encodeURI(path), options).on("downloadProgress", (e) => { let percent = Math.round(e.percent * 100) / 100; if (status.progress != percent) { status.progress = percent; statusTools.setStatus(status); } - }) - , + }), stream - ) - .then((res)=>{ - logger.info('Download success !') + ) + .then((res) => { + logger.info("Download success !"); status.progress = 1; statusTools.setStatus(status); - logger.debug("Backup dl size : " + (fs.statSync(tmpFile).size / 1024 / 1024)); + logger.debug("Backup dl size : " + fs.statSync(tmpFile).size / 1024 / 1024); resolve(tmpFile); - }).catch((err)=>{ - if(fs.existsSync(tmpFile)) - fs.unlinkSync(tmpFile); + }) + .catch((err) => { + if (fs.existsSync(tmpFile)) fs.unlinkSync(tmpFile); status.status = "error"; status.message = "Fail to download Hassio snapshot (" + err.message + ")"; status.error_code = 7; statusTools.setStatus(status); logger.error(status.message); reject(err.message); - }) - - }); - } - - getFolderContent(path) { - return new Promise((resolve, reject) => { - if(this.client == null){ - reject(); - return; - } - this.client.getDirectoryContents(path) + }); + }); + } + + getFolderContent(path) { + return new Promise((resolve, reject) => { + if (this.client == null) { + reject(); + return; + } + this.client + .getDirectoryContents(path) .then((contents) => { resolve(contents); - }).catch((error) => { - reject(error); }) - }); - } - - clean() { - let limit = settingsTools.getSettings().auto_clean_backup_keep; - if (limit == null) - limit = 5; - return new Promise((resolve, reject) => { - this.getFolderContent(this.getConf().back_dir + pathTools.auto).then(async (contents) => { + .catch((error) => { + reject(error); + }); + }); + } + + clean() { + let limit = settingsTools.getSettings().auto_clean_backup_keep; + if (limit == null) limit = 5; + return new Promise((resolve, reject) => { + this.getFolderContent(this.getConf().back_dir + pathTools.auto) + .then(async (contents) => { if (contents.length < limit) { resolve(); return; } contents.sort((a, b) => { - if (moment(a.lastmod).isBefore(moment(b.lastmod))) - return 1; - else - return -1; + if (moment(a.lastmod).isBefore(moment(b.lastmod))) return 1; + else return -1; }); - + let toDel = contents.slice(limit); for (let i in toDel) { await this.client.deleteFile(toDel[i].filename); } - logger.info('Cloud clean done.') + logger.info("Cloud clean done."); resolve(); - - }).catch((error) => { + }) + .catch((error) => { status.status = "error"; status.error_code = 6; - status.message = "Fail to clean Nexcloud (" + error + ") !" + status.message = "Fail to clean Nexcloud (" + error + ") !"; statusTools.setStatus(status); logger.error(status.message); reject(status.message); }); - }) - - } - - - - - } - - function cleanTempFolder() { - fs.readdir("./temp/", (err, files) => { - if (err) throw err; - - for (const file of files) { - fs.unlink(path.join("./temp/", file), err => { - if (err) throw err; - }); - } }); } - - - class Singleton { - constructor() { - if (!Singleton.instance) { - Singleton.instance = new WebdavTools(); - } +} + +function cleanTempFolder() { + fs.readdir("./temp/", (err, files) => { + if (err) throw err; + + for (const file of files) { + fs.unlink(path.join("./temp/", file), (err) => { + if (err) throw err; + }); } - - getInstance() { - return Singleton.instance; + }); +} + +class Singleton { + constructor() { + if (!Singleton.instance) { + Singleton.instance = new WebdavTools(); } } - - module.exports = Singleton; - - \ No newline at end of file + + getInstance() { + return Singleton.instance; + } +} + +module.exports = Singleton;