diff --git a/.eslintrc b/.eslintrc index 74de9c8..ad0902a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,18 +1,25 @@ { "extends": [ - "codex" + "codex/ts", + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" ], "plugins": [ - "chai-friendly" + "chai-friendly", + "@typescript-eslint" ], "env": { "mocha": true }, "rules": { - "no-unused-expressions": 0, - "chai-friendly/no-unused-expressions": 2 + "no-unused-expressions": 1, + "chai-friendly/no-unused-expressions": 2, + "@typescript-eslint/ban-types": 1, + "@typescript-eslint/no-magic-numbers": 0, + "@typescript-eslint/no-explicit-any": 1 }, - "parser": "babel-eslint", + "parser": "@typescript-eslint/parser", "globals": { "fetch": true, "alert": true diff --git a/.gitignore b/.gitignore index d9bc62b..fcc7825 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,6 @@ typings/ # Uploads /public/uploads /public/uploads_test + +# Compiled files +/dist/* \ No newline at end of file diff --git a/.nvmrc b/.nvmrc index ee1b03f..832d385 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -9.11.1 +16.14.0 diff --git a/README.md b/README.md index 18bfd6c..96164d5 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,10 @@ $ yarn install --frozen-lockfile ``` ### Available scripts +#### Compile to Javascript +``` +$ yarn compile +``` #### Start the server diff --git a/config/development.json b/config/development.json index c91a562..fc7ab53 100644 --- a/config/development.json +++ b/config/development.json @@ -1,6 +1,7 @@ { "port": 3000, "database": ".db", + "rcFile": "./.codexdocsrc", "uploads": "public/uploads", "secret": "iamasecretstring" } diff --git a/config/index.js b/config/index.js deleted file mode 100644 index 3e50721..0000000 --- a/config/index.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * This module reads configuration file depending on NODE_ENV - * - * @type {module} - */ - -const fs = require('fs'); -const path = require('path'); -const NODE_ENV = process.env.NODE_ENV || 'development'; -const configPath = `./${NODE_ENV}.json`; -let config; - -if (fs.existsSync(path.resolve(__dirname, configPath))) { - config = require(configPath); -} else { - config = { - database: '.db', - port: 3000, - uploads: 'public/uploads', - secret: 'secret' - }; -} - -module.exports = config; diff --git a/config/production.json b/config/production.json index c91a562..fc7ab53 100644 --- a/config/production.json +++ b/config/production.json @@ -1,6 +1,7 @@ { "port": 3000, "database": ".db", + "rcFile": "./.codexdocsrc", "uploads": "public/uploads", "secret": "iamasecretstring" } diff --git a/config/testing.json b/config/testing.json index 0c1ec88..25371d0 100644 --- a/config/testing.json +++ b/config/testing.json @@ -1,7 +1,7 @@ { "port": 3001, "database": ".testdb", - "rcFile": "./test/.codexdocsrc", + "rcFile": "./src/test/.codexdocsrc", "uploads": "public/uploads_test", "secret": "iamasecretstring" } diff --git a/docker/Dockerfile.prod b/docker/Dockerfile.prod index 581144f..7b227e6 100644 --- a/docker/Dockerfile.prod +++ b/docker/Dockerfile.prod @@ -1,12 +1,14 @@ -FROM node:12.14.1-alpine3.11 +FROM node:16.14.0-alpine3.15 WORKDIR /usr/src/app -RUN apk add --no-cache git gcc g++ python make musl-dev +RUN apk add --no-cache git gcc g++ python3 make musl-dev COPY package.json yarn.lock ./ -RUN yarn install --prod +RUN yarn install COPY . . +RUN yarn compile + CMD ["yarn", "start"] diff --git a/nodemon.json b/nodemon.json index 2b0661c..6a2a5ac 100644 --- a/nodemon.json +++ b/nodemon.json @@ -1,11 +1,15 @@ { - "ignore": [ - "node_modules", - "src/frontend", - "public/dist" - ], - "events": { - "restart": "echo \"App restarted due to: '$FILENAME'\"" - }, - "ext": "js,twig" -} + "ignore": [ + "node_modules", + "src/frontend", + "public/dist" + ], + "events": { + "restart": "echo \"App restarted due to: '$FILENAME'\"" + }, + "watch": ["src/"], + "execMap": { + "ts": "node -r ts-node/register" + }, + "ext": "js,json,ts,twig" +} \ No newline at end of file diff --git a/package.json b/package.json index 55d05ca..1fb4124 100644 --- a/package.json +++ b/package.json @@ -9,40 +9,45 @@ "> 1%" ], "scripts": { - "start": "cross-env NODE_ENV=production nodemon ./bin/www", - "start:dev": "cross-env NODE_ENV=development nodemon ./bin/www", - "test": "cross-env NODE_ENV=testing mocha --recursive ./test", - "lint": "eslint --fix --cache ./src/**/*.js", + "start:ts": "cross-env NODE_ENV=production nodemon --config nodemon.json ./src/bin/server.ts", + "start:dev": "cross-env NODE_ENV=development nodemon --config nodemon.json ./src/bin/server.ts", + "test": "cross-env NODE_ENV=testing mocha --recursive ./dist/test --exit", + "test:ts": "cross-env NODE_ENV=testing ts-mocha ./src/test/*.ts ./src/test/**/*.ts --exit", + "lint": "eslint --fix --cache --ext .ts ./src/backend", "build": "webpack ./src/frontend/js/app.js --o='./public/dist/[name].bundle.js' --output-library=Docs --output-public-path=/dist/ -p --mode=production", "build:dev": "webpack ./src/frontend/js/app.js --o='./public/dist/[name].bundle.js' --output-library=Docs --output-public-path=/dist/ -p --mode=development --watch", - "precommit": "yarn lint && yarn test --exit", - "generatePassword": "node ./generatePassword.js", - "editor-upgrade": "yarn add -D @editorjs/{editorjs,header,code,delimiter,list,link,image,table,inline-code,marker,warning,checklist,raw}@latest" + "precommit": "yarn lint && yarn test:ts", + "generatePassword:ts": "ts-node ./src/generatePassword.ts", + "generatePassword": "node ./dist/generatePassword.js", + "editor-upgrade": "yarn add -D @editorjs/{editorjs,header,code,delimiter,list,link,image,table,inline-code,marker,warning,checklist,raw}@latest", + "compile": "npx tsc" }, "dependencies": { "@editorjs/embed": "^2.5.0", "bcrypt": "^5.0.1", - "commander": "^2.19.0", - "cookie-parser": "~1.4.3", - "cross-env": "^5.2.0", - "csurf": "^1.9.0", - "debug": "~4.1.0", - "dotenv": "^6.2.0", - "express": "~4.16.0", - "file-type": "^10.7.1", - "http-errors": "~1.7.1", - "jsonwebtoken": "^8.4.0", - "mime": "^2.4.0", - "mkdirp": "^0.5.1", - "morgan": "~1.9.0", - "multer": "^1.3.1", + "commander": "^8.1.0", + "config": "^3.3.6", + "cookie-parser": "^1.4.5", + "cross-env": "^7.0.3", + "csurf": "^1.11.0", + "debug": "^4.3.2", + "dotenv": "^10.0.0", + "express": "^4.17.1", + "file-type": "^16.5.2", + "http-errors": "^1.8.0", + "jsonwebtoken": "^8.5.1", + "mime": "^2.5.2", + "mkdirp": "^1.0.4", + "morgan": "^1.10.0", + "multer": "^1.4.2", "nedb": "^1.8.0", "node-fetch": "^2.6.1", - "nodemon": "^1.18.3", - "open-graph-scraper": "^4.5.0", - "twig": "~1.12.0", + "nodemon": "^2.0.12", + "open-graph-scraper": "^4.9.0", + "ts-node": "^10.1.0", + "twig": "^1.15.4", "typescript-eslint": "^0.0.1-alpha.0", - "uuid4": "^1.0.0" + "uuid4": "^2.0.2" }, "devDependencies": { "@babel/core": "^7.0.0", @@ -63,6 +68,31 @@ "@editorjs/raw": "^2.3.0", "@editorjs/table": "^2.0.1", "@editorjs/warning": "^1.2.0", + "@types/bcrypt": "^5.0.0", + "@types/chai": "^4.2.21", + "@types/commander": "^2.12.2", + "@types/config": "^0.0.39", + "@types/cookie-parser": "^1.4.2", + "@types/csurf": "^1.11.2", + "@types/debug": "^4.1.7", + "@types/eslint": "^7.28.0", + "@types/express": "^4.17.13", + "@types/file-type": "^10.9.1", + "@types/jsonwebtoken": "^8.5.4", + "@types/mime": "^2.0.3", + "@types/mkdirp": "^1.0.2", + "@types/mocha": "^9.0.0", + "@types/morgan": "^1.9.3", + "@types/multer": "^1.4.7", + "@types/nedb": "^1.8.12", + "@types/node": "^16.4.1", + "@types/node-fetch": "^2.5.12", + "@types/open-graph-scraper": "^4.8.1", + "@types/rimraf": "^3.0.1", + "@types/sinon": "^10.0.2", + "@types/twig": "^1.12.6", + "@typescript-eslint/eslint-plugin": "^4.28.5", + "@typescript-eslint/parser": "^4.28.5", "autoprefixer": "^9.1.3", "babel": "^6.23.0", "babel-eslint": "^10.0.1", @@ -71,17 +101,16 @@ "chai-http": "^4.0.0", "css-loader": "^1.0.0", "cssnano": "^4.1.0", - "eslint": "^6.8.0", - "eslint-config-codex": "^1.3.4", + "eslint": "^7.31.0", + "eslint-config-codex": "^1.6.2", "eslint-plugin-chai-friendly": "^0.4.1", "eslint-plugin-import": "^2.14.0", "eslint-plugin-node": "^8.0.1", - "eslint-plugin-standard": "^4.0.0", "highlight.js": "^11.1.0", "husky": "^1.1.2", "mini-css-extract-plugin": "^0.4.3", "mocha": "^5.2.0", - "mocha-sinon": "^2.1.0", + "mocha-sinon": "^2.1.2", "module-dispatcher": "^2.0.0", "normalize.css": "^8.0.1", "nyc": "^13.1.0", @@ -99,8 +128,10 @@ "postcss-nested-ancestors": "^2.0.0", "postcss-nesting": "^7.0.0", "postcss-smart-import": "^0.7.6", - "rimraf": "^2.6.3", - "sinon": "^7.0.0", + "rimraf": "^3.0.2", + "sinon": "^11.1.2", + "ts-mocha": "^8.0.0", + "typescript": "^4.3.5", "webpack": "^4.17.1", "webpack-cli": "^3.1.0" } diff --git a/src/app.js b/src/app.js deleted file mode 100644 index 8ef3210..0000000 --- a/src/app.js +++ /dev/null @@ -1,42 +0,0 @@ -const createError = require('http-errors'); -const express = require('express'); -const path = require('path'); -const cookieParser = require('cookie-parser'); -const logger = require('morgan'); -const rcParser = require('./utils/rcparser'); -const routes = require('./routes'); - -const app = express(); -const config = rcParser.getConfiguration(); - -app.locals.config = config; - -// view engine setup -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'twig'); -require('./utils/twig'); - -app.use(logger('dev')); -app.use(express.json()); -app.use(express.urlencoded({ extended: true })); -app.use(cookieParser()); -app.use(express.static(path.join(__dirname, '../public'))); - -app.use('/', routes); -// catch 404 and forward to error handler -app.use(function (req, res, next) { - next(createError(404)); -}); - -// error handler -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 : {}; - - // render the error page - res.status(err.status || 500); - res.render('error'); -}); - -module.exports = app; diff --git a/src/backend/app.ts b/src/backend/app.ts new file mode 100644 index 0000000..b9f1c1c --- /dev/null +++ b/src/backend/app.ts @@ -0,0 +1,38 @@ +import express, { Request, Response } from 'express'; +import path from 'path'; +import cookieParser from 'cookie-parser'; +import morgan from 'morgan'; +import rcParser from './utils/rcparser'; +import routes from './routes'; +import HttpException from './exceptions/httpException'; + +const app = express(); +const config = rcParser.getConfiguration(); + +app.locals.config = config; + +// view engine setup +app.set('views', path.join(__dirname, '../../src/backend/', 'views')); +app.set('view engine', 'twig'); +require('./utils/twig'); + +app.use(morgan('dev')); +app.use(express.json()); +app.use(express.urlencoded({ extended: true })); +app.use(cookieParser()); +app.use(express.static(path.join(__dirname, '../../public'))); + +app.use('/', routes); + +// error handler +app.use(function (err: HttpException, req: Request, res: Response) { + // set locals, only providing error in development + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + res.status(err.status || 500); + res.render('error'); +}); + +export default app; \ No newline at end of file diff --git a/src/controllers/aliases.js b/src/backend/controllers/aliases.ts similarity index 75% rename from src/controllers/aliases.js rename to src/backend/controllers/aliases.ts index bdda40a..0628302 100644 --- a/src/controllers/aliases.js +++ b/src/backend/controllers/aliases.ts @@ -1,4 +1,4 @@ -const Alias = require('../models/alias'); +import Alias from '../models/alias'; /** * @class Aliases @@ -11,7 +11,7 @@ class Aliases { * @param {string} aliasName - alias name of entity * @returns {Promise} */ - static async get(aliasName) { + public static async get(aliasName: string): Promise { const alias = await Alias.get(aliasName); if (!alias.id) { @@ -22,4 +22,4 @@ class Aliases { } } -module.exports = Aliases; +export default Aliases; diff --git a/src/controllers/pages.js b/src/backend/controllers/pages.ts similarity index 68% rename from src/controllers/pages.js rename to src/backend/controllers/pages.ts index c37cf6e..6a4bd07 100644 --- a/src/controllers/pages.js +++ b/src/backend/controllers/pages.ts @@ -1,5 +1,7 @@ -const Model = require('../models/page'); -const Alias = require('../models/alias'); +import Page, { PageData } from '../models/page'; +import Alias from '../models/alias'; + +type PageDataFields = keyof PageData; /** * @class Pages @@ -11,7 +13,7 @@ class Pages { * * @returns {['title', 'body']} */ - static get REQUIRED_FIELDS() { + public static get REQUIRED_FIELDS(): Array { return [ 'body' ]; } @@ -21,8 +23,8 @@ class Pages { * @param {string} id - page id * @returns {Promise} */ - static async get(id) { - const page = await Model.get(id); + public static async get(id: string): Promise { + const page = await Page.get(id); if (!page._id) { throw new Error('Page with given id does not exist'); @@ -36,8 +38,8 @@ class Pages { * * @returns {Promise} */ - static async getAll() { - return Model.getAll(); + public static async getAll(): Promise { + return Page.getAll(); } /** @@ -46,20 +48,28 @@ class Pages { * @param {string} parent - id of current page * @returns {Promise} */ - static async getAllExceptChildren(parent) { + public static async getAllExceptChildren(parent: string): Promise { const pagesAvailable = this.removeChildren(await Pages.getAll(), parent); - return pagesAvailable.filter((item) => item !== null); + const nullFilteredPages: Page[] = []; + + pagesAvailable.forEach(async item => { + if (item instanceof Page) { + nullFilteredPages.push(item); + } + }); + + return nullFilteredPages; } /** * Set all children elements to null * - * @param {Page[]} [pagesAvailable] - Array of all pages + * @param {Array} [pagesAvailable] - Array of all pages * @param {string} parent - id of parent page * @returns {Array} */ - static removeChildren(pagesAvailable, parent) { + public static removeChildren(pagesAvailable: Array, parent: string | undefined): Array { pagesAvailable.forEach(async (item, index) => { if (item === null || item._parent !== parent) { return; @@ -74,14 +84,14 @@ class Pages { /** * Create new page model and save it in the database * - * @param {PageData} data + * @param {PageData} data - info about page * @returns {Promise} */ - static async insert(data) { + public static async insert(data: PageData): Promise { try { Pages.validate(data); - const page = new Model(data); + const page = new Page(data); const insertedPage = await page.save(); @@ -95,18 +105,80 @@ class Pages { } return insertedPage; - } catch (validationError) { - throw new Error(validationError); + } catch (e) { + throw new Error('validationError'); } } + /** + * Update page with given id in the database + * + * @param {string} id - page id + * @param {PageData} data - info about page + * @returns {Promise} + */ + public static async update(id: string, data: PageData): Promise { + const page = await Page.get(id); + const previousUri = page.uri; + + if (!page._id) { + throw new Error('Page with given id does not exist'); + } + + if (data.uri && !data.uri.match(/^[a-z0-9'-]+$/i)) { + throw new Error('Uri has unexpected characters'); + } + + page.data = data; + const updatedPage = await page.save(); + + if (updatedPage.uri !== previousUri) { + if (updatedPage.uri) { + const alias = new Alias({ + id: updatedPage._id, + type: Alias.types.PAGE, + }, updatedPage.uri); + + alias.save(); + } + + if (previousUri) { + Alias.markAsDeprecated(previousUri); + } + } + + return updatedPage; + } + + /** + * Remove page with given id from the database + * + * @param {string} id - page id + * @returns {Promise} + */ + public static async remove(id: string): Promise { + const page = await Page.get(id); + + if (!page._id) { + throw new Error('Page with given id does not exist'); + } + + if (page.uri) { + const alias = await Alias.get(page.uri); + + await alias.destroy(); + } + + return page.destroy(); + } + /** * Check PageData object for required fields * - * @param {PageData} data + * @param {PageData} data - info about page * @throws {Error} - validation error */ - static validate(data) { + private static validate(data: PageData): void { const allRequiredFields = Pages.REQUIRED_FIELDS.every(field => typeof data[field] !== 'undefined'); if (!allRequiredFields) { @@ -131,64 +203,6 @@ class Pages { throw new Error('Please, fill page Header'); } } - - /** - * Update page with given id in the database - * - * @param {string} id - page id - * @param {PageData} data - * @returns {Promise} - */ - static async update(id, data) { - const page = await Model.get(id); - const previousUri = page.uri; - - if (!page._id) { - throw new Error('Page with given id does not exist'); - } - - if (data.uri && !data.uri.match(/^[a-z0-9'-]+$/i)) { - throw new Error('Uri has unexpected characters'); - } - - page.data = data; - const updatedPage = await page.save(); - - if (updatedPage.uri !== previousUri) { - if (updatedPage.uri) { - const alias = new Alias({ - id: updatedPage._id, - type: Alias.types.PAGE, - }, updatedPage.uri); - - alias.save(); - } - - Alias.markAsDeprecated(previousUri); - } - - return updatedPage; - } - - /** - * Remove page with given id from the database - * - * @param {string} id - page id - * @returns {Promise} - */ - static async remove(id) { - const page = await Model.get(id); - - if (!page._id) { - throw new Error('Page with given id does not exist'); - } - - const alias = await Alias.get(page.uri); - - await alias.destroy(); - - return page.destroy(); - } } -module.exports = Pages; +export default Pages; diff --git a/src/controllers/pagesOrder.js b/src/backend/controllers/pagesOrder.ts similarity index 62% rename from src/controllers/pagesOrder.js rename to src/backend/controllers/pagesOrder.ts index eeb88a5..f084af3 100644 --- a/src/controllers/pagesOrder.js +++ b/src/backend/controllers/pagesOrder.ts @@ -1,4 +1,5 @@ -const Model = require('../models/pageOrder'); +import PageOrder from '../models/pageOrder'; +import Page from '../models/page'; /** * @class PagesOrder @@ -13,8 +14,8 @@ class PagesOrder { * @param {string} parentId - of which page we want to get children order * @returns {Promise} */ - static async get(parentId) { - const order = await Model.get(parentId); + public static async get(parentId: string): Promise { + const order = await PageOrder.get(parentId); if (!order._id) { throw new Error('Page with given id does not contain order'); @@ -26,10 +27,10 @@ class PagesOrder { /** * Returns all records about page's order * - * @returns {Promise} + * @returns {Promise} */ - static async getAll() { - return Model.getAll(); + public static async getAll(): Promise { + return PageOrder.getAll(); } /** @@ -38,8 +39,8 @@ class PagesOrder { * @param {string} parentId - parent page's id * @param {string} childId - new page pushed to the order */ - static async push(parentId, childId) { - const order = await Model.get(parentId); + public static async push(parentId: string, childId: string): Promise { + const order = await PageOrder.get(parentId); order.push(childId); await order.save(); @@ -52,13 +53,13 @@ class PagesOrder { * @param {string} newParentId - new parent page's id * @param {string} targetPageId - page's id which is changing the parent page */ - static async move(oldParentId, newParentId, targetPageId) { - const oldParentOrder = await Model.get(oldParentId); + public static async move(oldParentId: string, newParentId: string, targetPageId: string): Promise { + const oldParentOrder = await PageOrder.get(oldParentId); oldParentOrder.remove(targetPageId); await oldParentOrder.save(); - const newParentOrder = await Model.get(newParentId); + const newParentOrder = await PageOrder.get(newParentId); newParentOrder.push(targetPageId); await newParentOrder.save(); @@ -73,14 +74,14 @@ class PagesOrder { * @param {boolean} ignoreSelf - should we ignore current page in list or not * @returns {Page[]} */ - static async getOrderedChildren(pages, currentPageId, parentPageId, ignoreSelf = false) { - const children = await Model.get(parentPageId); + public static async getOrderedChildren(pages: Page[], currentPageId: string, parentPageId: string, ignoreSelf = false): Promise { + const children = await PageOrder.get(parentPageId); const unordered = pages.filter(page => page._parent === parentPageId).map(page => page._id); // Create unique array with ordered and unordered pages id - const ordered = [ ...new Set([...children.order, ...unordered]) ]; + const ordered = Array.from(new Set([...children.order, ...unordered])); - const result = []; + const result: Page[] = []; ordered.forEach(pageId => { pages.forEach(page => { @@ -94,26 +95,26 @@ class PagesOrder { } /** - * @param {string[]} unordered + * @param {string[]} unordered - list of pages * @param {string} currentPageId - page's id that changes the order * @param {string} parentPageId - parent page's id that contains both two pages * @param {string} putAbovePageId - page's id above which we put the target page */ - static async update(unordered, currentPageId, parentPageId, putAbovePageId) { - const pageOrder = await Model.get(parentPageId); + public static async update(unordered: string[], currentPageId: string, parentPageId: string, putAbovePageId: string): Promise { + const pageOrder = await PageOrder.get(parentPageId); // Create unique array with ordered and unordered pages id - pageOrder.order = [ ...new Set([...pageOrder.order, ...unordered]) ]; + pageOrder.order = Array.from(new Set([...pageOrder.order, ...unordered])); pageOrder.putAbove(currentPageId, putAbovePageId); await pageOrder.save(); } /** - * @param parentId + * @param {string} parentId - identity of parent page * @returns {Promise} */ - static async remove(parentId) { - const order = await Model.get(parentId); + public static async remove(parentId: string): Promise { + const order = await PageOrder.get(parentId); if (!order._id) { throw new Error('Page with given id does not contain order'); @@ -123,4 +124,4 @@ class PagesOrder { } } -module.exports = PagesOrder; +export default PagesOrder; diff --git a/src/controllers/transport.js b/src/backend/controllers/transport.ts similarity index 64% rename from src/controllers/transport.js rename to src/backend/controllers/transport.ts index a35a1aa..b8b773e 100644 --- a/src/controllers/transport.js +++ b/src/backend/controllers/transport.ts @@ -1,12 +1,17 @@ -const fileType = require('file-type'); -const fetch = require('node-fetch'); -const fs = require('fs'); -const nodePath = require('path'); +import fileType from 'file-type'; +import fetch from 'node-fetch'; +import fs from 'fs'; +import nodePath from 'path'; +import config from 'config'; +import File, { FileData } from '../models/file'; +import crypto from '../utils/crypto'; +import deepMerge from '../utils/objects'; -const Model = require('../models/file'); -const { random16 } = require('../utils/crypto'); -const { deepMerge } = require('../utils/objects'); -const config = require('../../config'); +const random16 = crypto.random16; + +interface Dict { + [key: string]: any; +} /** * @class Transport @@ -28,10 +33,10 @@ class Transport { * @param {object} map - object that represents how should fields of File object should be mapped to response * @returns {Promise} */ - static async save(multerData, map) { + public static async save(multerData: Dict, map: Dict): Promise { const { originalname: name, path, filename, size, mimetype } = multerData; - const file = new Model({ + const file = new File({ name, filename, path, @@ -57,22 +62,33 @@ class Transport { * @param {object} map - object that represents how should fields of File object should be mapped to response * @returns {Promise} */ - static async fetch(url, map) { + public static async fetch(url: string, map: Dict): Promise { const fetchedFile = await fetch(url); const buffer = await fetchedFile.buffer(); const filename = await random16(); - const type = fileType(buffer); + const type = await fileType.fromBuffer(buffer); const ext = type ? type.ext : nodePath.extname(url).slice(1); - fs.writeFileSync(`${config.uploads}/${filename}.${ext}`, buffer); + fs.writeFileSync(`${config.get('uploads')}/${filename}.${ext}`, buffer); - const file = new Model({ + const fetchedContentType: string | null = fetchedFile.headers.get('content-type'); + let fetchedMimeType: string|undefined; + + if (fetchedContentType === null) { + fetchedMimeType = undefined; + } else { + fetchedMimeType = fetchedContentType; + } + + const mimeType = type ? type.mime : fetchedMimeType; + + const file = new File({ name: url, filename: `${filename}.${ext}`, - path: `${config.uploads}/${filename}.${ext}`, + path: `${config.get('uploads')}/${filename}.${ext}`, size: buffer.length, - mimetype: type ? type.mime : fetchedFile.headers.get('content-type'), + mimetype: mimeType, }); await file.save(); @@ -89,19 +105,19 @@ class Transport { /** * Map fields of File object to response by provided map object * - * @param {File} file + * @param {File} file - file object * @param {object} map - object that represents how should fields of File object should be mapped to response * */ - static composeResponse(file, map) { - const response = {}; + public static composeResponse(file: File, map: Dict): Dict { + const response: Dict = {}; const { data } = file; Object.entries(map).forEach(([name, path]) => { - const fields = path.split(':'); + const fields: string[] = path.split(':'); if (fields.length > 1) { - let object = {}; + let object: Dict = {}; const result = object; fields.forEach((field, i) => { @@ -125,4 +141,4 @@ class Transport { } } -module.exports = Transport; +export default Transport; diff --git a/src/backend/controllers/users.ts b/src/backend/controllers/users.ts new file mode 100644 index 0000000..549cad5 --- /dev/null +++ b/src/backend/controllers/users.ts @@ -0,0 +1,20 @@ +import User from '../models/user'; + +/** + * @class Users + * @classdesc Users controller + */ +class Users { + /** + * Find and return user model. + * + * @returns {Promise} + */ + public static async get(): Promise { + const userData: User = await User.get(); + + return userData; + } +} + +export default Users; diff --git a/src/backend/exceptions/httpException.ts b/src/backend/exceptions/httpException.ts new file mode 100644 index 0000000..f13e7a2 --- /dev/null +++ b/src/backend/exceptions/httpException.ts @@ -0,0 +1,21 @@ +/** + * HttpException class for middleware + * + * @property {number} status - exception status code + * @property {string} message - detail about the exception + */ +class HttpException extends Error { + public status: number; + public message: string; + /** + * @param status - status of the exception + * @param message - message about the exception + */ + constructor(status: number, message: string) { + super(message); + this.status = status; + this.message = message; + } +} + +export default HttpException; \ No newline at end of file diff --git a/src/models/alias.js b/src/backend/models/alias.ts similarity index 70% rename from src/models/alias.js rename to src/backend/models/alias.ts index 5090d08..58d8142 100644 --- a/src/models/alias.js +++ b/src/backend/models/alias.ts @@ -1,5 +1,8 @@ -const { aliases: aliasesDb } = require('../utils/database/index'); -const { binaryMD5 } = require('../utils/crypto'); +import crypto from '../utils/crypto'; +import database from '../utils/database/index'; + +const binaryMD5 = crypto.binaryMD5; +const aliasesDb = database['aliases']; /** * @typedef {object} AliasData @@ -10,6 +13,13 @@ const { binaryMD5 } = require('../utils/crypto'); * @property {string} id - entity id * */ +export interface AliasData { + _id?: string; + hash?: string; + type?: string; + deprecated?: boolean; + id?: string; +} /** * @class Alias @@ -22,16 +32,40 @@ const { binaryMD5 } = require('../utils/crypto'); * @property {string} id - entity title */ class Alias { + public _id?: string; + public hash?: string; + public type?: string; + public deprecated?: boolean; + public id?: string; + + /** + * @class + * + * @param {AliasData} data - info about alias + * @param {string} aliasName - alias of entity + */ + constructor(data: AliasData = {}, aliasName = '') { + if (data === null) { + data = {}; + } + if (data._id) { + this._id = data._id; + } + if (aliasName) { + this.hash = binaryMD5(aliasName); + } + this.data = data; + } /** * Return Alias types * * @returns {object} */ - static get types() { + public static get types(): { PAGE: string } { return { PAGE: 'page', }; - }; + } /** * Find and return alias with given alias @@ -39,7 +73,7 @@ class Alias { * @param {string} aliasName - alias of entity * @returns {Promise} */ - static async get(aliasName) { + public static async get(aliasName: string): Promise { const hash = binaryMD5(aliasName); let data = await aliasesDb.findOne({ hash: hash, @@ -54,22 +88,17 @@ class Alias { } /** - * @class + * Mark alias as deprecated * - * @param {AliasData} data * @param {string} aliasName - alias of entity + * @returns {Promise} */ - constructor(data = {}, aliasName = '') { - if (data === null) { - data = {}; - } - if (data._id) { - this._id = data._id; - } - if (aliasName) { - this.hash = binaryMD5(aliasName); - } - this.data = data; + public static async markAsDeprecated(aliasName: string): Promise { + const alias = await Alias.get(aliasName); + + alias.deprecated = true; + + return alias.save(); } /** @@ -77,9 +106,9 @@ class Alias { * * @returns {Promise} */ - async save() { + public async save(): Promise { if (!this._id) { - const insertedRow = await aliasesDb.insert(this.data); + const insertedRow = await aliasesDb.insert(this.data) as { _id: string }; this._id = insertedRow._id; } else { @@ -92,9 +121,9 @@ class Alias { /** * Set AliasData object fields to internal model fields * - * @param {AliasData} aliasData + * @param {AliasData} aliasData - info about alias */ - set data(aliasData) { + public set data(aliasData: AliasData) { const { id, type, hash, deprecated } = aliasData; this.id = id || this.id; @@ -108,7 +137,7 @@ class Alias { * * @returns {AliasData} */ - get data() { + public get data(): AliasData { return { _id: this._id, id: this.id, @@ -119,23 +148,9 @@ class Alias { } /** - * Mark alias as deprecated - * - * @param {string} aliasName - alias of entity * @returns {Promise} */ - static async markAsDeprecated(aliasName) { - const alias = await Alias.get(aliasName); - - alias.deprecated = true; - - return alias.save(); - } - - /** - * @returns {Promise} - */ - async destroy() { + public async destroy(): Promise { await aliasesDb.remove({ _id: this._id }); delete this._id; @@ -144,4 +159,4 @@ class Alias { } } -module.exports = Alias; +export default Alias; diff --git a/src/models/file.js b/src/backend/models/file.ts similarity index 68% rename from src/models/file.js rename to src/backend/models/file.ts index af2a928..3ed44ee 100644 --- a/src/models/file.js +++ b/src/backend/models/file.ts @@ -1,4 +1,6 @@ -const { files: filesDb } = require('../utils/database/index'); +import database from '../utils/database/index'; + +const filesDb = database['files']; /** * @typedef {object} FileData @@ -10,6 +12,15 @@ const { files: filesDb } = require('../utils/database/index'); * @property {string} mimetype - file MIME type * @property {number} size - size of the file in */ +export interface FileData { + _id?: string; + name?: string; + filename?: string; + path?: string; + mimetype?: string; + size?: number; + [key: string]: string | number | undefined; +} /** * @class File @@ -23,48 +34,19 @@ const { files: filesDb } = require('../utils/database/index'); * @property {number} size - size of the file in */ class File { - /** - * Find and return model of file with given id - * - * @param {string} _id - file id - * @returns {Promise} - */ - static async get(_id) { - const data = await filesDb.findOne({ _id }); - - return new File(data); - } - - /** - * Find and return model of file with given id - * - * @param {string} filename - uploaded filename - * @returns {Promise} - */ - static async getByFilename(filename) { - const data = await filesDb.findOne({ filename }); - - return new File(data); - } - - /** - * Find all files which match passed query object - * - * @param {object} query - * @returns {Promise} - */ - static async getAll(query = {}) { - const docs = await filesDb.find(query); - - return Promise.all(docs.map(doc => new File(doc))); - } + public _id?: string; + public name?: string; + public filename?: string; + public path?: string; + public mimetype?: string; + public size?: number; /** * @class * - * @param {FileData} data + * @param {FileData} data - info about file */ - constructor(data = {}) { + constructor(data: FileData = {}) { if (data === null) { data = {}; } @@ -75,13 +57,48 @@ class File { this.data = data; } + /** + * Find and return model of file with given id + * + * @param {string} _id - file id + * @returns {Promise} + */ + public static async get(_id: string): Promise { + const data: FileData = await filesDb.findOne({ _id }); + + return new File(data); + } + + /** + * Find and return model of file with given id + * + * @param {string} filename - uploaded filename + * @returns {Promise} + */ + public static async getByFilename(filename: string): Promise { + const data = await filesDb.findOne({ filename }); + + return new File(data); + } + + /** + * Find all files which match passed query object + * + * @param {object} query - input query + * @returns {Promise} + */ + public static async getAll(query: Record = {}): Promise { + const docs = await filesDb.find(query); + + return Promise.all(docs.map(doc => new File(doc))); + } /** * Set FileData object fields to internal model fields * - * @param {FileData} fileData + * @param {FileData} fileData - info about file */ - set data(fileData) { + public set data(fileData: FileData) { const { name, filename, path, mimetype, size } = fileData; this.name = name || this.name; @@ -96,7 +113,7 @@ class File { * * @returns {FileData} */ - get data() { + public get data(): FileData { return { _id: this._id, name: this.name, @@ -112,9 +129,9 @@ class File { * * @returns {Promise} */ - async save() { + public async save(): Promise { if (!this._id) { - const insertedRow = await filesDb.insert(this.data); + const insertedRow = await filesDb.insert(this.data) as { _id: string }; this._id = insertedRow._id; } else { @@ -129,7 +146,7 @@ class File { * * @returns {Promise} */ - async destroy() { + public async destroy(): Promise { await filesDb.remove({ _id: this._id }); delete this._id; @@ -137,24 +154,24 @@ class File { return this; } - /** - * Removes unnecessary public folder prefix - * - * @param {string} path - * @returns {string} - */ - processPath(path) { - return path.replace(/^public/, ''); - } - /** * Return readable file data * * @returns {FileData} */ - toJSON() { + public toJSON(): FileData { return this.data; } + + /** + * Removes unnecessary public folder prefix + * + * @param {string} path - input path to be processed + * @returns {string} + */ + private processPath(path: string): string { + return path.replace(/^public/, ''); + } } -module.exports = File; +export default File; diff --git a/src/models/page.js b/src/backend/models/page.ts similarity index 65% rename from src/models/page.js rename to src/backend/models/page.ts index 87e2f8d..d90b186 100644 --- a/src/models/page.js +++ b/src/backend/models/page.ts @@ -1,5 +1,7 @@ -const urlify = require('../utils/urlify'); -const { pages: pagesDb } = require('../utils/database/index'); +import urlify from '../utils/urlify'; +import database from '../utils/database/index'; + +const pagesDb = database['pages']; /** * @typedef {object} PageData @@ -9,6 +11,13 @@ const { pages: pagesDb } = require('../utils/database/index'); * @property {*} body - page body * @property {string} parent - id of parent page */ +export interface PageData { + _id?: string; + title?: string; + uri?: string; + body?: any; + parent?: string; +} /** * @class Page @@ -21,48 +30,18 @@ const { pages: pagesDb } = require('../utils/database/index'); * @property {string} _parent - id of parent page */ class Page { - /** - * Find and return model of page with given id - * - * @param {string} _id - page id - * @returns {Promise} - */ - static async get(_id) { - const data = await pagesDb.findOne({ _id }); - - return new Page(data); - } - - /** - * Find and return model of page with given uri - * - * @param {string} uri - page uri - * @returns {Promise} - */ - static async getByUri(uri) { - const data = await pagesDb.findOne({ uri }); - - return new Page(data); - } - - /** - * Find all pages which match passed query object - * - * @param {object} query - * @returns {Promise} - */ - static async getAll(query = {}) { - const docs = await pagesDb.find(query); - - return Promise.all(docs.map(doc => new Page(doc))); - } + public _id?: string; + public body?: any; + public title?: string; + public uri?: string; + public _parent?: string; /** * @class * - * @param {PageData} data + * @param {PageData} data - page's data */ - constructor(data = {}) { + constructor(data: PageData = {}) { if (data === null) { data = {}; } @@ -74,12 +53,48 @@ class Page { this.data = data; } + /** + * Find and return model of page with given id + * + * @param {string} _id - page id + * @returns {Promise} + */ + public static async get(_id: string): Promise { + const data = await pagesDb.findOne({ _id }); + + return new Page(data); + } + + /** + * Find and return model of page with given uri + * + * @param {string} uri - page uri + * @returns {Promise} + */ + public static async getByUri(uri: string): Promise { + const data = await pagesDb.findOne({ uri }); + + return new Page(data); + } + + /** + * Find all pages which match passed query object + * + * @param {object} query - input query + * @returns {Promise} + */ + public static async getAll(query: Record = {}): Promise { + const docs = await pagesDb.find(query); + + return Promise.all(docs.map(doc => new Page(doc))); + } + /** * Set PageData object fields to internal model fields * - * @param {PageData} pageData + * @param {PageData} pageData - page's data */ - set data(pageData) { + public set data(pageData: PageData) { const { body, parent, uri } = pageData; this.body = body || this.body; @@ -93,7 +108,7 @@ class Page { * * @returns {PageData} */ - get data() { + public get data(): PageData { return { _id: this._id, title: this.title, @@ -103,32 +118,12 @@ class Page { }; } - /** - * Extract first header from editor data - * - * @returns {string} - */ - extractTitleFromBody() { - const headerBlock = this.body ? this.body.blocks.find(block => block.type === 'header') : ''; - - return headerBlock ? headerBlock.data.text : ''; - } - - /** - * Transform title for uri - * - * @returns {string} - */ - transformTitleToUri() { - return urlify(this.title); - } - /** * Link given page as parent * - * @param {Page} parentPage + * @param {Page} parentPage - the page to be set as parent */ - set parent(parentPage) { + public set parent(parentPage: Page) { this._parent = parentPage._id; } @@ -137,9 +132,10 @@ class Page { * * @returns {Promise} */ - get parent() { - return pagesDb.findOne({ _id: this._parent }) - .then(data => new Page(data)); + public async getParent(): Promise { + const data = await pagesDb.findOne({ _id: this._parent }); + + return new Page(data); } /** @@ -147,9 +143,11 @@ class Page { * * @returns {Promise} */ - get children() { + public get children(): Promise { return pagesDb.find({ parent: this._id }) - .then(data => data.map(page => new Page(page))); + .then(data => { + return data.map(page => new Page(page)); + }); } /** @@ -157,11 +155,13 @@ class Page { * * @returns {Promise} */ - async save() { - this.uri = await this.composeUri(this.uri); + public async save(): Promise { + if (this.uri !== undefined) { + this.uri = await this.composeUri(this.uri); + } if (!this._id) { - const insertedRow = await pagesDb.insert(this.data); + const insertedRow = await pagesDb.insert(this.data) as { _id: string }; this._id = insertedRow._id; } else { @@ -176,7 +176,7 @@ class Page { * * @returns {Promise} */ - async destroy() { + public async destroy(): Promise { await pagesDb.remove({ _id: this._id }); delete this._id; @@ -184,13 +184,22 @@ class Page { return this; } + /** + * Return readable page data + * + * @returns {PageData} + */ + public toJSON(): PageData { + return this.data; + } + /** * Find and return available uri * * @returns {Promise} - * @param uri + * @param uri - input uri to be composed */ - async composeUri(uri) { + private async composeUri(uri: string): Promise { let pageWithSameUriCount = 0; if (!this._id) { @@ -210,13 +219,28 @@ class Page { } /** - * Return readable page data + * Extract first header from editor data * - * @returns {PageData} + * @returns {string} */ - toJSON() { - return this.data; + private extractTitleFromBody(): string { + const headerBlock = this.body ? this.body.blocks.find((block: Record) => block.type === 'header') : ''; + + return headerBlock ? headerBlock.data.text : ''; + } + + /** + * Transform title for uri + * + * @returns {string} + */ + private transformTitleToUri(): string { + if (this.title === undefined) { + return ''; + } + + return urlify(this.title); } } -module.exports = Page; +export default Page; diff --git a/src/models/pageOrder.js b/src/backend/models/pageOrder.ts similarity index 58% rename from src/models/pageOrder.js rename to src/backend/models/pageOrder.ts index dd8f7c8..761fc6a 100644 --- a/src/models/pageOrder.js +++ b/src/backend/models/pageOrder.ts @@ -1,4 +1,6 @@ -const { pagesOrder: db } = require('../utils/database/index'); +import database from '../utils/database/index'; + +const db = database['pagesOrder']; /** * @typedef {object} PageOrderData @@ -6,6 +8,11 @@ const { pagesOrder: db } = require('../utils/database/index'); * @property {string} page - page id * @property {Array} order - list of ordered pages */ +export interface PageOrderData { + _id?: string; + page?: string; + order?: string[]; +} /** * @class PageOrder @@ -14,44 +21,17 @@ const { pagesOrder: db } = require('../utils/database/index'); * Creates order for Pages with children */ class PageOrder { - /** - * Returns current Page's children order - * - * @param {string} pageId - page's id - * @returns {PageOrder} - */ - static async get(pageId) { - const order = await db.findOne({ page: pageId }); + public _id?: string; + public page?: string; + private _order?: string[]; - let data = {}; - - if (!order) { - data.page = pageId; - } else { - data = order; - } - - return new PageOrder(data); - } - - /** - * Find all pages which match passed query object - * - * @param {object} query - * @returns {Promise} - */ - static async getAll(query = {}) { - const docs = await db.find(query); - - return Promise.all(docs.map(doc => new PageOrder(doc))); - } /** * @class * - * @param {PageOrderData} data + * @param {PageOrderData} data - info about pageOrder */ - constructor(data = {}) { + constructor(data: PageOrderData = {}) { if (data === null) { data = {}; } @@ -63,14 +43,46 @@ class PageOrder { this.data = data; } + /** + * Returns current Page's children order + * + * @param {string} pageId - page's id + * @returns {Promise} + */ + public static async get(pageId: string): Promise { + const order = await db.findOne({ page: pageId }); + + let data: PageOrderData = {}; + + if (order === null) { + data.page = pageId; + } else { + data = order; + } + + return new PageOrder(data); + } + + /** + * Find all pages which match passed query object + * + * @param {object} query - input query + * @returns {Promise} + */ + public static async getAll(query: Record = {}): Promise { + const docs = await db.find(query); + + return Promise.all(docs.map(doc => new PageOrder(doc))); + } + /** * constructor data setter * - * @param {PageOrderData} pageOrderData + * @param {PageOrderData} pageOrderData - info about pageOrder */ - set data(pageOrderData) { - this._page = pageOrderData.page || 0; - this._order = pageOrderData.order || []; + public set data(pageOrderData: PageOrderData) { + this.page = pageOrderData.page || '0'; + this.order = pageOrderData.order || []; } /** @@ -78,11 +90,11 @@ class PageOrder { * * @returns {PageOrderData} */ - get data() { + public get data(): PageOrderData { return { _id: this._id, - page: '' + this._page, - order: this._order, + page: '' + this.page, + order: this.order, }; } @@ -91,9 +103,12 @@ class PageOrder { * * @param {string} pageId - page's id */ - push(pageId) { + public push(pageId: string | number): void { if (typeof pageId === 'string') { - this._order.push(pageId); + if (this.order === undefined) { + this.order = []; + } + this.order.push(pageId); } else { throw new Error('given id is not string'); } @@ -104,11 +119,15 @@ class PageOrder { * * @param {string} pageId - page's id */ - remove(pageId) { - const found = this._order.indexOf(pageId); + public remove(pageId: string): void { + if (this.order === undefined) { + return; + } + + const found = this.order.indexOf(pageId); if (found >= 0) { - this._order.splice(found, 1); + this.order.splice(found, 1); } } @@ -116,9 +135,13 @@ class PageOrder { * @param {string} currentPageId - page's id that changes the order * @param {string} putAbovePageId - page's id above which we put the target page * - * @returns void + * @returns {void} */ - putAbove(currentPageId, putAbovePageId) { + public putAbove(currentPageId: string, putAbovePageId: string): void { + if (this.order === undefined) { + return; + } + const found1 = this.order.indexOf(putAbovePageId); const found2 = this.order.indexOf(currentPageId); @@ -135,16 +158,20 @@ class PageOrder { /** * Returns page before passed page with id * - * @param {string} pageId + * @param {string} pageId - identity of page */ - getPageBefore(pageId) { + public getPageBefore(pageId: string): string | null { + if (this.order === undefined) { + return null; + } + const currentPageInOrder = this.order.indexOf(pageId); /** * If page not found or first return nothing */ if (currentPageInOrder <= 0) { - return; + return null; } return this.order[currentPageInOrder - 1]; @@ -153,16 +180,20 @@ class PageOrder { /** * Returns page before passed page with id * - * @param pageId + * @param pageId - identity of page */ - getPageAfter(pageId) { + public getPageAfter(pageId: string): string | null { + if (this.order === undefined) { + return null; + } + const currentPageInOrder = this.order.indexOf(pageId); /** * If page not found or is last */ if (currentPageInOrder === -1 || currentPageInOrder === this.order.length - 1) { - return; + return null; } return this.order[currentPageInOrder + 1]; @@ -171,7 +202,7 @@ class PageOrder { /** * @param {string[]} order - define new order */ - set order(order) { + public set order(order: string[]) { this._order = order; } @@ -180,16 +211,18 @@ class PageOrder { * * @returns {string[]} */ - get order() { - return this._order; + public get order(): string[] { + return this._order || []; } /** * Save or update page data in the database + * + * @returns {Promise} */ - async save() { + public async save(): Promise { if (!this._id) { - const insertedRow = await db.insert(this.data); + const insertedRow = await db.insert(this.data) as { _id: string}; this._id = insertedRow._id; } else { @@ -201,14 +234,14 @@ class PageOrder { /** * Remove page data from the database + * + * @returns {Promise} */ - async destroy() { + public async destroy(): Promise { await db.remove({ _id: this._id }); delete this._id; - - return this; } } -module.exports = PageOrder; +export default PageOrder; diff --git a/src/backend/models/user.ts b/src/backend/models/user.ts new file mode 100644 index 0000000..0d382bb --- /dev/null +++ b/src/backend/models/user.ts @@ -0,0 +1,40 @@ +import database from '../utils/database/index'; + +const db = database['password']; + +export interface UserData { + passHash?: string; +} + +/** + * @class User + * @class User model + * + * @property {string} passHash - hashed password + */ +class User { + public passHash?: string; + + /** + * @class + * + * @param {UserData} userData - user data for construct new object + */ + constructor(userData: UserData) { + this.passHash = userData.passHash; + } + + /** + * Find and return model of user. + * User is only one. + * + * @returns {Promise} + */ + public static async get(): Promise { + const userData: UserData = await db.findOne({}); + + return new User(userData); + } +} + +export default User; diff --git a/src/routes/aliases.js b/src/backend/routes/aliases.ts similarity index 59% rename from src/routes/aliases.js rename to src/backend/routes/aliases.ts index d7f467f..1dc2195 100644 --- a/src/routes/aliases.js +++ b/src/backend/routes/aliases.ts @@ -1,16 +1,17 @@ -const express = require('express'); +import express, { Request, Response } from 'express'; +import Aliases from '../controllers/aliases'; +import Pages from '../controllers/pages'; +import Alias from '../models/alias'; +import verifyToken from './middlewares/token'; + const router = express.Router(); -const Aliases = require('../controllers/aliases'); -const Pages = require('../controllers/pages'); -const Alias = require('../models/alias'); -const verifyToken = require('./middlewares/token'); /** * GET /* * * Return document with given alias */ -router.get('*', verifyToken, async (req, res) => { +router.get('*', verifyToken, async (req: Request, res: Response) => { try { let url = req.originalUrl.slice(1); // Cuts first '/' character const queryParamsIndex = url.indexOf('?'); @@ -21,11 +22,15 @@ router.get('*', verifyToken, async (req, res) => { const alias = await Aliases.get(url); + if (alias.id === undefined) { + throw new Error('Alias not found'); + } + switch (alias.type) { case Alias.types.PAGE: { const page = await Pages.get(alias.id); - const pageParent = await page.parent; + const pageParent = await page.getParent(); res.render('pages/page', { page, @@ -37,9 +42,9 @@ router.get('*', verifyToken, async (req, res) => { } catch (err) { res.status(400).json({ success: false, - error: err.message, + error: err, }); } }); -module.exports = router; +export default router; diff --git a/src/backend/routes/api/index.ts b/src/backend/routes/api/index.ts new file mode 100644 index 0000000..be225d8 --- /dev/null +++ b/src/backend/routes/api/index.ts @@ -0,0 +1,12 @@ +import express from 'express'; +import pagesAPI from './pages'; +import transportAPI from './transport'; +import linksAPI from './links'; + +const router = express.Router(); + +router.use('/', pagesAPI); +router.use('/', transportAPI); +router.use('/', linksAPI); + +export default router; diff --git a/src/backend/routes/api/links.ts b/src/backend/routes/api/links.ts new file mode 100644 index 0000000..63fb06e --- /dev/null +++ b/src/backend/routes/api/links.ts @@ -0,0 +1,62 @@ +import express, { Request, Response } from 'express'; +import ogs from 'open-graph-scraper'; + +const router = express.Router(); + +interface ResponseData { + success: number; + meta?: { + title: string | undefined; + description: string | undefined; + siteName: string | undefined; + image: { url: string | undefined } + } +} + +/** + * Accept file url to fetch + */ +router.get('/fetchUrl', async (req: Request, res: Response) => { + const response: ResponseData = { + success: 0, + }; + + if (!req.query.url) { + res.status(400).json(response); + + return; + } + + if (typeof req.query.url !== 'string') { + return; + } + + try { + const linkData = (await ogs({ url: req.query.url })).result; + + if (!linkData.success) { + return; + } + + response.success = 1; + response.meta = { + title: linkData.ogTitle, + description: linkData.ogDescription, + siteName: linkData.ogSiteName, + image: { + url: undefined, + }, + }; + + if (linkData.ogImage !== undefined) { + response.meta.image = { url: linkData.ogImage.toString() }; + } + + res.status(200).json(response); + } catch (e) { + console.log(e); + res.status(500).json(response); + } +}); + +export default router; diff --git a/src/routes/api/pages.js b/src/backend/routes/api/pages.ts similarity index 59% rename from src/routes/api/pages.js rename to src/backend/routes/api/pages.ts index 8934ca9..ba240b7 100644 --- a/src/routes/api/pages.js +++ b/src/backend/routes/api/pages.ts @@ -1,8 +1,10 @@ -const express = require('express'); +import express, { Request, Response } from 'express'; +import multerFunc from 'multer'; +import Pages from '../../controllers/pages'; +import PagesOrder from '../../controllers/pagesOrder'; + const router = express.Router(); -const multer = require('multer')(); -const Pages = require('../../controllers/pages'); -const PagesOrder = require('../../controllers/pagesOrder'); +const multer = multerFunc(); /** * GET /page/:id @@ -10,18 +12,18 @@ const PagesOrder = require('../../controllers/pagesOrder'); * Return PageData of page with given id */ -router.get('/page/:id', async (req, res) => { +router.get('/page/:id', async (req: Request, res: Response) => { try { const page = await Pages.get(req.params.id); res.json({ success: true, - result: page.data + result: page.data, }); } catch (err) { res.status(400).json({ success: false, - error: err.message + error: (err as Error).message, }); } }); @@ -31,18 +33,18 @@ router.get('/page/:id', async (req, res) => { * * Return PageData for all pages */ -router.get('/pages', async (req, res) => { +router.get('/pages', async (req: Request, res: Response) => { try { const pages = await Pages.getAll(); res.json({ success: true, - result: pages + result: pages, }); } catch (err) { res.status(400).json({ success: false, - error: err.message + error: (err as Error).message, }); } }); @@ -52,22 +54,30 @@ router.get('/pages', async (req, res) => { * * Create new page in the database */ -router.put('/page', multer.none(), async (req, res) => { +router.put('/page', multer.none(), async (req: Request, res: Response) => { try { const { title, body, parent } = req.body; - const page = await Pages.insert({ title, body, parent }); + const page = await Pages.insert({ + title, + body, + parent, + }); + + if (page._id === undefined) { + throw new Error('Page not found'); + } /** push to the orders array */ await PagesOrder.push(parent, page._id); res.json({ success: true, - result: page + result: page, }); } catch (err) { res.status(400).json({ success: false, - error: err.message + error: (err as Error).message, }); } }); @@ -77,7 +87,7 @@ router.put('/page', multer.none(), async (req, res) => { * * Update page data in the database */ -router.post('/page/:id', multer.none(), async (req, res) => { +router.post('/page/:id', multer.none(), async (req: Request, res: Response) => { const { id } = req.params; try { @@ -85,25 +95,46 @@ router.post('/page/:id', multer.none(), async (req, res) => { const pages = await Pages.getAll(); let page = await Pages.get(id); + if (page._id === undefined) { + throw new Error('Page not found'); + } + + if (!page._parent) { + throw new Error('Parent not found'); + } + if (page._parent !== parent) { await PagesOrder.move(page._parent, parent, id); } else { if (putAbovePageId && putAbovePageId !== '0') { const unordered = pages.filter(_page => _page._parent === page._parent).map(_page => _page._id); - await PagesOrder.update(unordered, page._id, page._parent, putAbovePageId); + const unOrdered: string[] = []; + + unordered.forEach(item => { + if (typeof item === 'string') { + unOrdered.push(item); + } + }); + + await PagesOrder.update(unOrdered, page._id, page._parent, putAbovePageId); } } - page = await Pages.update(id, { title, body, parent, uri }); + page = await Pages.update(id, { + title, + body, + parent, + uri, + }); res.json({ success: true, - result: page + result: page, }); } catch (err) { res.status(400).json({ success: false, - error: err.message + error: (err as Error).message, }); } }); @@ -113,10 +144,19 @@ router.post('/page/:id', multer.none(), async (req, res) => { * * Remove page from the database */ -router.delete('/page/:id', async (req, res) => { +router.delete('/page/:id', async (req: Request, res: Response) => { try { const pageId = req.params.id; const page = await Pages.get(pageId); + + if (page._id === undefined) { + throw new Error('Page not found'); + } + + if (!page._parent) { + throw new Error('Parent not found'); + } + const parentPageOrder = await PagesOrder.get(page._parent); const pageBeforeId = parentPageOrder.getPageBefore(page._id); const pageAfterId = parentPageOrder.getPageAfter(page._id); @@ -134,17 +174,19 @@ router.delete('/page/:id', async (req, res) => { /** * remove current page and go deeper to remove children with orders * - * @param startFrom + * @param {string} startFrom - start point to delete * @returns {Promise} */ - const deleteRecursively = async (startFrom) => { - let order = []; + const deleteRecursively = async (startFrom: string): Promise => { + let order: string[] = []; try { const children = await PagesOrder.get(startFrom); order = children.order; - } catch (e) {} + } catch (e) { + order = []; + } order.forEach(async id => { await deleteRecursively(id); @@ -153,7 +195,9 @@ router.delete('/page/:id', async (req, res) => { await Pages.remove(startFrom); try { await PagesOrder.remove(startFrom); - } catch (e) {} + } catch (e) { + order = []; + } }; await deleteRecursively(req.params.id); @@ -164,14 +208,14 @@ router.delete('/page/:id', async (req, res) => { res.json({ success: true, - result: pageToRedirect + result: pageToRedirect, }); } catch (err) { res.status(400).json({ success: false, - error: err.message + error: (err as Error).message, }); } }); -module.exports = router; +export default router; diff --git a/src/routes/api/transport.js b/src/backend/routes/api/transport.ts similarity index 56% rename from src/routes/api/transport.js rename to src/backend/routes/api/transport.ts index 16139c9..15219e0 100644 --- a/src/routes/api/transport.js +++ b/src/backend/routes/api/transport.ts @@ -1,59 +1,79 @@ -const express = require('express'); -const router = express.Router(); -const multer = require('multer'); -const mime = require('mime'); -const mkdirp = require('mkdirp'); -const Transport = require('../../controllers/transport'); -const { random16 } = require('../../utils/crypto'); -const config = require('../../../config'); +import { Request, Response, Router } from 'express'; +import multer, { StorageEngine } from 'multer'; +import mime from 'mime'; +import mkdirp from 'mkdirp'; +import config from 'config'; +import Transport from '../../controllers/transport'; +import { random16 } from '../../utils/crypto'; + +const router = Router(); /** * Multer storage for uploaded files and images - * @type {DiskStorage|DiskStorage} + * + * @type {StorageEngine} */ -const storage = multer.diskStorage({ +const storage: StorageEngine = multer.diskStorage({ destination: (req, file, cb) => { - const dir = config.uploads || 'public/uploads'; + const dir: string = config.get('uploads') || 'public/uploads'; - mkdirp(dir, err => cb(err, dir)); + mkdirp(dir); + cb(null, dir); }, filename: async (req, file, cb) => { const filename = await random16(); cb(null, `${filename}.${mime.getExtension(file.mimetype)}`); - } + }, }); /** * Multer middleware for image uploading */ const imageUploader = multer({ - storage, + storage: storage, fileFilter: (req, file, cb) => { if (!/image/.test(file.mimetype) && !/video\/mp4/.test(file.mimetype)) { cb(null, false); + return; } cb(null, true); - } -}).fields([ { name: 'image', maxCount: 1 } ]); + }, +}).fields([ { + name: 'image', + maxCount: 1, +} ]); /** * Multer middleware for file uploading */ const fileUploader = multer({ - storage -}).fields([ { name: 'file', maxCount: 1 } ]); + storage: storage, +}).fields([ { + name: 'file', + maxCount: 1, +} ]); /** * Accepts images to upload */ -router.post('/transport/image', imageUploader, async (req, res) => { - let response = { success: 0 }; +router.post('/transport/image', imageUploader, async (req: Request, res: Response) => { + const response = { + success: 0, + message: '', + }; - if (!req.files || !req.files.image) { + if (req.files === undefined) { + response.message = 'No files found'; res.status(400).json(response); + + return; + } + if (!('image' in req.files)) { + res.status(400).json(response); + return; } @@ -73,11 +93,17 @@ router.post('/transport/image', imageUploader, async (req, res) => { /** * Accepts files to upload */ -router.post('/transport/file', fileUploader, async (req, res) => { - let response = { success: 0 }; +router.post('/transport/file', fileUploader, async (req: Request, res: Response) => { + const response = { success: 0 }; - if (!req.files || !req.files.file) { + if (req.files === undefined) { res.status(400).json(response); + + return; + } + if (!('file' in req.files)) { + res.status(400).json(response); + return; } @@ -97,11 +123,12 @@ router.post('/transport/file', fileUploader, async (req, res) => { /** * Accept file url to fetch */ -router.post('/transport/fetch', multer().none(), async (req, res) => { - let response = { success: 0 }; +router.post('/transport/fetch', multer().none(), async (req: Request, res: Response) => { + const response = { success: 0 }; if (!req.body.url) { res.status(400).json(response); + return; } @@ -116,4 +143,4 @@ router.post('/transport/fetch', multer().none(), async (req, res) => { } }); -module.exports = router; +export default router; diff --git a/src/backend/routes/auth.ts b/src/backend/routes/auth.ts new file mode 100644 index 0000000..0f0065e --- /dev/null +++ b/src/backend/routes/auth.ts @@ -0,0 +1,78 @@ +import express, { Request, Response } from 'express'; +import jwt from 'jsonwebtoken'; +import config from 'config'; +import bcrypt from 'bcrypt'; +import csrf from 'csurf'; +import * as dotenv from 'dotenv'; +import Users from '../controllers/users'; + +dotenv.config(); + +const router = express.Router(); +const csrfProtection = csrf({ cookie: true }); +const parseForm = express.urlencoded({ extended: false }); + +/** + * Authorization page + */ +router.get('/auth', csrfProtection, function (req: Request, res: Response) { + res.render('auth', { + title: 'Login page', + csrfToken: req.csrfToken(), + }); +}); + +/** + * Process given password + */ +router.post('/auth', parseForm, csrfProtection, async (req: Request, res: Response) => { + try { + const userDoc = await Users.get(); + const passHash = userDoc.passHash; + + if (!passHash) { + res.render('auth', { + title: 'Login page', + header: 'Password not set', + csrfToken: req.csrfToken(), + }); + + return; + } + + bcrypt.compare(req.body.password, passHash, async (err, result) => { + if (err || result === false) { + res.render('auth', { + title: 'Login page', + header: 'Wrong password', + csrfToken: req.csrfToken(), + }); + + return; + } + + const token = jwt.sign({ + iss: 'Codex Team', + sub: 'auth', + iat: Date.now(), + }, passHash + config.get('secret')); + + res.cookie('authToken', token, { + httpOnly: true, + expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year + }); + + res.redirect('/'); + }); + } catch (err) { + res.render('auth', { + title: 'Login page', + header: 'Password not set', + csrfToken: req.csrfToken(), + }); + + return; + } +}); + +export default router; diff --git a/src/routes/home.js b/src/backend/routes/home.ts similarity index 55% rename from src/routes/home.js rename to src/backend/routes/home.ts index b1963de..ffe0148 100644 --- a/src/routes/home.js +++ b/src/backend/routes/home.ts @@ -1,9 +1,10 @@ -const express = require('express'); -const verifyToken = require('./middlewares/token'); +import express, { Request, Response } from 'express'; +import verifyToken from './middlewares/token'; + const router = express.Router(); /* GET home page. */ -router.get('/', verifyToken, async (req, res) => { +router.get('/', verifyToken, async (req: Request, res: Response) => { const config = req.app.locals.config; if (config.startPage) { @@ -12,4 +13,4 @@ router.get('/', verifyToken, async (req, res) => { res.render('pages/index', { isAuthorized: res.locals.isAuthorized }); }); -module.exports = router; +export default router; diff --git a/src/backend/routes/index.ts b/src/backend/routes/index.ts new file mode 100644 index 0000000..2057c44 --- /dev/null +++ b/src/backend/routes/index.ts @@ -0,0 +1,17 @@ +import express from 'express'; +import home from './home'; +import pages from './pages'; +import auth from './auth'; +import aliases from './aliases'; +import api from './api'; +import pagesMiddleware from './middlewares/pages'; + +const router = express.Router(); + +router.use('/', pagesMiddleware, home); +router.use('/', pagesMiddleware, pages); +router.use('/', pagesMiddleware, auth); +router.use('/api', api); +router.use('/', aliases); + +export default router; diff --git a/src/backend/routes/middlewares/locals.ts b/src/backend/routes/middlewares/locals.ts new file mode 100644 index 0000000..91a119e --- /dev/null +++ b/src/backend/routes/middlewares/locals.ts @@ -0,0 +1,16 @@ +import { NextFunction, Request, Response } from 'express'; + +/** + * Middleware for checking locals.isAuthorized property, which allows to edit/create pages + * + * @param req - request object + * @param res - response object + * @param next - next function + */ +export default function allowEdit(req: Request, res: Response, next: NextFunction): void { + if (res.locals.isAuthorized) { + next(); + } else { + res.redirect('/auth'); + } +} diff --git a/src/routes/middlewares/pages.js b/src/backend/routes/middlewares/pages.ts similarity index 61% rename from src/routes/middlewares/pages.js rename to src/backend/routes/middlewares/pages.ts index 21386bb..523b7cc 100644 --- a/src/routes/middlewares/pages.js +++ b/src/backend/routes/middlewares/pages.ts @@ -1,6 +1,9 @@ -const Pages = require('../../controllers/pages'); -const PagesOrder = require('../../controllers/pagesOrder'); -const asyncMiddleware = require('../../utils/asyncMiddleware'); +import { NextFunction, Request, Response } from 'express'; +import Pages from '../../controllers/pages'; +import PagesOrder from '../../controllers/pagesOrder'; +import Page from '../../models/page'; +import asyncMiddleware from '../../utils/asyncMiddleware'; +import PageOrder from '../../models/pageOrder'; /** * Process one-level pages list to parent-children list @@ -8,12 +11,12 @@ const asyncMiddleware = require('../../utils/asyncMiddleware'); * @param {string} parentPageId - parent page id * @param {Page[]} pages - list of all available pages * @param {PagesOrder[]} pagesOrder - list of pages order - * @param {number} level - * @param {number} currentLevel + * @param {number} level - max level recursion + * @param {number} currentLevel - current level of element * - * @return {Page[]} + * @returns {Page[]} */ -function createMenuTree(parentPageId, pages, pagesOrder, level = 1, currentLevel = 1) { +function createMenuTree(parentPageId: string, pages: Page[], pagesOrder: PageOrder[], level = 1, currentLevel = 1): Page[] { const childrenOrder = pagesOrder.find(order => order.data.page === parentPageId); /** @@ -21,16 +24,16 @@ function createMenuTree(parentPageId, pages, pagesOrder, level = 1, currentLevel * if we got some children order on parents tree, then we push found pages in order sequence * otherwise just find all pages includes parent tree */ - let ordered = []; + let ordered: any[] = []; if (childrenOrder) { - ordered = childrenOrder.order.map(pageId => { + ordered = childrenOrder.order.map((pageId: string) => { return pages.find(page => page._id === pageId); }); } const unordered = pages.filter(page => page._parent === parentPageId); - const branch = [ ...new Set([...ordered, ...unordered]) ]; + const branch = Array.from(new Set([...ordered, ...unordered])); /** * stop recursion when we got the passed max level @@ -44,20 +47,22 @@ function createMenuTree(parentPageId, pages, pagesOrder, level = 1, currentLevel */ return branch.filter(page => page && page._id).map(page => { return Object.assign({ - children: createMenuTree(page._id, pages, pagesOrder, level, currentLevel + 1) + children: createMenuTree(page._id, pages, pagesOrder, level, currentLevel + 1), }, page.data); }); } /** * Middleware for all /page/... routes - * @param req - * @param res - * @param next + * + * @param {Request} req + * @param {Response} res + * @param {NextFunction} next */ -module.exports = asyncMiddleware(async (req, res, next) => { +export default asyncMiddleware(async (req: Request, res: Response, next: NextFunction) => { /** * Pages without parent + * * @type {string} */ const parentIdOfRootPages = '0'; diff --git a/src/backend/routes/middlewares/token.ts b/src/backend/routes/middlewares/token.ts new file mode 100644 index 0000000..2289be1 --- /dev/null +++ b/src/backend/routes/middlewares/token.ts @@ -0,0 +1,38 @@ +import * as dotenv from 'dotenv'; +import config from 'config'; +import { NextFunction, Request, Response } from 'express'; +import jwt from 'jsonwebtoken'; +import Users from '../../controllers/users'; + +dotenv.config(); + +/** + * Middleware for checking jwt token + * + * @param req - request object + * @param res - response object + * @param next - next function + */ +export default async function verifyToken(req: Request, res: Response, next: NextFunction): Promise { + const token = req.cookies.authToken; + + try { + const userDoc = await Users.get(); + + if (!userDoc.passHash) { + res.locals.isAuthorized = false; + next(); + + return; + } + + const decodedToken = jwt.verify(token, userDoc.passHash + config.get('secret')); + + res.locals.isAuthorized = !!decodedToken; + + next(); + } catch (err) { + res.locals.isAuthorized = false; + next(); + } +} diff --git a/src/backend/routes/pages.ts b/src/backend/routes/pages.ts new file mode 100644 index 0000000..82c8107 --- /dev/null +++ b/src/backend/routes/pages.ts @@ -0,0 +1,75 @@ +import express, { NextFunction, Request, Response } from 'express'; +import Pages from '../controllers/pages'; +import PagesOrder from '../controllers/pagesOrder'; +import verifyToken from './middlewares/token'; +import allowEdit from './middlewares/locals'; + +const router = express.Router(); + +/** + * Create new page form + */ +router.get('/page/new', verifyToken, allowEdit, async (req: Request, res: Response, next: NextFunction) => { + try { + const pagesAvailable = await Pages.getAll(); + + res.render('pages/form', { + pagesAvailable, + page: null, + }); + } catch (error) { + res.status(404); + next(error); + } +}); + +/** + * Edit page form + */ +router.get('/page/edit/:id', verifyToken, allowEdit, async (req: Request, res: Response, next: NextFunction) => { + const pageId = req.params.id; + + try { + const page = await Pages.get(pageId); + const pagesAvailable = await Pages.getAllExceptChildren(pageId); + + if (!page._parent) { + throw new Error('Parent not found'); + } + + const parentsChildrenOrdered = await PagesOrder.getOrderedChildren(pagesAvailable, pageId, page._parent, true); + + res.render('pages/form', { + page, + parentsChildrenOrdered, + pagesAvailable, + }); + } catch (error) { + res.status(404); + next(error); + } +}); + +/** + * View page + */ +router.get('/page/:id', verifyToken, async (req: Request, res: Response, next: NextFunction) => { + const pageId = req.params.id; + + try { + const page = await Pages.get(pageId); + + const pageParent = await page.parent; + + res.render('pages/page', { + page, + pageParent, + config: req.app.locals.config, + }); + } catch (error) { + res.status(404); + next(error); + } +}); + +export default router; diff --git a/src/backend/utils/asyncMiddleware.ts b/src/backend/utils/asyncMiddleware.ts new file mode 100644 index 0000000..65fdda4 --- /dev/null +++ b/src/backend/utils/asyncMiddleware.ts @@ -0,0 +1,18 @@ +import { NextFunction, Request, Response } from 'express'; + +interface InputFunction { + (req: Request, res: Response, next: NextFunction): void; +} + +/** + * Helper for making async middlewares for express router + * + * @param {Function} fn - input function + * @returns {function(*=, *=, *=)} + */ +export default function asyncMiddleware(fn: InputFunction): (req: Request, res: Response, next: NextFunction) => void { + return (req: Request, res: Response, next: NextFunction) => { + Promise.resolve(fn(req, res, next)) + .catch(next); + }; +} diff --git a/src/utils/crypto.js b/src/backend/utils/crypto.ts similarity index 50% rename from src/utils/crypto.js rename to src/backend/utils/crypto.ts index 0d23ccc..39b60c6 100644 --- a/src/utils/crypto.js +++ b/src/backend/utils/crypto.ts @@ -1,4 +1,14 @@ -const crypto = require('crypto'); +import crypto from 'crypto'; + +/** + * + * @param {string} hexStr - input hex string + * @returns {string} - output binary string + */ +function hexToBinary(hexStr: string): string { + return (parseInt(hexStr, 16).toString(2)) + .padStart(8, '0'); +} /** * Create binary md5 @@ -6,10 +16,10 @@ const crypto = require('crypto'); * @param stringToHash - string to hash * @returns {string} - binary hash of argument */ -function binaryMD5(stringToHash) { - return crypto.createHash('md5') +export function binaryMD5(stringToHash: string): string { + return hexToBinary(crypto.createHash('md5') .update(stringToHash) - .digest('binary'); + .digest('hex')); } /** @@ -17,7 +27,7 @@ function binaryMD5(stringToHash) { * * @returns {Promise} */ -function random16() { +export function random16(): Promise { return new Promise((resolve, reject) => { crypto.randomBytes(16, (err, raw) => { if (err) { @@ -29,7 +39,7 @@ function random16() { }); } -module.exports = { +export default { binaryMD5, random16, }; diff --git a/src/utils/database/index.js b/src/backend/utils/database/index.ts similarity index 58% rename from src/utils/database/index.js rename to src/backend/utils/database/index.ts index 43913c4..f742172 100644 --- a/src/utils/database/index.js +++ b/src/backend/utils/database/index.ts @@ -1,33 +1,58 @@ -const pages = require('./pages'); -const files = require('./files'); -const password = require('./password'); -const aliases = require('./aliases'); -const pagesOrder = require('./pagesOrder'); +import Datastore from 'nedb'; +import { AliasData } from '../../models/alias'; +import { FileData } from '../../models/file'; +import { PageData } from '../../models/page'; +import { PageOrderData } from '../../models/pageOrder'; +import { UserData } from '../../models/user'; +import initDb from './initDb'; + +/** + * @typedef Options - optional params + * @param {boolean} multi - (false) allows to take action to several documents + * @param {boolean} upsert - (false) if true, upsert document with update fields. + * Method will return inserted doc or number of affected docs if doc hasn't been inserted + * @param {boolean} returnUpdatedDocs - (false) if true, returns affected docs + */ +interface Options { + multi?: boolean; + upsert?: boolean; + returnUpdatedDocs?: boolean; +} + +interface ResolveFunction { + (value: any): void; +} + +interface RejectFunction { + (reason?: unknown): void; +} /** * @class Database * @classdesc Simple decorator class to work with nedb datastore * - * @property db - nedb Datastore object + * @property {Datastore} db - nedb Datastore object */ -class Database { +export class Database { + private db: Datastore; /** - * @constructor + * @class * * @param {Object} nedbInstance - nedb Datastore object */ - constructor(nedbInstance) { + constructor(nedbInstance: Datastore) { this.db = nedbInstance; } /** * Insert new document into the database + * * @see https://github.com/louischatriot/nedb#inserting-documents * * @param {Object} doc - object to insert * @returns {Promise} - inserted doc or Error object */ - async insert(doc) { + public async insert(doc: DocType): Promise { return new Promise((resolve, reject) => this.db.insert(doc, (err, newDoc) => { if (err) { reject(err); @@ -39,14 +64,15 @@ class Database { /** * Find documents that match passed query + * * @see https://github.com/louischatriot/nedb#finding-documents * * @param {Object} query - query object * @param {Object} projection - projection object * @returns {Promise|Error>} - found docs or Error object */ - async find(query, projection) { - const cbk = (resolve, reject) => (err, docs) => { + public async find(query: Record, projection?: DocType): Promise> { + const cbk = (resolve: ResolveFunction, reject: RejectFunction) => (err: Error | null, docs: DocType[]) => { if (err) { reject(err); } @@ -65,14 +91,15 @@ class Database { /** * Find one document matches passed query + * * @see https://github.com/louischatriot/nedb#finding-documents * * @param {Object} query - query object * @param {Object} projection - projection object * @returns {Promise} - found doc or Error object */ - async findOne(query, projection) { - const cbk = (resolve, reject) => (err, doc) => { + public async findOne(query: Record, projection?: DocType): Promise { + const cbk = (resolve: ResolveFunction, reject: RejectFunction) => (err: Error | null, doc: DocType) => { if (err) { reject(err); } @@ -91,18 +118,15 @@ class Database { /** * Update document matches query + * * @see https://github.com/louischatriot/nedb#updating-documents * * @param {Object} query - query object * @param {Object} update - fields to update - * @param {Object} options - * @param {Boolean} options.multi - (false) allows update several documents - * @param {Boolean} options.upsert - (false) if true, upsert document with update fields. - * Method will return inserted doc or number of affected docs if doc hasn't been inserted - * @param {Boolean} options.returnUpdatedDocs - (false) if true, returns affected docs + * @param {Options} options - optional params * @returns {Promise} - number of updated rows or affected docs or Error object */ - async update(query, update, options = {}) { + public async update(query: Record, update: DocType, options: Options = {}): Promise> { return new Promise((resolve, reject) => this.db.update(query, update, options, (err, result, affectedDocs) => { if (err) { reject(err); @@ -126,14 +150,14 @@ class Database { /** * Remove document matches passed query + * * @see https://github.com/louischatriot/nedb#removing-documents * * @param {Object} query - query object - * @param {Object} options - * @param {Boolean} options.multi - (false) if true, remove several docs + * @param {Options} options - optional params * @returns {Promise} - number of removed rows or Error object */ - async remove(query, options = {}) { + public async remove(query: Record, options: Options = {}): Promise { return new Promise((resolve, reject) => this.db.remove(query, options, (err, result) => { if (err) { reject(err); @@ -144,11 +168,10 @@ class Database { } } -module.exports = { - class: Database, - pages: new Database(pages), - password: new Database(password), - aliases: new Database(aliases), - pagesOrder: new Database(pagesOrder), - files: new Database(files) +export default { + pages: new Database(initDb('pages')), + password: new Database(initDb('password')), + aliases: new Database(initDb('aliases')), + pagesOrder: new Database(initDb('pagesOrder')), + files: new Database(initDb('files')), }; diff --git a/src/backend/utils/database/initDb.ts b/src/backend/utils/database/initDb.ts new file mode 100644 index 0000000..7475369 --- /dev/null +++ b/src/backend/utils/database/initDb.ts @@ -0,0 +1,16 @@ +import Datastore from 'nedb'; +import config from 'config'; +import path from 'path'; + +/** + * Init function for nedb instance + * + * @param {string} name - name of the data file + * @returns {Datastore} db - nedb instance + */ +export default function initDb(name: string): Datastore { + return new Datastore({ + filename: path.resolve(`./${config.get('database')}/${name}.db`), + autoload: true, + }); +} \ No newline at end of file diff --git a/src/utils/objects.js b/src/backend/utils/objects.ts similarity index 62% rename from src/utils/objects.js rename to src/backend/utils/objects.ts index c297a37..7eb5d06 100644 --- a/src/utils/objects.js +++ b/src/backend/utils/objects.ts @@ -5,8 +5,13 @@ * @param {object[]} sources * @returns {object} */ -function deepMerge(target, ...sources) { - const isObject = item => item && typeof item === 'object' && !Array.isArray(item); + +/** + * @param {Record} target - target to merge into + * @param {...any[]} sources - sources to merge from + */ +function deepMerge(target: Record, ...sources: any[]): Record { + const isObject = (item: unknown): boolean => !!item && typeof item === 'object' && !Array.isArray(item); if (!sources.length) { return target; @@ -30,6 +35,4 @@ function deepMerge(target, ...sources) { return deepMerge(target, ...sources); } -module.exports = { - deepMerge, -}; +export default deepMerge; diff --git a/src/utils/rcparser.js b/src/backend/utils/rcparser.ts similarity index 71% rename from src/utils/rcparser.js rename to src/backend/utils/rcparser.ts index d995075..85a274d 100644 --- a/src/utils/rcparser.js +++ b/src/backend/utils/rcparser.ts @@ -1,28 +1,43 @@ -const fs = require('fs'); -const path = require('path'); -const config = require('../../config'); -const rcPath = path.resolve(__dirname, '../../', config.rcFile || './.codexdocsrc'); +import fs from 'fs'; +import path from 'path'; +import config from 'config'; + +const rcPath = path.resolve(__dirname, '../../../', config.get('rcFile') || './.codexdocsrc'); + +/** + * @typedef {object} menu + * @property {string} title - menu option title + * @property {string} uri - menu option href + */ +interface Menu { + title: string; + uri: string; + [key: string]: string; +} /** * @typedef {object} RCData * @property {string} title - website title - * @property {object[]} menu - options for website menu - * @property {string} menu[].title - menu option title - * @property {string} menu[].uri - menu option href + * @property {Menu[]} menu - options for website menu */ +interface RCData { + title: string; + menu: Menu[]; + [key: string]: string | Menu[]; +} /** * @class RCParser * @classdesc Class to parse runtime configuration file for CodeX Docs engine */ -module.exports = class RCParser { +export default class RCParser { /** * Default CodeX Docs configuration * * @static * @returns {{title: string, menu: Array}} */ - static get DEFAULTS() { + public static get DEFAULTS():RCData { return { title: 'CodeX Docs', menu: [], @@ -35,12 +50,12 @@ module.exports = class RCParser { * @static * @returns {{title: string, menu: []}} */ - static getConfiguration() { + public static getConfiguration(): RCData { if (!fs.existsSync(rcPath)) { return RCParser.DEFAULTS; } - const file = fs.readFileSync(rcPath, { encoding: 'UTF-8' }); + const file = fs.readFileSync(rcPath, 'utf-8'); const rConfig = RCParser.DEFAULTS; let userConfig; @@ -63,7 +78,7 @@ module.exports = class RCParser { rConfig.menu = RCParser.DEFAULTS.menu; } - rConfig.menu = rConfig.menu.filter((option, i) => { + rConfig.menu = rConfig.menu.filter((option: string | Menu, i:number) => { i = i + 1; if (typeof option === 'string') { return true; @@ -92,7 +107,7 @@ module.exports = class RCParser { return true; }); - rConfig.menu = rConfig.menu.map(option => { + rConfig.menu = rConfig.menu.map((option: string | Menu) => { if (typeof option === 'string') { return { title: option, @@ -106,4 +121,4 @@ module.exports = class RCParser { return rConfig; } -}; +} diff --git a/src/utils/translation.js b/src/backend/utils/translation.ts similarity index 78% rename from src/utils/translation.js rename to src/backend/utils/translation.ts index f1682a3..f7baee4 100644 --- a/src/utils/translation.js +++ b/src/backend/utils/translation.ts @@ -1,4 +1,7 @@ -const translationTable = { +interface TransTable { + [key: string]: string; +} +const translationTable: TransTable = { а: 'a', б: 'b', в: 'v', @@ -73,6 +76,10 @@ const translationTable = { * @returns {string} - translated string */ -module.exports = function translateString(string) { +/** + * @param {string} string - input text to be translated + * @returns {string} text - translated text + */ +export default function translateString(string: string): string { return string.replace(/[А-яёЁ]/g, (char) => translationTable[char] || char); -}; +} diff --git a/src/utils/twig.js b/src/backend/utils/twig.ts similarity index 53% rename from src/utils/twig.js rename to src/backend/utils/twig.ts index 2195d59..fa3ee6d 100644 --- a/src/utils/twig.js +++ b/src/backend/utils/twig.ts @@ -1,22 +1,22 @@ /** * Twig extensions */ -const twig = require('twig'); -const fs = require('fs'); -const urlify = require('./urlify'); +import twig from 'twig'; +import fs from 'fs'; +import urlify from './urlify'; -module.exports = (function () { +export default (function () { 'use strict'; /** * Function for include svg on page * * @example svg('path/from/root/dir') - * @param filename - name of icon + * @param {string} filename - name of icon * @returns {string} - svg code */ - twig.extendFunction('svg', function (filename) { - return fs.readFileSync(`${__dirname}/../frontend/svg/${filename}.svg`, 'utf-8'); + twig.extendFunction('svg', function (filename: string) { + return fs.readFileSync(`./src/frontend/svg/${filename}.svg`, 'utf-8'); }); /** @@ -26,7 +26,7 @@ module.exports = (function () { * @param {string} string - source string with HTML * @returns {string} alias-like string */ - twig.extendFilter('urlify', function (string) { + twig.extendFilter('urlify', function (string: string) { return urlify(string); }); @@ -34,13 +34,15 @@ module.exports = (function () { * Parse link as URL object * * @param {string} linkUrl - link to be processed - * @returns {UrlWithStringQuery} — url data + * @returns {string} url — url data */ - twig.extendFunction('parseLink', function (linkUrl) { + twig.extendFunction('parseLink', function (linkUrl: string): string { try { - return new URL(linkUrl); + return new URL(linkUrl).toString(); } catch (e) { console.log(e); + + return ''; } }); }()); diff --git a/src/utils/urlify.js b/src/backend/utils/urlify.ts similarity index 87% rename from src/utils/urlify.js rename to src/backend/utils/urlify.ts index bb08e20..9716a10 100644 --- a/src/utils/urlify.js +++ b/src/backend/utils/urlify.ts @@ -1,4 +1,4 @@ -const translateString = require('./translation'); +import translateString from './translation'; /** * Convert text to URL-like string @@ -7,7 +7,7 @@ const translateString = require('./translation'); * @param {string} string - source string with HTML * @returns {string} alias-like string */ -module.exports = function urlify(string) { +export default function urlify(string: string): string { // strip tags string = string.replace(/(<([^>]+)>)/ig, ''); @@ -30,4 +30,4 @@ module.exports = function urlify(string) { string = translateString(string); return string; -}; +} diff --git a/src/views/auth.twig b/src/backend/views/auth.twig similarity index 100% rename from src/views/auth.twig rename to src/backend/views/auth.twig diff --git a/src/views/components/aside.twig b/src/backend/views/components/aside.twig similarity index 100% rename from src/views/components/aside.twig rename to src/backend/views/components/aside.twig diff --git a/src/views/components/header.twig b/src/backend/views/components/header.twig similarity index 100% rename from src/views/components/header.twig rename to src/backend/views/components/header.twig diff --git a/src/views/error.twig b/src/backend/views/error.twig similarity index 100% rename from src/views/error.twig rename to src/backend/views/error.twig diff --git a/src/views/layout.twig b/src/backend/views/layout.twig similarity index 100% rename from src/views/layout.twig rename to src/backend/views/layout.twig diff --git a/src/views/pages/blocks/checklist.twig b/src/backend/views/pages/blocks/checklist.twig similarity index 100% rename from src/views/pages/blocks/checklist.twig rename to src/backend/views/pages/blocks/checklist.twig diff --git a/src/views/pages/blocks/code.twig b/src/backend/views/pages/blocks/code.twig similarity index 100% rename from src/views/pages/blocks/code.twig rename to src/backend/views/pages/blocks/code.twig diff --git a/src/views/pages/blocks/delimiter.twig b/src/backend/views/pages/blocks/delimiter.twig similarity index 100% rename from src/views/pages/blocks/delimiter.twig rename to src/backend/views/pages/blocks/delimiter.twig diff --git a/src/views/pages/blocks/embed.twig b/src/backend/views/pages/blocks/embed.twig similarity index 100% rename from src/views/pages/blocks/embed.twig rename to src/backend/views/pages/blocks/embed.twig diff --git a/src/views/pages/blocks/header.twig b/src/backend/views/pages/blocks/header.twig similarity index 100% rename from src/views/pages/blocks/header.twig rename to src/backend/views/pages/blocks/header.twig diff --git a/src/views/pages/blocks/image.twig b/src/backend/views/pages/blocks/image.twig similarity index 100% rename from src/views/pages/blocks/image.twig rename to src/backend/views/pages/blocks/image.twig diff --git a/src/views/pages/blocks/linkTool.twig b/src/backend/views/pages/blocks/linkTool.twig similarity index 100% rename from src/views/pages/blocks/linkTool.twig rename to src/backend/views/pages/blocks/linkTool.twig diff --git a/src/views/pages/blocks/list.twig b/src/backend/views/pages/blocks/list.twig similarity index 100% rename from src/views/pages/blocks/list.twig rename to src/backend/views/pages/blocks/list.twig diff --git a/src/views/pages/blocks/paragraph.twig b/src/backend/views/pages/blocks/paragraph.twig similarity index 100% rename from src/views/pages/blocks/paragraph.twig rename to src/backend/views/pages/blocks/paragraph.twig diff --git a/src/views/pages/blocks/raw.twig b/src/backend/views/pages/blocks/raw.twig similarity index 100% rename from src/views/pages/blocks/raw.twig rename to src/backend/views/pages/blocks/raw.twig diff --git a/src/views/pages/blocks/table.twig b/src/backend/views/pages/blocks/table.twig similarity index 100% rename from src/views/pages/blocks/table.twig rename to src/backend/views/pages/blocks/table.twig diff --git a/src/views/pages/blocks/warning.twig b/src/backend/views/pages/blocks/warning.twig similarity index 100% rename from src/views/pages/blocks/warning.twig rename to src/backend/views/pages/blocks/warning.twig diff --git a/src/views/pages/form.twig b/src/backend/views/pages/form.twig similarity index 100% rename from src/views/pages/form.twig rename to src/backend/views/pages/form.twig diff --git a/src/views/pages/index.twig b/src/backend/views/pages/index.twig similarity index 100% rename from src/views/pages/index.twig rename to src/backend/views/pages/index.twig diff --git a/src/views/pages/page.twig b/src/backend/views/pages/page.twig similarity index 100% rename from src/views/pages/page.twig rename to src/backend/views/pages/page.twig diff --git a/bin/nvm.sh b/src/bin/nvm.sh similarity index 100% rename from bin/nvm.sh rename to src/bin/nvm.sh diff --git a/bin/www b/src/bin/server.ts old mode 100755 new mode 100644 similarity index 65% rename from bin/www rename to src/bin/server.ts index ab2a467..5ea477b --- a/bin/www +++ b/src/bin/server.ts @@ -1,17 +1,17 @@ -#!/usr/bin/env node - /** * Module dependencies. */ -const app = require('../src/app'); -const debug = require('debug')('codex.editor.docs:server'); -const http = require('http'); -const config = require('../config'); +import app from '../backend/app'; +import http from 'http'; +import config from 'config'; +import Debug from 'debug'; + +const debug = Debug.debug('codex.editor.docs:server'); /** * Get port from environment and store in Express. */ -const port = normalizePort(config.port || '3000'); +const port = normalizePort(config.get('port') || '3000'); app.set('port', port); @@ -29,8 +29,9 @@ server.on('listening', onListening); /** * Normalize a port into a number, string, or false. + * @param val */ -function normalizePort(val) { +function normalizePort(val: string): number | string | false { const value = parseInt(val, 10); if (isNaN(value)) { @@ -47,9 +48,10 @@ function normalizePort(val) { } /** - * Event listener for HTTP server "error" event. + * Event listener for HTTP server 'error' event. + * @param error */ -function onError(error) { +function onError(error: NodeJS.ErrnoException): void { if (error.syscall !== 'listen') { throw error; } @@ -63,19 +65,27 @@ function onError(error) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); + break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); + break; default: throw error; } } /** - * Event listener for HTTP server "listening" event. + * Event listener for HTTP server 'listening' event. */ -function onListening() { +function onListening(): void { const addr = server.address(); + + if (addr === null) { + debug('Address not found'); + process.exit(1); + } + const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; @@ -83,4 +93,7 @@ function onListening() { debug('Listening on ' + bind); } -module.exports = {server, app}; +export default { + server, + app, +}; \ No newline at end of file diff --git a/src/controllers/users.js b/src/controllers/users.js deleted file mode 100644 index 676a26f..0000000 --- a/src/controllers/users.js +++ /dev/null @@ -1,20 +0,0 @@ -const Model = require('../models/user'); - -/** - * @class Users - * @classdesc Users controller - */ -class Users { - /** - * Find and return user model. - * - * @returns {Promise} - */ - static async get() { - const userDoc = await Model.get(); - - return userDoc; - } -} - -module.exports = Users; diff --git a/src/frontend/js/modules/writing.js b/src/frontend/js/modules/writing.js index bb3ea77..7fab306 100644 --- a/src/frontend/js/modules/writing.js +++ b/src/frontend/js/modules/writing.js @@ -52,11 +52,16 @@ export default class Writing { this.editor = editor; }); + window.onbeforeunload = (e) => { + return ''; + } + /** * Activate form elements */ this.nodes.saveButton = moduleEl.querySelector('[name="js-submit-save"]'); this.nodes.saveButton.addEventListener('click', () => { + window.onbeforeunload = null; this.saveButtonClicked(); }); @@ -69,7 +74,7 @@ export default class Writing { if (!isUserAgree) { return; } - + window.onbeforeunload = null; this.removeButtonClicked(); }); } diff --git a/generatePassword.js b/src/generatePassword.ts similarity index 82% rename from generatePassword.js rename to src/generatePassword.ts index 9b5d32e..f0c09b4 100644 --- a/generatePassword.js +++ b/src/generatePassword.ts @@ -1,14 +1,17 @@ #!/usr/bin/env node -let { password: db } = require('./src/utils/database'); -const program = require('commander'); +import database from './backend/utils/database'; +import commander from 'commander'; +import bcrypt from 'bcrypt'; -const bcrypt = require('bcrypt'); +const db = database['password']; +const program = commander.program; const saltRounds = 12; /** * Script for generating password, that will be used to create and edit pages in CodeX.Docs. * Hashes password with bcrypt and inserts it to the database. + * * @see {https://github.com/tj/commander.js | CommanderJS} */ program @@ -23,7 +26,7 @@ program const userDoc = { passHash: hash }; - await db.remove({}, {multi: true}); + await db.remove({}, { multi: true }); await db.insert(userDoc); console.log('Password was successfully generated'); diff --git a/src/models/user.js b/src/models/user.js deleted file mode 100644 index c29e2c2..0000000 --- a/src/models/user.js +++ /dev/null @@ -1,36 +0,0 @@ -const { password: db } = require('../utils/database/index'); - -/** - * @class User - * @class User model - * - * @property {string} passHash - hashed password - */ -class User { - /** - * Find and return model of user. - * User is only one. - * - * @returns {Promise} - */ - static async get() { - const data = await db.findOne({}); - - if (!data) { - return null; - } - - return new User(data); - } - - /** - * @class - * - * @param {object} userData - */ - constructor(userData) { - this.passHash = userData.passHash; - } -} - -module.exports = User; diff --git a/src/routes/api/index.js b/src/routes/api/index.js deleted file mode 100644 index ed1c555..0000000 --- a/src/routes/api/index.js +++ /dev/null @@ -1,12 +0,0 @@ -const express = require('express'); -const router = express.Router(); - -const pagesAPI = require('./pages'); -const transportAPI = require('./transport'); -const linksAPI = require('./links'); - -router.use('/', pagesAPI); -router.use('/', transportAPI); -router.use('/', linksAPI); - -module.exports = router; diff --git a/src/routes/api/links.js b/src/routes/api/links.js deleted file mode 100644 index 99d0e43..0000000 --- a/src/routes/api/links.js +++ /dev/null @@ -1,38 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const ogs = require('open-graph-scraper'); - -/** - * Accept file url to fetch - */ -router.get('/fetchUrl', async (req, res) => { - const response = { - success: 0 - }; - - if (!req.query.url) { - res.status(400).json(response); - return; - } - - try { - const linkData = (await ogs({ url: req.query.url })).result; - - response.success = 1; - response.meta = { - title: linkData.ogTitle, - description: linkData.ogDescription, - site_name: linkData.ogSiteName, - image: { - url: linkData.ogImage.url - } - }; - - res.status(200).json(response); - } catch (e) { - console.log(e); - res.status(500).json(response); - } -}); - -module.exports = router; diff --git a/src/routes/auth.js b/src/routes/auth.js deleted file mode 100644 index 1c1b5f8..0000000 --- a/src/routes/auth.js +++ /dev/null @@ -1,63 +0,0 @@ -require('dotenv').config(); - -const express = require('express'); -const jwt = require('jsonwebtoken'); -const router = express.Router(); -const Users = require('../controllers/users'); -const config = require('../../config/index'); -const bcrypt = require('bcrypt'); -const csrf = require('csurf'); -const csrfProtection = csrf({ cookie: true }); -const parseForm = express.urlencoded({ extended: false }); - -/** - * Authorization page - */ -router.get('/auth', csrfProtection, function (req, res) { - res.render('auth', { - title: 'Login page', - csrfToken: req.csrfToken(), - }); -}); - -/** - * Process given password - */ -router.post('/auth', parseForm, csrfProtection, async (req, res) => { - const userDoc = await Users.get(); - - if (!userDoc) { - res.render('auth', { - title: 'Login page', - header: 'Password not set', - csrfToken: req.csrfToken(), - }); - } - - const passHash = userDoc.passHash; - - bcrypt.compare(req.body.password, passHash, async (err, result) => { - if (err || result === false) { - res.render('auth', { - title: 'Login page', - header: 'Wrong password', - csrfToken: req.csrfToken(), - }); - } - - const token = jwt.sign({ - iss: 'Codex Team', - sub: 'auth', - iat: Date.now(), - }, passHash + config.secret); - - res.cookie('authToken', token, { - httpOnly: true, - expires: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year - }); - - res.redirect('/'); - }); -}); - -module.exports = router; diff --git a/src/routes/index.js b/src/routes/index.js deleted file mode 100644 index aab43a2..0000000 --- a/src/routes/index.js +++ /dev/null @@ -1,18 +0,0 @@ -const express = require('express'); -const router = express.Router(); - -const home = require('./home'); -const pages = require('./pages'); -const auth = require('./auth'); -const aliases = require('./aliases'); -const api = require('./api'); - -const pagesMiddleware = require('./middlewares/pages'); - -router.use('/', pagesMiddleware, home); -router.use('/', pagesMiddleware, pages); -router.use('/', pagesMiddleware, auth); -router.use('/api', api); -router.use('/', aliases); - -module.exports = router; diff --git a/src/routes/middlewares/locals.js b/src/routes/middlewares/locals.js deleted file mode 100644 index bd584cb..0000000 --- a/src/routes/middlewares/locals.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Middleware for checking locals.isAuthorized property, which allows to edit/create pages - * @param req - * @param res - * @param next - */ -module.exports = function allowEdit(req, res, next) { - if (res.locals.isAuthorized) { - next(); - } else { - res.redirect('/auth'); - } -}; diff --git a/src/routes/middlewares/token.js b/src/routes/middlewares/token.js deleted file mode 100644 index 9b7af2d..0000000 --- a/src/routes/middlewares/token.js +++ /dev/null @@ -1,26 +0,0 @@ -require('dotenv').config(); -const config = require('../../../config/index'); -const jwt = require('jsonwebtoken'); -const Users = require('../../controllers/users'); - -/** - * Middleware for checking jwt token - * @param req - * @param res - * @param next - */ -module.exports = async function verifyToken(req, res, next) { - let token = req.cookies.authToken; - const userDoc = await Users.get(); - - if (!userDoc) { - res.locals.isAuthorized = false; - next(); - return; - } - - jwt.verify(token, userDoc.passHash + config.secret, (err, decodedToken) => { - res.locals.isAuthorized = !(err || !decodedToken); - next(); - }); -}; diff --git a/src/routes/pages.js b/src/routes/pages.js deleted file mode 100644 index 46375ab..0000000 --- a/src/routes/pages.js +++ /dev/null @@ -1,65 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const Pages = require('../controllers/pages'); -const PagesOrder = require('../controllers/pagesOrder'); - -const verifyToken = require('./middlewares/token'); -const allowEdit = require('./middlewares/locals'); - -/** - * Create new page form - */ -router.get('/page/new', verifyToken, allowEdit, async (req, res, next) => { - const pagesAvailable = await Pages.getAll(); - - res.render('pages/form', { - pagesAvailable, - page: null, - }); -}); - -/** - * Edit page form - */ -router.get('/page/edit/:id', verifyToken, allowEdit, async (req, res, next) => { - const pageId = req.params.id; - - try { - const page = await Pages.get(pageId); - const pagesAvailable = await Pages.getAllExceptChildren(pageId); - const parentsChildrenOrdered = await PagesOrder.getOrderedChildren(pagesAvailable, pageId, page._parent, true); - - res.render('pages/form', { - page, - parentsChildrenOrdered, - pagesAvailable, - }); - } catch (error) { - res.status(404); - next(error); - } -}); - -/** - * View page - */ -router.get('/page/:id', verifyToken, async (req, res, next) => { - const pageId = req.params.id; - - try { - const page = await Pages.get(pageId); - - const pageParent = await page.parent; - - res.render('pages/page', { - page, - pageParent, - config: req.app.locals.config, - }); - } catch (error) { - res.status(404); - next(error); - } -}); - -module.exports = router; diff --git a/src/test/database.ts b/src/test/database.ts new file mode 100644 index 0000000..a073223 --- /dev/null +++ b/src/test/database.ts @@ -0,0 +1,196 @@ +import fs from 'fs'; +import config from 'config'; +import { expect } from 'chai'; +import Datastore from 'nedb'; + +import { Database } from '../backend/utils/database'; + +interface Document { + data?: any; + _id?: string; + update?: boolean; + no?: any; +} + +describe('Database', () => { + const pathToDB = `./${config.get('database')}/test.db`; + let nedbInstance; + let db: Database; + + before(() => { + if (fs.existsSync(pathToDB)) { + fs.unlinkSync(pathToDB); + } + }); + + it('Creating db instance', async () => { + nedbInstance = new Datastore({ filename: pathToDB, autoload: true }); + db = new Database(nedbInstance); + }); + + it('Inserting document', async () => { + const data = 'Text data'; + + const insertedDoc = await db.insert({ data }) as Document; + + expect(insertedDoc).to.be.a('object'); + expect(insertedDoc.data).to.equal(data); + }); + + it('Finding document', async () => { + const data = 'Text data'; + + const insertedDoc = await db.insert({ data }) as Document; + + expect(insertedDoc).to.be.a('object'); + expect(insertedDoc.data).to.equal(data); + + const foundDoc = await db.findOne({ _id: insertedDoc._id }) as Document; + + expect(foundDoc).not.be.null; + expect(foundDoc._id).to.equal(insertedDoc._id); + expect(foundDoc.data).to.equal(data); + + const projectedDoc = await db.findOne({ _id: insertedDoc._id }, { data: 1, _id: 0 }); + + expect(Object.keys(projectedDoc).length).to.equal(1); + expect(Object.keys(projectedDoc).pop()).to.equal('data'); + }); + + it('Updating document', async () => { + const data = 'Text data'; + + const insertedDoc = await db.insert({ data }) as Document; + + expect(insertedDoc).to.be.a('object'); + expect(insertedDoc.data).to.equal(data); + + const updatedData = 'Updated text data'; + + await db.update({ _id: insertedDoc._id }, { data: updatedData }); + + const updatedDoc = await db.findOne({ _id: insertedDoc._id }) as Document; + + expect(updatedDoc).not.be.null; + expect(updatedDoc.data).not.equal(data); + expect(updatedDoc.data).to.equal(updatedData); + }); + + it('Updating documents with options', async () => { + const data = { + update: true, + data: 'Text data', + }; + + await db.insert(data); + await db.insert(data); + + let numberOfUpdatedDocs = await db.update({ update: true }, { $set: { data: 'First update' } }, { multi: true }); + + expect(numberOfUpdatedDocs).to.equal(2); + + const affectedDocs = await db.update( + { update: true }, + { $set: { data: 'Second update' } }, + { + multi: true, + returnUpdatedDocs: true, + } + ) as Array; + + expect(affectedDocs).to.be.a('array'); + affectedDocs.forEach((doc: Document) => { + expect(doc.data).to.equal('Second update'); + }); + + const upsertedDoc = await db.update({ update: true, data: 'First update' }, { $set: { data: 'Third update' } }, { upsert: true }) as Document; + + expect(upsertedDoc.update).to.be.true; + expect(upsertedDoc.data).to.equal('Third update'); + + numberOfUpdatedDocs = await db.update({ data: 'Third update' }, { $set: { data: 'Fourth update' } }, { upsert: true }); + + expect(numberOfUpdatedDocs).to.equal(1); + }); + + it('Finding documents', async () => { + const data1 = 'Text data 1'; + const data2 = 'Text data 2'; + + const insertedDoc1 = await db.insert({ data: data1, flag: true, no: 1 }) as Document; + const insertedDoc2 = await db.insert({ data: data2, flag: true, no: 2 }) as Document; + + const foundDocs = await db.find({ flag: true }) as Array; + + expect(foundDocs).to.be.a('array'); + expect(foundDocs.length).to.equal(2); + + foundDocs.sort(({ no: a }, { no: b }) => a - b); + + expect(foundDocs[0]._id).to.equal(insertedDoc1._id); + expect(foundDocs[0].data).to.equal(insertedDoc1.data); + expect(foundDocs[1]._id).to.equal(insertedDoc2._id); + expect(foundDocs[1].data).to.equal(insertedDoc2.data); + + const projectedDocs = await db.find({ flag: true }, { no: 1, _id: 0 }) as Array; + + expect(projectedDocs.length).to.equal(2); + projectedDocs.forEach(data => { + expect(Object.keys(data).length).to.equal(1); + expect(Object.keys(data).pop()).to.equal('no'); + }); + }); + + it('Removing document', async () => { + const data = 'Text data'; + + const insertedDoc = await db.insert({ data }) as Document; + + expect(insertedDoc).to.be.a('object'); + expect(insertedDoc.data).to.equal(data); + + await db.remove({ _id: insertedDoc._id }); + + const deletedDoc = await db.findOne({ _id: insertedDoc._id }); + + expect(deletedDoc).to.be.null; + }); + + it('Test invalid database queries', async () => { + try { + await db.insert({}); + } catch (err) { + expect((err as Error).message).to.equal('Cannot read property \'_id\' of undefined'); + } + + try { + await db.find({ size: { $invalidComparator: 1 } }); + } catch (err) { + expect((err as Error).message).to.equal('Unknown comparison function $invalidComparator'); + } + + try { + await db.findOne({ field: { $invalidComparator: 1 } }); + } catch (err) { + expect((err as Error).message).to.equal('Unknown comparison function $invalidComparator'); + } + + try { + await db.update({ field: { $undefinedComparator: 1 } }, {}); + } catch (err) { + expect((err as Error).message).to.equal('Unknown comparison function $undefinedComparator'); + } + + try { + await db.remove({ field: { $undefinedComparator: 1 } }); + } catch (err) { + expect((err as Error).message).to.equal('Unknown comparison function $undefinedComparator'); + } + }); + + after(() => { + if (fs.existsSync(pathToDB)) { + fs.unlinkSync(pathToDB); + } + }); +}); diff --git a/test/express.js b/src/test/express.ts similarity index 51% rename from test/express.js rename to src/test/express.ts index 79f8dec..c74dbed 100644 --- a/test/express.js +++ b/src/test/express.ts @@ -1,17 +1,19 @@ -const { app } = require('../bin/www'); -const chai = require('chai'); -const chaiHTTP = require('chai-http'); -const { expect } = chai; +import chaiHTTP from 'chai-http'; +import chai, { expect } from 'chai'; + +import server from '../bin/server'; + +const app = server.app; chai.use(chaiHTTP); describe('Express app', () => { it('App is available', async () => { - let agent = chai.request.agent(app); + const agent = chai.request.agent(app); const result = await agent .get('/'); expect(result).to.have.status(200); }); -}); +}); \ No newline at end of file diff --git a/test/models/alias.js b/src/test/models/alias.ts similarity index 89% rename from test/models/alias.js rename to src/test/models/alias.ts index 023f2c8..453457e 100644 --- a/test/models/alias.js +++ b/src/test/models/alias.ts @@ -1,14 +1,16 @@ -const {expect} = require('chai'); -const fs = require('fs'); -const path = require('path'); -const config = require('../../config'); -const Alias = require('../../src/models/alias'); -const {binaryMD5} = require('../../src/utils/crypto'); -const {aliases} = require('../../src/utils/database'); +import { expect } from 'chai'; +import fs from 'fs'; +import path from 'path'; +import config from 'config'; +import Alias from '../../backend/models/alias'; +import { binaryMD5 } from '../../backend/utils/crypto'; +import database from '../../backend/utils/database'; + +const aliases = database['aliases']; describe('Alias model', () => { after(() => { - const pathToDB = path.resolve(__dirname, '../../', config.database, './aliases.db'); + const pathToDB = path.resolve(__dirname, '../../../', config.get('database'), './aliases.db'); if (fs.existsSync(pathToDB)) { fs.unlinkSync(pathToDB); @@ -108,7 +110,7 @@ describe('Alias model', () => { expect(savedAlias.id).to.equal(initialData.id); expect(savedAlias.deprecated).to.equal(false); - const insertedAlias = await aliases.findOne({_id: savedAlias._id}); + const insertedAlias = await aliases.findOne({_id: savedAlias._id}) as Alias; expect(insertedAlias._id).to.equal(savedAlias._id); expect(insertedAlias.hash).to.equal(savedAlias.hash); @@ -128,7 +130,7 @@ describe('Alias model', () => { expect(alias._id).to.equal(insertedAlias._id); - const updatedAlias = await aliases.findOne({_id: alias._id}); + const updatedAlias = await aliases.findOne({_id: alias._id}) as Alias; expect(updatedAlias._id).to.equal(savedAlias._id); expect(updatedAlias.hash).to.equal(updateData.hash); diff --git a/test/models/file.js b/src/test/models/file.ts similarity index 75% rename from test/models/file.js rename to src/test/models/file.ts index 1e99b2e..f1d54a4 100644 --- a/test/models/file.js +++ b/src/test/models/file.ts @@ -1,14 +1,16 @@ -const {expect} = require('chai'); -const fs = require('fs'); -const path = require('path'); -const config = require('../../config'); -const File = require('../../src/models/file'); -const {files} = require('../../src/utils/database'); +import { expect } from 'chai'; +import fs from 'fs'; +import path from 'path'; +import config from 'config'; +import File from '../../backend/models/file'; +import database from '../../backend/utils/database'; + +const files = database['files']; describe('File model', () => { after(() => { - const pathToDB = path.resolve(__dirname, '../../', config.database, './files.db'); + const pathToDB = path.resolve(__dirname, '../../../', config.get('database'), './files.db'); if (fs.existsSync(pathToDB)) { fs.unlinkSync(pathToDB); @@ -20,7 +22,7 @@ describe('File model', () => { expect(file.data).to.be.a('object'); - let {data} = file; + let { data } = file; expect(data._id).to.be.undefined; expect(data.name).to.be.undefined; @@ -29,7 +31,7 @@ describe('File model', () => { expect(data.size).to.be.undefined; expect(data.mimetype).to.be.undefined; - file = new File(null); + file = new File(); data = file.data; @@ -51,8 +53,6 @@ describe('File model', () => { file = new File(initialData); - const json = file.toJSON(); - data = file.data; expect(data._id).to.equal(initialData._id); @@ -63,7 +63,7 @@ describe('File model', () => { expect(data.mimetype).to.equal(initialData.mimetype); const update = { - _id: 12345, + _id: '12345', name: 'updated filename', filename: 'updated randomname', path: '/uploads/updated randomname', @@ -94,7 +94,7 @@ describe('File model', () => { const file = new File(initialData); - let savedFile = await file.save(); + const savedFile = await file.save(); expect(savedFile._id).not.be.undefined; expect(savedFile.name).to.equal(initialData.name); @@ -103,7 +103,7 @@ describe('File model', () => { expect(savedFile.size).to.equal(initialData.size); expect(savedFile.mimetype).to.equal(initialData.mimetype); - const insertedFile = await files.findOne({_id: file._id}); + const insertedFile = await files.findOne({ _id: file._id }); expect(insertedFile._id).to.equal(file._id); expect(insertedFile.name).to.equal(file.name); @@ -113,7 +113,7 @@ describe('File model', () => { expect(insertedFile.mimetype).to.equal(file.mimetype); const updateData = { - _id: 12345, + _id: '12345', name: 'updated filename', filename: 'updated randomname', path: '/uploads/updated randomname', @@ -126,7 +126,7 @@ describe('File model', () => { expect(file._id).to.equal(insertedFile._id); - const updatedFile = await files.findOne({_id: file._id}); + const updatedFile = await files.findOne({ _id: file._id }); expect(updatedFile._id).to.equal(savedFile._id); expect(updatedFile.name).to.equal(updateData.name); @@ -139,7 +139,7 @@ describe('File model', () => { expect(file._id).to.be.undefined; - const removedFile = await files.findOne({_id: updatedFile._id}); + const removedFile = await files.findOne({ _id: updatedFile._id }); expect(removedFile).to.be.null; }); @@ -157,16 +157,18 @@ describe('File model', () => { const savedFile = await file.save(); - const foundFile = await File.get(savedFile._id); - - const {data} = foundFile; - - expect(data._id).to.equal(savedFile._id); - expect(data.name).to.equal(savedFile.name); - expect(data.filename).to.equal(savedFile.filename); - expect(data.path).to.equal(savedFile.path); - expect(data.size).to.equal(savedFile.size); - expect(data.mimetype).to.equal(savedFile.mimetype); + if (savedFile._id !== undefined){ + const foundFile = await File.get(savedFile._id); + + const { data } = foundFile; + + expect(data._id).to.equal(savedFile._id); + expect(data.name).to.equal(savedFile.name); + expect(data.filename).to.equal(savedFile.filename); + expect(data.path).to.equal(savedFile.path); + expect(data.size).to.equal(savedFile.size); + expect(data.mimetype).to.equal(savedFile.mimetype); + } await file.destroy(); }); @@ -184,16 +186,18 @@ describe('File model', () => { const savedFile = await file.save(); - const foundFile = await File.getByFilename(savedFile.filename); - - const {data} = foundFile; - - expect(data._id).to.equal(savedFile._id); - expect(data.name).to.equal(savedFile.name); - expect(data.filename).to.equal(savedFile.filename); - expect(data.path).to.equal(savedFile.path); - expect(data.size).to.equal(savedFile.size); - expect(data.mimetype).to.equal(savedFile.mimetype); + if (savedFile.filename !== undefined){ + const foundFile = await File.getByFilename(savedFile.filename); + + const { data } = foundFile; + + expect(data._id).to.equal(savedFile._id); + expect(data.name).to.equal(savedFile.name); + expect(data.filename).to.equal(savedFile.filename); + expect(data.path).to.equal(savedFile.path); + expect(data.size).to.equal(savedFile.size); + expect(data.mimetype).to.equal(savedFile.mimetype); + } await file.destroy(); }); @@ -218,7 +222,7 @@ describe('File model', () => { const savedFiles = await Promise.all(filesToSave.map(file => file.save())); - const foundFiles = await File.getAll({_id: {$in: savedFiles.map(file => file._id)}}); + const foundFiles = await File.getAll({ _id: { $in: savedFiles.map(file => file._id) } }); expect(foundFiles.length).to.equal(2); diff --git a/test/models/page.js b/src/test/models/page.ts similarity index 82% rename from test/models/page.js rename to src/test/models/page.ts index 6c99f3c..bd9d61d 100644 --- a/test/models/page.js +++ b/src/test/models/page.ts @@ -1,15 +1,16 @@ -const {expect} = require('chai'); -const fs = require('fs'); -const path = require('path'); -const config = require('../../config'); -const Page = require('../../src/models/page'); -const {pages} = require('../../src/utils/database'); -const translateString = require('../../src/utils/translation'); +import { expect } from 'chai'; +import fs from 'fs'; +import path from 'path'; +import config from 'config'; +import Page from '../../backend/models/page'; +import translateString from '../../backend/utils/translation'; +import database from '../../backend/utils/database'; + +const pages = database['pages']; describe('Page model', () => { - - const transformToUri = (string) => { - return translateString(string + const transformToUri = (text: string): string => { + return translateString(text .replace(/ /g, ' ') .replace(/[^a-zA-Z0-9А-Яа-яЁё ]/g, ' ') .replace(/ +/g, ' ') @@ -20,7 +21,7 @@ describe('Page model', () => { }; after(() => { - const pathToDB = path.resolve(__dirname, '../../', config.database, './pages.db'); + const pathToDB = path.resolve(__dirname, '../../../', config.get('database'), './pages.db'); if (fs.existsSync(pathToDB)) { fs.unlinkSync(pathToDB); @@ -40,7 +41,7 @@ describe('Page model', () => { expect(data.body).to.be.undefined; expect(data.parent).to.be.equal('0'); - page = new Page(null); + page = new Page(); data = page.data; @@ -83,7 +84,7 @@ describe('Page model', () => { expect(json.parent).to.be.equal('0'); const update = { - _id: 12345, + _id: '12345', body: { blocks: [ { @@ -122,7 +123,7 @@ describe('Page model', () => { }; const page = new Page(initialData); - let savedPage = await page.save(); + const savedPage = await page.save(); expect(savedPage._id).not.be.undefined; expect(savedPage.title).to.equal(initialData.body.blocks[0].data.text); @@ -188,7 +189,7 @@ describe('Page model', () => { const firstPage = new Page(initialData); let firstSavedPage = await firstPage.save(); const secondPage = new Page(initialData); - let secondSavedPage = await secondPage.save(); + const secondSavedPage = await secondPage.save(); expect(secondSavedPage.uri).to.equal(transformToUri(initialData.body.blocks[0].data.text) + '-1'); @@ -200,7 +201,7 @@ describe('Page model', () => { expect(firstSavedPage.uri).to.equal(newUri); const thirdPage = new Page(initialData); - let thirdSavedPage = await thirdPage.save(); + const thirdSavedPage = await thirdPage.save(); expect(thirdSavedPage.uri).to.equal(transformToUri(initialData.body.blocks[0].data.text)); }); @@ -222,6 +223,12 @@ describe('Page model', () => { const savedPage = await page.save(); + if (savedPage._id == undefined) { + await page.destroy(); + + return; + } + const foundPage = await Page.get(savedPage._id); const {data} = foundPage; @@ -302,26 +309,29 @@ describe('Page model', () => { } } ] - } + }, + parent: parentId, } ); - child.parent = parent; - const {_id: childId} = await child.save(); - const testedParent = await child.parent; + const testedParent = await child.getParent(); - expect(testedParent._id).to.equal(parentId); - expect(testedParent.title).to.equal(parent.body.blocks[0].data.text); - expect(testedParent.uri).to.equal(transformToUri(parent.body.blocks[0].data.text)); - expect(testedParent.body).to.deep.equal(parent.body); + expect(testedParent).to.be.not.null; + if (testedParent) { + expect(testedParent._id).to.equal(parentId); + expect(testedParent.title).to.equal(parent.body.blocks[0].data.text); + expect(testedParent.uri).to.equal(transformToUri(parent.body.blocks[0].data.text)); + expect(testedParent.body).to.deep.equal(parent.body); + } const children = await parent.children; expect(children.length).to.equal(1); - const testedChild = children.pop(); + const temp: Page|undefined = children.pop(); + const testedChild: Page = !temp ? new Page({}) : temp; expect(testedChild._id).to.equal(childId); expect(testedChild.title).to.equal(child.body.blocks[0].data.text); @@ -354,20 +364,22 @@ describe('Page model', () => { }); it('test deletion', async () => { - - const pages = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; + const pageIndexes = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; const orders = { '0' : ['1', '2', '3'], '1' : ['4', '5'], '5' : ['6', '7', '8'], - '3' : ['9'] - }; + '3' : ['9'], + } as { [key: string]: string[] }; + + function deleteRecursively(startFrom: string): void { + const order: string[] = orders[startFrom]; - function deleteRecursively(startFrom) { - const order = orders[startFrom]; if (!order) { - const found = pages.indexOf(startFrom); - pages.splice(found, 1); + const found = pageIndexes.indexOf(startFrom); + + pageIndexes.splice(found, 1); + return; } @@ -375,8 +387,8 @@ describe('Page model', () => { deleteRecursively(id); }); - const found = pages.indexOf(startFrom); - pages.splice(found, 1); + const found = pageIndexes.indexOf(startFrom); + pageIndexes.splice(found, 1); } }); }); diff --git a/test/models/pageOrder.js b/src/test/models/pageOrder.ts similarity index 76% rename from test/models/pageOrder.js rename to src/test/models/pageOrder.ts index 71df37d..569af52 100644 --- a/test/models/pageOrder.js +++ b/src/test/models/pageOrder.ts @@ -1,13 +1,15 @@ -const {expect} = require('chai'); -const fs = require('fs'); -const path = require('path'); -const config = require('../../config'); -const PageOrder = require('../../src/models/pageOrder'); -const {pagesOrder} = require('../../src/utils/database'); +import { expect } from 'chai'; +import fs from 'fs'; +import path from 'path'; +import config from 'config'; +import PageOrder from '../../backend/models/pageOrder'; +import database from '../../backend/utils/database'; + +const pagesOrder = database['pagesOrder']; describe('PageOrder model', () => { after(() => { - const pathToDB = path.resolve(__dirname, '../../', config.database, './pagesOrder.db'); + const pathToDB = path.resolve(__dirname, '../../../', config.get('database'), './pagesOrder.db'); if (fs.existsSync(pathToDB)) { fs.unlinkSync(pathToDB); @@ -15,7 +17,7 @@ describe('PageOrder model', () => { }); it('Empty Model', async () => { - let pageOrder = new PageOrder(); + const pageOrder = new PageOrder(); expect(pageOrder.data).to.be.a('object'); @@ -25,7 +27,7 @@ describe('PageOrder model', () => { expect(data.page).to.be.to.equal('0'); expect(data.order).to.be.an('array').that.is.empty; - page = new PageOrder(null); + let page = new PageOrder(); data = page.data; @@ -53,13 +55,13 @@ describe('PageOrder model', () => { order: ['1', '2'] }; const pageOrder = new PageOrder(testData); - let {data} = await pageOrder.save(); + const {data} = await pageOrder.save(); expect(data._id).not.be.undefined; expect(data.page).to.equal(testData.page); expect(data.order).to.deep.equals(testData.order); - const insertedPageOrder = await pagesOrder.findOne({_id: data._id}); + const insertedPageOrder = await pagesOrder.findOne({_id: data._id}) as PageOrder; expect(insertedPageOrder._id).to.equal(data._id); expect(insertedPageOrder.page).to.equal(data.page); expect(insertedPageOrder.order).to.deep.equal(data.order); @@ -74,7 +76,7 @@ describe('PageOrder model', () => { expect(pageOrder.data._id).to.equal(insertedPageOrder._id); - const updatedData = await pagesOrder.findOne({_id: insertedPageOrder._id}); + const updatedData = await pagesOrder.findOne({_id: insertedPageOrder._id}) as PageOrder; expect(updatedData.page).to.equal(updateData.page); expect(updatedData.order).to.deep.equal(updateData.order); @@ -97,9 +99,11 @@ describe('PageOrder model', () => { await pageOrder.save(); pageOrder.push('3'); expect(pageOrder.data.order).to.be.an('array').that.is.not.empty; - pageOrder.data.order.forEach((el) => { - expect(el).to.be.an('string') - }); + if (pageOrder.data.order !== undefined) { + pageOrder.data.order.forEach((el) => { + expect(el).to.be.an('string'); + }); + } expect(pageOrder.data.order).to.deep.equals(['1', '2', '3']); @@ -130,11 +134,13 @@ describe('PageOrder model', () => { const pageOrder = new PageOrder(testData); const insertedData = await pageOrder.save(); - const insertedPageOrder = await PageOrder.get(insertedData.data.page); - expect(insertedPageOrder).to.instanceOf(PageOrder); - expect(insertedPageOrder.data._id).to.be.equal(insertedData.data._id); + if (insertedData.data.page !== undefined) { + const insertedPageOrder = await PageOrder.get(insertedData.data.page); + expect(insertedPageOrder).to.instanceOf(PageOrder); + expect(insertedPageOrder.data._id).to.be.equal(insertedData.data._id); + } - const emptyInstance = await PageOrder.get(null); + const emptyInstance = await PageOrder.get(''); expect(emptyInstance.data.page).to.be.equal('0'); expect(emptyInstance.data.order).to.be.an('array').that.is.empty; diff --git a/test/rcparser.js b/src/test/rcparser.ts similarity index 56% rename from test/rcparser.js rename to src/test/rcparser.ts index 053952c..4172217 100644 --- a/test/rcparser.js +++ b/src/test/rcparser.ts @@ -1,18 +1,14 @@ -const {expect} = require('chai'); +import { expect } from 'chai'; +import fs from 'fs'; +import path from 'path'; +import config from 'config'; +import sinon = require('sinon'); -require('mocha-sinon'); -const fs = require('fs'); -const path = require('path'); -const config = require('../config'); -const rcParser = require('../src/utils/rcparser'); +import rcParser from '../backend/utils/rcparser'; -const rcPath = path.resolve(process.cwd(), config.rcFile); +const rcPath = path.resolve(process.cwd(), config.get('rcFile')); describe('RC file parser test', () => { - beforeEach(function () { - this.sinon.stub(console, 'log'); - }); - afterEach(() => { if (fs.existsSync(rcPath)) { fs.unlinkSync(rcPath); @@ -27,25 +23,27 @@ describe('RC file parser test', () => { it('Invalid JSON formatted config', () => { const invalidJson = '{title: "Codex Docs"}'; + const spy = sinon.spy(console, 'log'); fs.writeFileSync(rcPath, invalidJson, 'utf8'); const parsedConfig = rcParser.getConfiguration(); - expect(console.log.calledOnce).to.be.true; - expect(console.log.calledWith('CodeX Docs rc file should be in JSON format.')).to.be.true; + expect(spy.calledOnce).to.be.true; + expect(spy.calledWith('CodeX Docs rc file should be in JSON format.')).to.be.true; expect(parsedConfig).to.be.deep.equal(rcParser.DEFAULTS); + spy.restore(); }); it('Normal config', () => { const normalConfig = { title: 'Documentation', menu: [ - {title: 'Option 1', uri: '/option1'}, - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} - ] + { title: 'Option 1', uri: '/option1' }, + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, + ], }; fs.writeFileSync(rcPath, JSON.stringify(normalConfig), 'utf8'); @@ -58,10 +56,10 @@ describe('RC file parser test', () => { it('Missed title', () => { const normalConfig = { menu: [ - {title: 'Option 1', uri: '/option1'}, - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} - ] + { title: 'Option 1', uri: '/option1' }, + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, + ], }; fs.writeFileSync(rcPath, JSON.stringify(normalConfig), 'utf8'); @@ -74,7 +72,7 @@ describe('RC file parser test', () => { it('Missed menu', () => { const normalConfig = { - title: 'Documentation' + title: 'Documentation', }; fs.writeFileSync(rcPath, JSON.stringify(normalConfig), 'utf8'); @@ -89,21 +87,23 @@ describe('RC file parser test', () => { const normalConfig = { title: 'Documentation', menu: { - 0: {title: 'Option 1', uri: '/option1'}, - 1: {title: 'Option 2', uri: '/option2'}, - 2: {title: 'Option 3', uri: '/option3'} - } + 0: { title: 'Option 1', uri: '/option1' }, + 1: { title: 'Option 2', uri: '/option2' }, + 2: { title: 'Option 3', uri: '/option3' }, + }, }; fs.writeFileSync(rcPath, JSON.stringify(normalConfig), 'utf8'); + const spy = sinon.spy(console, 'log'); const parsedConfig = rcParser.getConfiguration(); - expect(console.log.calledOnce).to.be.true; - expect(console.log.calledWith('Menu section in the rc file must be an array.')).to.be.true; + expect(spy.calledOnce).to.be.true; + expect(spy.calledWith('Menu section in the rc file must be an array.')).to.be.true; expect(parsedConfig.title).to.be.equal(normalConfig.title); expect(parsedConfig.menu).to.be.deep.equal(rcParser.DEFAULTS.menu); + spy.restore(); }); it('Menu option is a string', () => { @@ -111,15 +111,15 @@ describe('RC file parser test', () => { title: 'Documentation', menu: [ 'Option 1', - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} - ] + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, + ], }; const expectedMenu = [ - {title: 'Option 1', uri: '/option-1'}, - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} + { title: 'Option 1', uri: '/option-1' }, + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, ]; fs.writeFileSync(rcPath, JSON.stringify(normalConfig), 'utf8'); @@ -134,129 +134,139 @@ describe('RC file parser test', () => { const normalConfig = { title: 'Documentation', menu: [ - [ {title: 'Option 1', uri: '/option1'} ], - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} - ] + [ { title: 'Option 1', uri: '/option1' } ], + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, + ], }; const expectedMenu = [ - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, ]; + const spy = sinon.spy(console, 'log'); fs.writeFileSync(rcPath, JSON.stringify(normalConfig), 'utf8'); const parsedConfig = rcParser.getConfiguration(); - expect(console.log.calledOnce).to.be.true; - expect(console.log.calledWith('Menu option #1 in rc file must be a string or an object')).to.be.true; + expect(spy.calledOnce).to.be.true; + expect(spy.calledWith('Menu option #1 in rc file must be a string or an object')).to.be.true; expect(parsedConfig.title).to.be.equal(normalConfig.title); expect(parsedConfig.menu).to.be.deep.equal(expectedMenu); + spy.restore(); }); it('Menu option title is undefined', () => { const normalConfig = { title: 'Documentation', menu: [ - {uri: '/option1'}, - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} - ] + { uri: '/option1' }, + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, + ], }; const expectedMenu = [ - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, ]; + const spy = sinon.spy(console, 'log'); fs.writeFileSync(rcPath, JSON.stringify(normalConfig), 'utf8'); const parsedConfig = rcParser.getConfiguration(); - expect(console.log.calledOnce).to.be.true; - expect(console.log.calledWith('Menu option #1 title must be a string.')).to.be.true; + expect(spy.calledOnce).to.be.true; + expect(spy.calledWith('Menu option #1 title must be a string.')).to.be.true; expect(parsedConfig.title).to.be.equal(normalConfig.title); expect(parsedConfig.menu).to.be.deep.equal(expectedMenu); + spy.restore(); }); it('Menu option title is not a string', () => { const normalConfig = { title: 'Documentation', menu: [ - {title: [], uri: '/option1'}, - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} - ] + { title: [], uri: '/option1' }, + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, + ], }; const expectedMenu = [ - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, ]; + const spy = sinon.spy(console, 'log'); fs.writeFileSync(rcPath, JSON.stringify(normalConfig), 'utf8'); const parsedConfig = rcParser.getConfiguration(); - expect(console.log.calledOnce).to.be.true; - expect(console.log.calledWith('Menu option #1 title must be a string.')).to.be.true; + expect(spy.calledOnce).to.be.true; + expect(spy.calledWith('Menu option #1 title must be a string.')).to.be.true; expect(parsedConfig.title).to.be.equal(normalConfig.title); expect(parsedConfig.menu).to.be.deep.equal(expectedMenu); + spy.restore(); }); it('Menu option uri is undefined', () => { const normalConfig = { title: 'Documentation', menu: [ - {title: 'Option 1'}, - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} - ] + { title: 'Option 1' }, + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, + ], }; const expectedMenu = [ - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, ]; + const spy = sinon.spy(console, 'log'); fs.writeFileSync(rcPath, JSON.stringify(normalConfig), 'utf8'); const parsedConfig = rcParser.getConfiguration(); - expect(console.log.calledOnce).to.be.true; - expect(console.log.calledWith('Menu option #1 uri must be a string.')).to.be.true; + expect(spy.calledOnce).to.be.true; + expect(spy.calledWith('Menu option #1 uri must be a string.')).to.be.true; expect(parsedConfig.title).to.be.equal(normalConfig.title); expect(parsedConfig.menu).to.be.deep.equal(expectedMenu); + spy.restore(); }); it('Menu option title is not a string', () => { const normalConfig = { title: 'Documentation', menu: [ - {title: 'Option 1', uri: []}, - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} - ] + { title: 'Option 1', uri: [] }, + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, + ], }; const expectedMenu = [ - {title: 'Option 2', uri: '/option2'}, - {title: 'Option 3', uri: '/option3'} + { title: 'Option 2', uri: '/option2' }, + { title: 'Option 3', uri: '/option3' }, ]; + const spy = sinon.spy(console, 'log'); fs.writeFileSync(rcPath, JSON.stringify(normalConfig), 'utf8'); const parsedConfig = rcParser.getConfiguration(); - expect(console.log.calledOnce).to.be.true; - expect(console.log.calledWith('Menu option #1 uri must be a string.')).to.be.true; + expect(spy.calledOnce).to.be.true; + expect(spy.calledWith('Menu option #1 uri must be a string.')).to.be.true; expect(parsedConfig.title).to.be.equal(normalConfig.title); expect(parsedConfig.menu).to.be.deep.equal(expectedMenu); + spy.restore(); }); }); diff --git a/test/rest/aliases.js b/src/test/rest/aliases.ts similarity index 71% rename from test/rest/aliases.js rename to src/test/rest/aliases.ts index 753099c..fe9ec3e 100644 --- a/test/rest/aliases.js +++ b/src/test/rest/aliases.ts @@ -1,29 +1,30 @@ -const {app} = require('../../bin/www'); +import fs from 'fs'; +import path from 'path'; +import config from 'config'; +import chai from 'chai'; +import chaiHTTP from 'chai-http'; +import server from '../../bin/server'; -const fs = require('fs'); -const path = require('path'); -const config = require('../../config'); -const chai = require('chai'); -const chaiHTTP = require('chai-http'); const {expect} = chai; +const app = server.app; chai.use(chaiHTTP); describe('Aliases REST: ', () => { - let agent; + let agent: ChaiHttp.Agent; before(async () => { agent = chai.request.agent(app); }); after(async () => { - const pathToDB = path.resolve(__dirname, '../../', config.database, './pages.db'); + const pathToDB = path.resolve(__dirname, '../../', config.get('database'), './pages.db'); if (fs.existsSync(pathToDB)) { fs.unlinkSync(pathToDB); } - const pathToAliasDB = path.resolve(__dirname, '../../', config.database, './aliases.db'); + const pathToAliasDB = path.resolve(__dirname, '../../', config.get('database'), './aliases.db'); if (fs.existsSync(pathToAliasDB)) { fs.unlinkSync(pathToAliasDB); diff --git a/test/rest/pages.js b/src/test/rest/pages.ts similarity index 91% rename from test/rest/pages.js rename to src/test/rest/pages.ts index bff52f9..ca73eb6 100644 --- a/test/rest/pages.js +++ b/src/test/rest/pages.ts @@ -1,22 +1,23 @@ -const {app} = require('../../bin/www'); -const model = require('../../src/models/page'); -const Page = require('../../src/models/page'); -const PageOrder = require('../../src/models/pageOrder'); -const translateString = require('../../src/utils/translation'); +import fs from 'fs'; +import path from 'path'; +import config from 'config'; +import chai from 'chai'; +import chaiHTTP from 'chai-http'; +import server from '../../bin/server'; +import model from '../../backend/models/page'; +import Page from '../../backend/models/page'; +import PageOrder from '../../backend/models/pageOrder'; +import translateString from '../../backend/utils/translation'; -const fs = require('fs'); -const path = require('path'); -const config = require('../../config'); -const chai = require('chai'); -const chaiHTTP = require('chai-http'); const {expect} = chai; +const app = server.app; chai.use(chaiHTTP); describe('Pages REST: ', () => { - let agent; - const transformToUri = (string) => { - return translateString(string + let agent: ChaiHttp.Agent; + const transformToUri = (text: string):string => { + return translateString(text .replace(/ /g, ' ') .replace(/[^a-zA-Z0-9А-Яа-яЁё ]/g, ' ') .replace(/ +/g, ' ') @@ -31,9 +32,9 @@ describe('Pages REST: ', () => { }); after(async () => { - const pathToPagesDB = path.resolve(__dirname, '../../', config.database, './pages.db'); - const pathToPagesOrderDB = path.resolve(__dirname, '../../', config.database, './pagesOrder.db'); - const pathToAliasesDB = path.resolve(__dirname, '../../', config.database, './aliases.db'); + const pathToPagesDB = path.resolve(__dirname, '../../../', config.get('database'), './pages.db'); + const pathToPagesOrderDB = path.resolve(__dirname, '../../../', config.get('database'), './pagesOrder.db'); + const pathToAliasesDB = path.resolve(__dirname, '../../../', config.get('database'), './aliases.db'); if (fs.existsSync(pathToPagesDB)) { fs.unlinkSync(pathToPagesDB); @@ -93,15 +94,15 @@ describe('Pages REST: ', () => { it('Page data validation on create', async () => { const res = await agent .put('/api/page') - .send({someField: 'Some text'}); + .send({ someField: 'Some text' }); expect(res).to.have.status(400); expect(res).to.be.json; - const {success, error} = res.body; + const { success, error } = res.body; expect(success).to.be.false; - expect(error).to.equal('Error: Some of required fields is missed'); + expect(error).to.equal('validationError'); }); it('Finding page', async () => { @@ -363,7 +364,7 @@ describe('Pages REST: ', () => { expect(error).to.equal('Page with given id does not exist'); }); - async function createPageTree() { + async function createPageTree():Promise { /** * Creating page tree * @@ -474,7 +475,7 @@ describe('Pages REST: ', () => { } it('Removing a page and its children', async () => { - let pages = await createPageTree(); + const pages = await createPageTree(); /** * Deleting from tree page1 diff --git a/test/rest/test_file.json b/src/test/rest/test_file.json similarity index 100% rename from test/rest/test_file.json rename to src/test/rest/test_file.json diff --git a/test/rest/test_image.png b/src/test/rest/test_image.png similarity index 100% rename from test/rest/test_image.png rename to src/test/rest/test_image.png diff --git a/test/rest/transport.js b/src/test/rest/transport.ts similarity index 71% rename from test/rest/transport.js rename to src/test/rest/transport.ts index da375f0..ccee062 100644 --- a/test/rest/transport.js +++ b/src/test/rest/transport.ts @@ -1,44 +1,44 @@ -const fs = require('fs'); -const path = require('path'); -const fileType = require('file-type'); -const chai = require('chai'); -const chaiHTTP = require('chai-http'); -const rimraf = require('rimraf'); +import fs from 'fs'; +import path from 'path'; +import fileType from 'file-type'; +import chai from 'chai'; +import chaiHTTP from 'chai-http'; +import rimraf from 'rimraf'; +import config from 'config'; +import server from '../../bin/server'; +import model from '../../backend/models/file'; + const {expect} = chai; - -const {app} = require('../../bin/www'); -const model = require('../../src/models/file'); - -const config = require('../../config'); +const app = server.app; chai.use(chaiHTTP); describe('Transport routes: ', () => { - let agent; + let agent: ChaiHttp.Agent; before(async () => { agent = chai.request.agent(app); - if (!fs.existsSync('./' + config.uploads)) { - fs.mkdirSync('./' + config.uploads); + if (!fs.existsSync('./' + config.get('uploads'))) { + fs.mkdirSync('./' + config.get('uploads')); } }); after(async () => { - const pathToDB = path.resolve(__dirname, '../../', config.database, './files.db'); + const pathToDB = path.resolve(__dirname, '../../../', config.get('database'), './files.db'); if (fs.existsSync(pathToDB)) { fs.unlinkSync(pathToDB); } - if (fs.existsSync('./' + config.uploads)) { - rimraf.sync('./' + config.uploads); + if (fs.existsSync('./' + config.get('uploads'))) { + rimraf.sync('./' + config.get('uploads')); } }); it('Uploading an image', async () => { const name = 'test_image.png'; - const image = fs.readFileSync(path.resolve(`./test/rest/${name}`)); + const image = fs.readFileSync(path.resolve(`./src/test/rest/${name}`)); const res = await agent .post('/api/transport/image') .attach('image', image, name); @@ -55,19 +55,27 @@ describe('Transport routes: ', () => { expect(file.name).to.equal(name); expect(file.filename).to.equal(body.filename); expect(file.path).to.equal(body.path); - expect(file.mimetype).to.equal(fileType(image).mime); - expect(file.size).to.equal(image.byteLength); - const getRes = await agent - .get(file.path); + const type = await fileType.fromBuffer(image); + expect(type).to.be.not.undefined; + if (type !== undefined) { + expect(file.mimetype).to.equal(type.mime); + expect(file.size).to.equal(image.byteLength); - expect(getRes).to.have.status(200); - expect(getRes).to.have.header('content-type', fileType(image).mime); + expect(file.path).to.be.not.undefined; + if (file.path !== undefined) { + const getRes = await agent + .get(file.path); + + expect(getRes).to.have.status(200); + expect(getRes).to.have.header('content-type', type.mime); + } + } }); it('Uploading an image with map option', async () => { const name = 'test_image.png'; - const image = fs.readFileSync(path.resolve(`./test/rest/${name}`)); + const image = fs.readFileSync(path.resolve(`./src/test/rest/${name}`)); const res = await agent .post('/api/transport/image') .attach('image', image, name) @@ -88,7 +96,7 @@ describe('Transport routes: ', () => { it('Uploading a file', async () => { const name = 'test_file.json'; - const json = fs.readFileSync(path.resolve(`./test/rest/${name}`)); + const json = fs.readFileSync(path.resolve(`./src/test/rest/${name}`)); const res = await agent .post('/api/transport/file') .attach('file', json, name); @@ -107,16 +115,19 @@ describe('Transport routes: ', () => { expect(file.path).to.equal(body.path); expect(file.size).to.equal(json.byteLength); - const getRes = await agent - .get(file.path); - - expect(getRes).to.have.status(200); - expect(getRes).to.have.header('content-type', new RegExp(`^${file.mimetype}`)); + expect(file.path).to.be.not.undefined; + if (file.path !== undefined){ + const getRes = await agent + .get(file.path); + + expect(getRes).to.have.status(200); + expect(getRes).to.have.header('content-type', new RegExp(`^${file.mimetype}`)); + } }); it('Uploading a file with map option', async () => { const name = 'test_file.json'; - const json = fs.readFileSync(path.resolve(`./test/rest/${name}`)); + const json = fs.readFileSync(path.resolve(`./src/test/rest/${name}`)); const res = await agent .post('/api/transport/file') .attach('file', json, name) @@ -155,11 +166,14 @@ describe('Transport routes: ', () => { expect(file.path).to.equal(body.path); expect(file.size).to.equal(body.size); - const getRes = await agent - .get(file.path); - - expect(getRes).to.have.status(200); - expect(getRes).to.have.header('content-type', file.mimetype); + expect(file.path).to.be.not.undefined; + if (file.path !== undefined){ + const getRes = await agent + .get(file.path); + + expect(getRes).to.have.status(200); + expect(getRes).to.have.header('content-type', file.mimetype); + } }); it('Send an file URL to fetch with map option', async () => { @@ -193,7 +207,7 @@ describe('Transport routes: ', () => { expect(body.success).to.equal(0); const name = 'test_file.json'; - const json = fs.readFileSync(path.resolve(`./test/rest/${name}`)); + const json = fs.readFileSync(path.resolve(`./src/test/rest/${name}`)); res = await agent .post('/api/transport/file') .attach('file', json, name) @@ -216,7 +230,7 @@ describe('Transport routes: ', () => { expect(body.success).to.equal(0); let name = 'test_file.json'; - const json = fs.readFileSync(path.resolve(`./test/rest/${name}`)); + const json = fs.readFileSync(path.resolve(`./src/test/rest/${name}`)); res = await agent .post('/api/transport/image') .attach('image', json, name); @@ -224,7 +238,7 @@ describe('Transport routes: ', () => { expect(res).to.have.status(400); name = 'test_image.png'; - const image = fs.readFileSync(path.resolve(`./test/rest/${name}`)); + const image = fs.readFileSync(path.resolve(`./src/test/rest/${name}`)); res = await agent .post('/api/transport/image') .attach('image', image, name) diff --git a/src/utils/asyncMiddleware.js b/src/utils/asyncMiddleware.js deleted file mode 100644 index d9fba14..0000000 --- a/src/utils/asyncMiddleware.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Helper for making async middlewares for express router - * - * @param fn - * @returns {function(*=, *=, *=)} - */ -module.exports = function asyncMiddleware(fn) { - return (req, res, next) => { - Promise.resolve(fn(req, res, next)) - .catch(next); - }; -}; diff --git a/src/utils/database/aliases.js b/src/utils/database/aliases.js deleted file mode 100644 index 2770232..0000000 --- a/src/utils/database/aliases.js +++ /dev/null @@ -1,6 +0,0 @@ -const Datastore = require('nedb'); -const config = require('../../../config'); - -const db = new Datastore({ filename: `./${config.database}/aliases.db`, autoload: true }); - -module.exports = db; diff --git a/src/utils/database/files.js b/src/utils/database/files.js deleted file mode 100644 index aaeb816..0000000 --- a/src/utils/database/files.js +++ /dev/null @@ -1,6 +0,0 @@ -const Datastore = require('nedb'); -const config = require('../../../config'); - -const db = new Datastore({ filename: `./${config.database}/files.db`, autoload: true }); - -module.exports = db; diff --git a/src/utils/database/pages.js b/src/utils/database/pages.js deleted file mode 100644 index 115738e..0000000 --- a/src/utils/database/pages.js +++ /dev/null @@ -1,6 +0,0 @@ -const Datastore = require('nedb'); -const config = require('../../../config'); - -const db = new Datastore({ filename: `./${config.database}/pages.db`, autoload: true }); - -module.exports = db; diff --git a/src/utils/database/pagesOrder.js b/src/utils/database/pagesOrder.js deleted file mode 100644 index 253b72c..0000000 --- a/src/utils/database/pagesOrder.js +++ /dev/null @@ -1,5 +0,0 @@ -const Datastore = require('nedb'); -const config = require('../../../config'); -const db = new Datastore({ filename: `./${config.database}/pagesOrder.db`, autoload: true }); - -module.exports = db; diff --git a/src/utils/database/password.js b/src/utils/database/password.js deleted file mode 100644 index 33d0295..0000000 --- a/src/utils/database/password.js +++ /dev/null @@ -1,6 +0,0 @@ -const Datastore = require('nedb'); -const config = require('../../../config'); - -const db = new Datastore({ filename: `./${config.database}/password.db`, autoload: true }); - -module.exports = db; diff --git a/test/database.js b/test/database.js deleted file mode 100644 index af4e306..0000000 --- a/test/database.js +++ /dev/null @@ -1,179 +0,0 @@ -const fs = require('fs'); -const config = require('../config'); -const {expect} = require('chai'); - -const {class: Database} = require('../src/utils/database'); -const Datastore = require('nedb'); - -describe('Database', () => { - const pathToDB = `./${config.database}/test.db`; - let nedbInstance; - let db; - - before(() => { - if (fs.existsSync(pathToDB)) { - fs.unlinkSync(pathToDB); - } - }); - - it('Creating db instance', async () => { - nedbInstance = new Datastore({filename: pathToDB, autoload: true}); - db = new Database(nedbInstance); - }); - - it('Inserting document', async () => { - const data = 'Text data'; - - const insertedDoc = await db.insert({data}); - - expect(insertedDoc).to.be.a('object'); - expect(insertedDoc.data).to.equal(data); - }); - - it('Finding document', async () => { - const data = 'Text data'; - - const insertedDoc = await db.insert({data}); - - expect(insertedDoc).to.be.a('object'); - expect(insertedDoc.data).to.equal(data); - - const foundDoc = await db.findOne({_id: insertedDoc._id}); - - expect(foundDoc).not.be.null; - expect(foundDoc._id).to.equal(insertedDoc._id); - expect(foundDoc.data).to.equal(data); - - const projectedDoc = await db.findOne({_id: insertedDoc._id}, {data: 1, _id: 0}); - - expect(Object.keys(projectedDoc).length).to.equal(1); - expect(Object.keys(projectedDoc).pop()).to.equal('data'); - }); - - it('Updating document', async () => { - const data = 'Text data'; - - const insertedDoc = await db.insert({data}); - - expect(insertedDoc).to.be.a('object'); - expect(insertedDoc.data).to.equal(data); - - const updatedData = 'Updated text data'; - - await db.update({_id: insertedDoc._id}, {data: updatedData}); - - const updatedDoc = await db.findOne({_id: insertedDoc._id}); - - expect(updatedDoc).not.be.null; - expect(updatedDoc.data).not.equal(data); - expect(updatedDoc.data).to.equal(updatedData); - }); - - it('Updating documents with options', async () => { - const data = {update: true, data: 'Text data'}; - - await db.insert(data); - await db.insert(data); - - let numberOfUpdatedDocs = await db.update({update: true}, {$set: {data: 'First update'}}, {multi: true}); - - expect(numberOfUpdatedDocs).to.equal(2); - - const affectedDocs = await db.update({update: true}, {$set: {data: 'Second update'}}, {multi: true, returnUpdatedDocs: true}); - - expect(affectedDocs).to.be.a('array'); - affectedDocs.forEach(doc => { - expect(doc.data).to.equal('Second update'); - }); - - const upsertedDoc = await db.update({update: true, data: 'First update'}, {$set: {data: 'Third update'}}, {upsert: true}); - - expect(upsertedDoc.update).to.be.true; - expect(upsertedDoc.data).to.equal('Third update'); - - numberOfUpdatedDocs = await db.update({data: 'Third update'}, {$set: {data: 'Fourth update'}}, {upsert: true}); - - expect(numberOfUpdatedDocs).to.equal(1); - }); - - it('Finding documents', async () => { - const data1 = 'Text data 1'; - const data2 = 'Text data 2'; - - const insertedDoc1 = await db.insert({data: data1, flag: true, no: 1}); - const insertedDoc2 = await db.insert({data: data2, flag: true, no: 2}); - - const foundDocs = await db.find({flag: true}); - - expect(foundDocs).to.be.a('array'); - expect(foundDocs.length).to.equal(2); - - foundDocs.sort(({no: a}, {no: b}) => a - b); - - expect(foundDocs[0]._id).to.equal(insertedDoc1._id); - expect(foundDocs[0].data).to.equal(insertedDoc1.data); - expect(foundDocs[1]._id).to.equal(insertedDoc2._id); - expect(foundDocs[1].data).to.equal(insertedDoc2.data); - - const projectedDocs = await db.find({flag: true}, {no: 1, _id: 0}); - - expect(projectedDocs.length).to.equal(2); - projectedDocs.forEach(data => { - expect(Object.keys(data).length).to.equal(1); - expect(Object.keys(data).pop()).to.equal('no'); - }); - }); - - it('Removing document', async () => { - const data = 'Text data'; - - const insertedDoc = await db.insert({data}); - - expect(insertedDoc).to.be.a('object'); - expect(insertedDoc.data).to.equal(data); - - await db.remove({_id: insertedDoc._id}); - - const deletedDoc = await db.findOne({_id: insertedDoc._id}); - - expect(deletedDoc).to.be.null; - }); - - it('Test invalid database queries', async () => { - try { - await db.insert(); - } catch (err) { - expect(err.message).to.equal('Cannot read property \'_id\' of undefined'); - } - - try { - await db.find({size: {$invalidComparator: 1}}); - } catch (err) { - expect(err.message).to.equal('Unknown comparison function $invalidComparator'); - } - - try { - await db.findOne({field: {$invalidComparator: 1}}); - } catch (err) { - expect(err.message).to.equal('Unknown comparison function $invalidComparator'); - } - - try { - await db.update({field: {$undefinedComparator: 1}}); - } catch (err) { - expect(err.message).to.equal('Unknown comparison function $undefinedComparator'); - } - - try { - await db.remove({field: {$undefinedComparator: 1}}); - } catch (err) { - expect(err.message).to.equal('Unknown comparison function $undefinedComparator'); - } - }); - - after(() => { - if (fs.existsSync(pathToDB)) { - fs.unlinkSync(pathToDB); - } - }); -}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..68155e3 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,72 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "./dist/", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "skipLibCheck": true, /* Skip type checking of declaration files. */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +} diff --git a/yarn.lock b/yarn.lock index f0af7b7..9357b38 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,13 @@ # yarn lockfile v1 +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -710,6 +717,18 @@ version "1.0.0" resolved "https://registry.yarnpkg.com/@codexteam/misprints/-/misprints-1.0.0.tgz#e5a7dec7389fe0f176cd51a040d6dc9bdc252086" +"@cspotcode/source-map-consumer@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" + integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== + +"@cspotcode/source-map-support@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" + integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== + dependencies: + "@cspotcode/source-map-consumer" "0.8.0" + "@csstools/convert-colors@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" @@ -776,6 +795,35 @@ version "1.2.0" resolved "https://registry.yarnpkg.com/@editorjs/warning/-/warning-1.2.0.tgz#245a2286a2e996512ac345275b64fa638e319f5e" +"@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + "@mapbox/node-pre-gyp@^1.0.0": version "1.0.5" resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz#2a0b32fcb416fb3f2250fd24cb2a81421a4f5950" @@ -790,41 +838,130 @@ semver "^7.3.4" tar "^6.1.0" -"@sindresorhus/is@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-3.1.0.tgz#d8735532635bea69ad39119df5f0f10099bd09dc" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" -"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0", "@sinonjs/commons@^1.7.0": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.8.3": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/commons@^1.7.0": version "1.8.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217" dependencies: type-detect "4.0.8" -"@sinonjs/formatio@^3.2.1": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.2.2.tgz#771c60dfa75ea7f2d68e3b94c7e888a78781372c" +"@sinonjs/fake-timers@>=5": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.1.tgz#7b698e0b9d12d93611f06ee143c30ced848e2840" + integrity sha512-Wp5vwlZ0lOqpSYGKqr53INws9HLkt6JDc/pDZcPf7bchQnrXJMXPns8CXx0hFikMSGSWfvtvvpb2gtMVfkWagA== dependencies: - "@sinonjs/commons" "^1" - "@sinonjs/samsam" "^3.1.0" + "@sinonjs/commons" "^1.7.0" -"@sinonjs/samsam@^3.1.0", "@sinonjs/samsam@^3.3.3": - version "3.3.3" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.3.3.tgz#46682efd9967b259b81136b9f120fd54585feb4a" +"@sinonjs/fake-timers@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" + integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== dependencies: - "@sinonjs/commons" "^1.3.0" - array-from "^2.1.1" - lodash "^4.17.15" + "@sinonjs/commons" "^1.7.0" + +"@sinonjs/samsam@^6.0.2": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-6.1.1.tgz#627f7f4cbdb56e6419fa2c1a3e4751ce4f6a00b1" + integrity sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA== + dependencies: + "@sinonjs/commons" "^1.6.0" + lodash.get "^4.4.2" + type-detect "^4.0.8" "@sinonjs/text-encoding@^0.7.1": version "0.7.1" resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + "@szmarczak/http-timer@^4.0.5": version "4.0.5" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" dependencies: defer-to-connect "^2.0.0" +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + +"@tsconfig/node10@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" + integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== + +"@tsconfig/node12@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" + integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + +"@tsconfig/node14@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" + integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + +"@tsconfig/node16@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" + integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== + +"@types/bcrypt@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-5.0.0.tgz#a835afa2882d165aff5690893db314eaa98b9f20" + integrity sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw== + dependencies: + "@types/node" "*" + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + "@types/cacheable-request@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" @@ -838,23 +975,116 @@ version "4.2.12" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.12.tgz#6160ae454cd89dae05adc3bb97997f488b608201" +"@types/chai@^4.2.21": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.0.tgz#23509ebc1fa32f1b4d50d6a66c4032d5b8eaabdc" + integrity sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw== + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" +"@types/commander@^2.12.2": + version "2.12.2" + resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae" + integrity sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q== + dependencies: + commander "*" + +"@types/config@^0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/config/-/config-0.0.39.tgz#aad18ceb9439329adc3d4c6b91a908a72c715612" + integrity sha512-EBHj9lSIyw62vwqCwkeJXjiV6C2m2o+RJZlRWLkHduGYiNBoMXcY6AhSLqjQQ+uPdrPYrOMYvVa41zjo00LbFQ== + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/cookie-parser@^1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@types/cookie-parser/-/cookie-parser-1.4.2.tgz#e4d5c5ffda82b80672a88a4281aaceefb1bd9df5" + integrity sha512-uwcY8m6SDQqciHsqcKDGbo10GdasYsPCYkH3hVegj9qAah6pX5HivOnOuI3WYmyQMnOATV39zv/Ybs0bC/6iVg== + dependencies: + "@types/express" "*" + "@types/cookiejar@*": version "2.1.1" resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.1.tgz#90b68446364baf9efd8e8349bb36bd3852b75b80" -"@types/eslint-visitor-keys@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" +"@types/csurf@^1.11.2": + version "1.11.2" + resolved "https://registry.yarnpkg.com/@types/csurf/-/csurf-1.11.2.tgz#c1cba70f7af653c508b28db047e6c1be72411345" + integrity sha512-9bc98EnwmC1S0aSJiA8rWwXtgXtXHHOQOsGHptImxFgqm6CeH+mIOunHRg6+/eg2tlmDMX3tY7XrWxo2M/nUNQ== + dependencies: + "@types/express-serve-static-core" "*" + +"@types/debug@^4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" + integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== + dependencies: + "@types/ms" "*" + +"@types/eslint@^7.28.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.29.0.tgz#e56ddc8e542815272720bb0b4ccc2aff9c3e1c78" + integrity sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.28" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" + integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/file-type@^10.9.1": + version "10.9.1" + resolved "https://registry.yarnpkg.com/@types/file-type/-/file-type-10.9.1.tgz#fc9a6b38697777eca346dba914fdea4b38e04b97" + integrity sha512-oq0fy8Jqj19HofanFsZ56o5anMDUQtFO9B3wfLqM9o42RyCe1WT+wRbSvRbL2l8ARZXNaJturHk0b442+0yi+g== + dependencies: + file-type "*" + +"@types/glob@*": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" "@types/http-cache-semantics@*": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" -"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4": +"@types/json-schema@*", "@types/json-schema@^7.0.7": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/json-schema@^7.0.4": version "7.0.5" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" @@ -862,26 +1092,144 @@ version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" +"@types/jsonwebtoken@^8.5.4": + version "8.5.8" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz#01b39711eb844777b7af1d1f2b4cf22fda1c0c44" + integrity sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A== + dependencies: + "@types/node" "*" + "@types/keyv@*": version "3.1.1" resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" dependencies: "@types/node" "*" +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/mime@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a" + integrity sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q== + +"@types/minimatch@*": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + +"@types/mkdirp@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-1.0.2.tgz#8d0bad7aa793abe551860be1f7ae7f3198c16666" + integrity sha512-o0K1tSO0Dx5X6xlU5F1D6625FawhC3dU3iqr25lluNv/+/QIVH8RLNEiVokgIZo+mz+87w/3Mkg/VvQS+J51fQ== + dependencies: + "@types/node" "*" + +"@types/mocha@^9.0.0": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.0.tgz#baf17ab2cca3fcce2d322ebc30454bff487efad5" + integrity sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg== + +"@types/morgan@^1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@types/morgan/-/morgan-1.9.3.tgz#ae04180dff02c437312bc0cfb1e2960086b2f540" + integrity sha512-BiLcfVqGBZCyNCnCH3F4o2GmDLrpy0HeBVnNlyZG4fo88ZiE9SoiBe3C+2ezuwbjlEyT+PDZ17//TAlRxAn75Q== + dependencies: + "@types/node" "*" + +"@types/ms@*": + version "0.7.31" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + +"@types/multer@^1.4.7": + version "1.4.7" + resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.7.tgz#89cf03547c28c7bbcc726f029e2a76a7232cc79e" + integrity sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA== + dependencies: + "@types/express" "*" + +"@types/nedb@^1.8.12": + version "1.8.12" + resolved "https://registry.yarnpkg.com/@types/nedb/-/nedb-1.8.12.tgz#597bb124ddaf16039c6d478f4abc0a8f2006b134" + integrity sha512-ICDoQMORMjOSqfNFXT4ENXfwwCir1BPblXNm0SPH7C4Q10ou+pvVagcFAJ+rrzf3A47tGU4K/KbzKu7wO9j45Q== + dependencies: + "@types/node" "*" + +"@types/node-fetch@^2.5.12": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975" + integrity sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + "@types/node@*": version "14.0.26" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.26.tgz#22a3b8a46510da8944b67bfc27df02c34a35331c" +"@types/node@^16.4.1": + version "16.11.26" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.26.tgz#63d204d136c9916fb4dcd1b50f9740fe86884e47" + integrity sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ== + +"@types/open-graph-scraper@^4.8.1": + version "4.8.1" + resolved "https://registry.yarnpkg.com/@types/open-graph-scraper/-/open-graph-scraper-4.8.1.tgz#c009360a3e242f7e9a290d3609ffb950f44d6966" + integrity sha512-YtDUxwWiqD0urgCrhGfIeuy84J5TfnrtkM/5a5JXAXGLfi1uMHtZGpDT4ZVwlo9jBNemvXHya6cH28bZS1To1g== + dependencies: + "@types/node" "*" + "@types/q@^1.5.1": version "1.5.4" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + "@types/responselike@*", "@types/responselike@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" dependencies: "@types/node" "*" +"@types/rimraf@^3.0.1": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.2.tgz#a63d175b331748e5220ad48c901d7bbf1f44eef8" + integrity sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ== + dependencies: + "@types/glob" "*" + "@types/node" "*" + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/sinon@^10.0.2": + version "10.0.11" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.11.tgz#8245827b05d3fc57a6601bd35aee1f7ad330fc42" + integrity sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g== + dependencies: + "@types/sinonjs__fake-timers" "*" + +"@types/sinonjs__fake-timers@*": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" + integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== + "@types/superagent@^3.8.3": version "3.8.7" resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-3.8.7.tgz#1f1ed44634d5459b3a672eb7235a8e7cfd97704c" @@ -889,44 +1237,80 @@ "@types/cookiejar" "*" "@types/node" "*" -"@typescript-eslint/eslint-plugin@^2.12.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9" +"@types/twig@^1.12.6": + version "1.12.8" + resolved "https://registry.yarnpkg.com/@types/twig/-/twig-1.12.8.tgz#d1eb7cce4ddafa78005446519162b09693dc218b" + integrity sha512-CcK4gxgQKN/JkcPCTsu1sMzu8KDQVUK/F+QoNS99fuM2pg5NzJ8KXuDY8iqyJrHcCT8QGyjxIHaPerQnDs339A== + +"@typescript-eslint/eslint-plugin@^4.28.5", "@typescript-eslint/eslint-plugin@^4.6.1": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" + integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg== dependencies: - "@typescript-eslint/experimental-utils" "2.34.0" + "@typescript-eslint/experimental-utils" "4.33.0" + "@typescript-eslint/scope-manager" "4.33.0" + debug "^4.3.1" functional-red-black-tree "^1.0.1" - regexpp "^3.0.0" - tsutils "^3.17.1" + ignore "^5.1.8" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" +"@typescript-eslint/experimental-utils@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" + integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q== dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.34.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" -"@typescript-eslint/parser@^2.12.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.34.0.tgz#50252630ca319685420e9a39ca05fe185a256bc8" +"@typescript-eslint/parser@^4.28.5", "@typescript-eslint/parser@^4.6.1": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" + integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA== dependencies: - "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.34.0" - "@typescript-eslint/typescript-estree" "2.34.0" - eslint-visitor-keys "^1.1.0" + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" + debug "^4.3.1" -"@typescript-eslint/typescript-estree@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" +"@typescript-eslint/scope-manager@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" + integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ== dependencies: - debug "^4.1.1" - eslint-visitor-keys "^1.1.0" - glob "^7.1.6" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" + +"@typescript-eslint/types@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" + integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== + +"@typescript-eslint/typescript-estree@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" + integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA== + dependencies: + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" + debug "^4.3.1" + globby "^11.0.3" is-glob "^4.0.1" - lodash "^4.17.15" - semver "^7.3.2" - tsutils "^3.17.1" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" + integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg== + dependencies: + "@typescript-eslint/types" "4.33.0" + eslint-visitor-keys "^2.0.0" "@webassemblyjs/ast@1.9.0": version "1.9.0" @@ -1067,24 +1451,37 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" -accepts@~1.3.5: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" + mime-types "~2.1.34" + negotiator "0.6.3" -acorn-jsx@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" +acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== acorn@^6.4.1: version "6.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" -acorn@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd" +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.4.1: + version "8.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" + integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== agent-base@6: version "6.0.2" @@ -1109,21 +1506,41 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" + integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" -ansi-align@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== dependencies: - string-width "^2.0.0" + string-width "^4.1.0" -ansi-escapes@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - dependencies: - type-fest "^0.11.0" +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-regex@^2.0.0: version "2.1.1" @@ -1141,6 +1558,11 @@ ansi-regex@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -1151,6 +1573,13 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + ansi-styles@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" @@ -1176,6 +1605,14 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + append-field@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" @@ -1201,6 +1638,11 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1223,11 +1665,7 @@ array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" -array-from@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" - -array-includes@^3.0.3, array-includes@^3.1.1: +array-includes@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" dependencies: @@ -1235,18 +1673,23 @@ array-includes@^3.0.3, array-includes@^3.1.1: es-abstract "^1.17.0" is-string "^1.0.5" +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" -array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.3: +array.prototype.flat@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" dependencies: define-properties "^1.1.3" es-abstract "^1.17.0-next.1" -arrify@^1.0.1: +arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -1273,9 +1716,10 @@ assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async-each@^1.0.1: version "1.0.3" @@ -1371,9 +1815,10 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -basic-auth@~2.0.0: +basic-auth@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" + integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== dependencies: safe-buffer "5.1.2" @@ -1420,36 +1865,39 @@ bn.js@^5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0" -body-parser@1.18.3: - version "1.18.3" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" +body-parser@1.19.2: + version "1.19.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" + integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== dependencies: - bytes "3.0.0" + bytes "3.1.2" content-type "~1.0.4" debug "2.6.9" depd "~1.1.2" - http-errors "~1.6.3" - iconv-lite "0.4.23" + http-errors "1.8.1" + iconv-lite "0.4.24" on-finished "~2.3.0" - qs "6.5.2" - raw-body "2.3.3" - type-is "~1.6.16" + qs "6.9.7" + raw-body "2.4.3" + type-is "~1.6.18" boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" -boxen@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" +boxen@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== dependencies: - ansi-align "^2.0.0" - camelcase "^4.0.0" - chalk "^2.0.1" - cli-boxes "^1.0.0" - string-width "^2.0.0" - term-size "^1.2.0" - widest-line "^2.0.0" + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" brace-expansion@^1.1.7: version "1.1.11" @@ -1473,7 +1921,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@~3.0.2: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" dependencies: @@ -1559,6 +2007,11 @@ buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" +buffer-from@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -1582,9 +2035,10 @@ busboy@^0.2.11: dicer "0.2.5" readable-stream "1.1.x" -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== cacache@^12.0.2: version "12.0.4" @@ -1624,16 +2078,30 @@ cacheable-lookup@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz#049fdc59dffdd4fc285e8f4f82936591bd59fec3" -cacheable-request@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58" +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +cacheable-request@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" + integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== dependencies: clone-response "^1.0.2" get-stream "^5.1.0" http-cache-semantics "^4.0.0" keyv "^4.0.0" lowercase-keys "^2.0.0" - normalize-url "^4.1.0" + normalize-url "^6.0.1" responselike "^2.0.0" caching-transform@^3.0.1: @@ -1665,14 +2133,15 @@ callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" -camelcase@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - camelcase@^5.0.0: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -1686,10 +2155,6 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000655, caniuse-lite@^1.0.30001093, can version "1.0.30001247" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001247.tgz" -capture-stack-trace@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" - chai-http@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/chai-http/-/chai-http-4.3.0.tgz#3c37c675c1f4fe685185a307e345de7599337c1a" @@ -1723,7 +2188,7 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" dependencies: @@ -1731,6 +2196,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -1738,28 +2211,38 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - -chardet@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-1.2.1.tgz#8e0b4441c96f1ad747431989db1ff590739c6931" +chardet@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-1.4.0.tgz#278748f260219990fb2167dbfb1b253ca26b41ea" + integrity sha512-NpwMDdSIprbYx1CLnfbxEIarI0Z+s9MssEgggMNheGM+WD68yOhV7IEA/3r6tr0yTRgQD0HuZJDw32s99i6L+A== check-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" -cheerio@^1.0.0-rc.3: - version "1.0.0-rc.3" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6" +cheerio-select@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-1.5.0.tgz#faf3daeb31b17c5e1a9dabcee288aaf8aafa5823" + integrity sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg== dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.1" - entities "~1.1.1" - htmlparser2 "^3.9.1" - lodash "^4.15.0" - parse5 "^3.0.1" + css-select "^4.1.3" + css-what "^5.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + domutils "^2.7.0" + +cheerio@^1.0.0-rc.10: + version "1.0.0-rc.10" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.10.tgz#2ba3dcdfcc26e7956fc1f440e61d51c643379f3e" + integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw== + dependencies: + cheerio-select "^1.5.0" + dom-serializer "^1.3.2" + domhandler "^4.2.0" + htmlparser2 "^6.1.0" + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter "^6.0.1" + tslib "^2.2.0" chokidar@^2.1.8: version "2.1.8" @@ -1793,6 +2276,21 @@ chokidar@^3.4.1: optionalDependencies: fsevents "~2.1.2" +chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -1807,10 +2305,6 @@ chrome-trace-event@^1.0.2: dependencies: tslib "^1.9.0" -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -1831,19 +2325,10 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - dependencies: - restore-cursor "^3.1.0" - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== cliui@^4.0.0: version "4.1.0" @@ -1932,23 +2417,35 @@ colorette@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" -combined-stream@^1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" +commander@*: + version "9.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.0.0.tgz#86d58f24ee98126568936bd1d3574e0308a99a40" + integrity sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw== + commander@2.15.1: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" -commander@^2.19.0, commander@^2.20.0: +commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" -comment-parser@^0.7.2: - version "0.7.5" - resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-0.7.5.tgz#06db157a3b34addf8502393743e41897e2c73059" +commander@^8.1.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +comment-parser@^0.7.6: + version "0.7.6" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-0.7.6.tgz#0e743a53c8e646c899a1323db31f6cd337b10f12" + integrity sha512-GKNxVA7/iuTnAqGADlTWX4tkhzxZKXp5fLJqKTlQLHkE65XDUKutZ3BHaJC5IGcper2tT3QRD1xr4o3jNpgXXg== commondir@^1.0.1: version "1.0.1" @@ -1971,16 +2468,24 @@ concat-stream@^1.5.0, concat-stream@^1.5.2: readable-stream "^2.2.2" typedarray "^0.0.6" -configstore@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" +config@^3.3.6: + version "3.3.7" + resolved "https://registry.yarnpkg.com/config/-/config-3.3.7.tgz#4310410dc2bf4e0effdca21a12a4035860a24ee4" + integrity sha512-mX/n7GKDYZMqvvkY6e6oBY49W8wxdmQt+ho/5lhwFDXqQW9gI+Ahp8EKp8VAbISPnmf2+Bv5uZK7lKXZ6pf1aA== dependencies: - dot-prop "^4.1.0" + json5 "^2.1.1" + +configstore@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== + dependencies: + dot-prop "^5.2.0" graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" + make-dir "^3.0.0" + unique-string "^2.0.0" + write-file-atomic "^3.0.0" + xdg-basedir "^4.0.0" console-browserify@^1.1.0: version "1.2.0" @@ -1998,9 +2503,12 @@ contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" -content-disposition@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" content-type@~1.0.4: version "1.0.4" @@ -2012,25 +2520,32 @@ convert-source-map@^1.6.0, convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" -cookie-parser@~1.4.3: - version "1.4.5" - resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.5.tgz#3e572d4b7c0c80f9c61daf604e4336831b5d1d49" +cookie-parser@^1.4.5: + version "1.4.6" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.6.tgz#3ac3a7d35a7a03bbc7e365073a26074824214594" + integrity sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA== dependencies: - cookie "0.4.0" + cookie "0.4.1" cookie-signature "1.0.6" cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" -cookie@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - cookie@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" +cookie@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +cookie@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + cookiejar@^2.1.0, cookiejar@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" @@ -2081,12 +2596,6 @@ create-ecdh@^4.0.0: bn.js "^4.1.0" elliptic "^6.0.0" -create-error-class@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - dependencies: - capture-stack-trace "^1.0.0" - create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" @@ -2108,11 +2617,17 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-env@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.1.tgz#b2c76c1ca7add66dc874d11798466094f551b34d" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== dependencies: - cross-spawn "^6.0.5" + cross-spawn "^7.0.1" cross-spawn@^4: version "4.0.2" @@ -2121,14 +2636,6 @@ cross-spawn@^4: lru-cache "^4.0.1" which "^1.2.9" -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -2139,6 +2646,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.1, cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -2155,9 +2671,10 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== csrf@3.1.0: version "3.1.0" @@ -2208,14 +2725,16 @@ css-select@^2.0.0: domutils "^1.7.0" nth-check "^1.0.2" -css-select@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" +css-select@^4.1.3: + version "4.2.1" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd" + integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ== dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" + boolbase "^1.0.0" + css-what "^5.1.0" + domhandler "^4.3.0" + domutils "^2.8.0" + nth-check "^2.0.1" css-selector-tokenizer@^0.7.0: version "0.7.3" @@ -2238,14 +2757,15 @@ css-tree@1.0.0-alpha.39: mdn-data "2.0.6" source-map "^0.6.1" -css-what@2.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - css-what@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39" +css-what@^5.0.1, css-what@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" + integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== + cssesc@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" @@ -2322,9 +2842,10 @@ csso@^4.0.2: dependencies: css-tree "1.0.0-alpha.39" -csurf@^1.9.0: +csurf@^1.11.0: version "1.11.0" resolved "https://registry.yarnpkg.com/csurf/-/csurf-1.11.0.tgz#ab0c3c6634634192bd3d6f4b861be20800eeb61a" + integrity sha512-UCtehyEExKTxgiu8UHdGvHj4tnpE/Qctue03Giq5gPgMQ9cg/ciod5blZQ5a4uCEenNQjxyGuzygLdKUmee/bQ== dependencies: cookie "0.4.0" cookie-signature "1.0.6" @@ -2353,18 +2874,32 @@ debug@4: dependencies: ms "2.1.2" -debug@^3.1.0, debug@^3.2.6: +debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" dependencies: ms "^2.1.1" +debug@^4.3.1, debug@^4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -2373,6 +2908,13 @@ decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -2389,9 +2931,10 @@ deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== default-require-extensions@^2.0.0: version "2.0.0" @@ -2399,6 +2942,11 @@ default-require-extensions@^2.0.0: dependencies: strip-bom "^3.0.0" +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + defer-to-connect@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" @@ -2440,6 +2988,11 @@ depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" +depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + des.js@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" @@ -2466,10 +3019,20 @@ dicer@0.2.5: readable-stream "1.1.x" streamsearch "0.1.2" -diff@3.5.0, diff@^3.5.0: +diff@3.5.0, diff@^3.1.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diff@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -2478,6 +3041,13 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -2498,18 +3068,20 @@ dom-serializer@0: domelementtype "^2.0.1" entities "^2.0.0" -dom-serializer@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" +dom-serializer@^1.0.1, dom-serializer@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: +domelementtype@1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" @@ -2517,31 +3089,33 @@ domelementtype@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - dependencies: - domelementtype "1" +domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626" + integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g== dependencies: - dom-serializer "0" - domelementtype "1" + domelementtype "^2.2.0" -domutils@^1.5.1, domutils@^1.7.0: +domutils@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" dependencies: dom-serializer "0" domelementtype "1" -dot-prop@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" +domutils@^2.5.2, domutils@^2.7.0, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== dependencies: - is-obj "^1.0.0" + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" dot-prop@^5.2.0: version "5.2.0" @@ -2549,9 +3123,10 @@ dot-prop@^5.2.0: dependencies: is-obj "^2.0.0" -dotenv@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" +dotenv@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== duplexer3@^0.1.4: version "0.1.4" @@ -2622,9 +3197,12 @@ enhanced-resolve@^4.1.1, enhanced-resolve@^4.3.0: memory-fs "^0.5.0" tapable "^1.0.0" -entities@^1.1.1, entities@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" entities@^2.0.0: version "2.0.3" @@ -2670,14 +3248,15 @@ es6-error@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" -es6-promise@^4.2.5: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - escalade@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" +escape-goat@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" + integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2686,33 +3265,46 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -eslint-config-codex@^1.3.4: - version "1.3.6" - resolved "https://registry.yarnpkg.com/eslint-config-codex/-/eslint-config-codex-1.3.6.tgz#5f24e28326405091afeae17172dc414c1c973e83" +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-codex@^1.6.2: + version "1.6.4" + resolved "https://registry.yarnpkg.com/eslint-config-codex/-/eslint-config-codex-1.6.4.tgz#41e55d0b27a09f9d2101cf853509b317e9b09383" + integrity sha512-o1BTbzjSuOLZiEJqTeLyjy6xZTQnLSHF9yVcbYJVsDZKebtGOVjt+uKHqqEyMuGRLjhgG1Sk9Eq1C7OkrXCrgg== dependencies: - "@typescript-eslint/eslint-plugin" "^2.12.0" - "@typescript-eslint/parser" "^2.12.0" - eslint-config-standard "14.1.0" - eslint-plugin-import "2.19.1" - eslint-plugin-jsdoc "^22.1.0" - eslint-plugin-node "10.0.0" + "@typescript-eslint/eslint-plugin" "^4.6.1" + "@typescript-eslint/parser" "^4.6.1" + eslint-config-standard "16.0.1" + eslint-plugin-import "2.22.1" + eslint-plugin-jsdoc "^30.7.7" + eslint-plugin-node "11.1.0" eslint-plugin-promise "4.2.1" - eslint-plugin-standard "4.0.1" - typescript "^3.7.3" - typescript-eslint "^0.0.1-alpha.0" + eslint-plugin-standard "4.0.2" -eslint-config-standard@14.1.0: - version "14.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.0.tgz#b23da2b76fe5a2eba668374f246454e7058f15d4" +eslint-config-standard@16.0.1: + version "16.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.1.tgz#9a385eea27f96b7918cb53f07e01e9d10cc56401" + integrity sha512-WBBiQQZdaPyL+4sPkGWhWrHCDtvJoU195B9j8yXE9uFQnX34gMXI5CeBRm95gx3PMEZPM5OpwET10hH4F4SxCA== -eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.3: +eslint-import-resolver-node@^0.3.3: version "0.3.4" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" dependencies: debug "^2.6.9" resolve "^1.13.1" -eslint-module-utils@^2.4.1, eslint-module-utils@^2.6.0: +eslint-import-resolver-node@^0.3.4: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== + dependencies: + debug "^3.2.7" + resolve "^1.20.0" + +eslint-module-utils@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" dependencies: @@ -2730,29 +3322,32 @@ eslint-plugin-es@^1.3.1: eslint-utils "^1.4.2" regexpp "^2.0.1" -eslint-plugin-es@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz#0f5f5da5f18aa21989feebe8a73eadefb3432976" +eslint-plugin-es@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" + integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== dependencies: - eslint-utils "^1.4.2" + eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-import@2.19.1: - version "2.19.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.19.1.tgz#5654e10b7839d064dd0d46cd1b88ec2133a11448" +eslint-plugin-import@2.22.1: + version "2.22.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" + integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== dependencies: - array-includes "^3.0.3" - array.prototype.flat "^1.2.1" + 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.2" - eslint-module-utils "^2.4.1" + 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.0" + object.values "^1.1.1" read-pkg-up "^2.0.0" - resolve "^1.12.0" + resolve "^1.17.0" + tsconfig-paths "^3.9.0" eslint-plugin-import@^2.14.0: version "2.22.0" @@ -2772,24 +3367,26 @@ eslint-plugin-import@^2.14.0: resolve "^1.17.0" tsconfig-paths "^3.9.0" -eslint-plugin-jsdoc@^22.1.0: - version "22.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-22.2.0.tgz#b89159e01ed8eeee4f6512101e96cac6a2999461" +eslint-plugin-jsdoc@^30.7.7: + version "30.7.13" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-30.7.13.tgz#52e5c74fb806d3bbeb51d04a0c829508c3c6b563" + integrity sha512-YM4WIsmurrp0rHX6XiXQppqKB8Ne5ATiZLJe2+/fkp9l9ExXFr43BbAbjZaVrpCT+tuPYOZ8k1MICARHnURUNQ== dependencies: - comment-parser "^0.7.2" - debug "^4.1.1" - jsdoctypeparser "^6.1.0" - lodash "^4.17.15" - regextras "^0.7.0" - semver "^6.3.0" - spdx-expression-parse "^3.0.0" + comment-parser "^0.7.6" + debug "^4.3.1" + jsdoctypeparser "^9.0.0" + lodash "^4.17.20" + regextras "^0.7.1" + semver "^7.3.4" + spdx-expression-parse "^3.0.1" -eslint-plugin-node@10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz#fd1adbc7a300cf7eb6ac55cf4b0b6fc6e577f5a6" +eslint-plugin-node@11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== dependencies: - eslint-plugin-es "^2.0.0" - eslint-utils "^1.4.2" + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" ignore "^5.1.1" minimatch "^3.0.4" resolve "^1.10.1" @@ -2810,9 +3407,10 @@ eslint-plugin-promise@4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" -eslint-plugin-standard@4.0.1, eslint-plugin-standard@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" +eslint-plugin-standard@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.2.tgz#021211a9f077e63a6847e7bb9ab4247327ac8e0c" + integrity sha512-nKptN8l7jksXkwFk++PhJB3cCDTcXOEyhISIN86Ue2feJ1LFyY3PrY3/xT2keXlJSY5bpmbiTG0f885/YKAvTA== eslint-scope@^4.0.3: version "4.0.3" @@ -2821,86 +3419,106 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: - esrecurse "^4.1.0" + esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^1.3.1, eslint-utils@^1.4.2, eslint-utils@^1.4.3: +eslint-utils@^1.3.1, eslint-utils@^1.4.2: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" dependencies: eslint-visitor-keys "^1.1.0" -eslint-utils@^2.0.0: +eslint-utils@^2.0.0, eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" -eslint@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint@^7.31.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== dependencies: - "@babel/code-frame" "^7.0.0" + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" 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" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" esutils "^2.0.2" - file-entry-cache "^5.0.1" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" + glob-parent "^5.1.2" + globals "^13.6.0" 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.merge "^4.6.2" 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" - table "^5.2.3" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" -esquery@^1.0.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== dependencies: estraverse "^5.1.0" @@ -2910,6 +3528,13 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + estraverse@^4.1.0, estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" @@ -2918,6 +3543,11 @@ estraverse@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642" +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -2937,18 +3567,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -2979,38 +3597,39 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" -express@~4.16.0: - version "4.16.4" - resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" +express@^4.17.1: + version "4.17.3" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" + integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== dependencies: - accepts "~1.3.5" + accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.18.3" - content-disposition "0.5.2" + body-parser "1.19.2" + content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.3.1" + cookie "0.4.2" cookie-signature "1.0.6" debug "2.6.9" depd "~1.1.2" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.1.1" + finalhandler "~1.1.2" fresh "0.5.2" merge-descriptors "1.0.1" methods "~1.1.2" on-finished "~2.3.0" - parseurl "~1.3.2" + parseurl "~1.3.3" path-to-regexp "0.1.7" - proxy-addr "~2.0.4" - qs "6.5.2" - range-parser "~1.2.0" - safe-buffer "5.1.2" - send "0.16.2" - serve-static "1.13.2" - setprototypeof "1.1.0" - statuses "~1.4.0" - type-is "~1.6.16" + proxy-addr "~2.0.7" + qs "6.9.7" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" @@ -3031,14 +3650,6 @@ extend@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -3052,41 +3663,69 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" +fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" -fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fastparse@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + figgy-pudding@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: - escape-string-regexp "^1.0.5" + flat-cache "^3.0.4" -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" +file-type@*: + version "17.1.1" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-17.1.1.tgz#24c59bc663df0c0c181b31dfacde25e06431afbe" + integrity sha512-heRUMZHby2Qj6wZAA3YHeMlRmZNQTcb6VxctkGmM+mcM6ROQKvHpr7SS6EgdfEhH+s25LDshBjvPx/Ecm+bOVQ== dependencies: - flat-cache "^2.0.1" + readable-web-to-node-stream "^3.0.2" + strtok3 "^7.0.0-alpha.7" + token-types "^5.0.0-alpha.2" -file-type@^10.7.1: - version "10.11.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.11.0.tgz#2961d09e4675b9fb9a3ee6b69e9cd23f43fd1890" +file-type@^16.5.2: + version "16.5.3" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.3.tgz#474b7e88c74724046abb505e9b8ed4db30c4fc06" + integrity sha512-uVsl7iFhHSOY4bEONLlTK47iAHtNsFHWP5YE4xJfZ4rnX7S1Q3wce09XgqSC7E/xh8Ncv/be1lNoyprlUH/x6A== + dependencies: + readable-web-to-node-stream "^3.0.0" + strtok3 "^6.2.4" + token-types "^4.1.1" file-uri-to-path@1.0.0: version "1.0.0" @@ -3107,16 +3746,17 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== dependencies: debug "2.6.9" encodeurl "~1.0.2" escape-html "~1.0.3" on-finished "~2.3.0" - parseurl "~1.3.2" - statuses "~1.4.0" + parseurl "~1.3.3" + statuses "~1.5.0" unpipe "~1.0.0" find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: @@ -3148,17 +3788,18 @@ findup-sync@^3.0.0: micromatch "^3.0.4" resolve-dir "^1.0.1" -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" + flatted "^3.1.0" + rimraf "^3.0.2" -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" +flatted@^3.1.0: + version "3.2.5" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== flatten@^1.0.2: version "1.0.3" @@ -3194,13 +3835,23 @@ form-data@^2.3.1: combined-stream "^1.0.6" mime-types "^2.1.12" +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + formidable@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== fragment-cache@^0.2.1: version "0.2.1" @@ -3249,6 +3900,11 @@ fsevents@~2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3290,13 +3946,10 @@ get-stdin@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - -get-stream@^4.0.0: +get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== dependencies: pump "^3.0.0" @@ -3317,7 +3970,14 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0, glob-parent@~5.1.0: +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" dependencies: @@ -3334,7 +3994,7 @@ glob@7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" dependencies: @@ -3345,11 +4005,12 @@ glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -global-dirs@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== dependencies: - ini "^1.3.4" + ini "2.0.0" global-modules@^1.0.0: version "1.0.0" @@ -3387,11 +4048,24 @@ globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" +globals@^13.6.0, globals@^13.9.0: + version "13.12.1" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb" + integrity sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw== dependencies: - type-fest "^0.8.1" + type-fest "^0.20.2" + +globby@^11.0.3: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" gonzales-pe@^4.0.3: version "4.3.0" @@ -3399,37 +4073,39 @@ gonzales-pe@^4.0.3: dependencies: minimist "^1.2.5" -got@^11.5.1: - version "11.5.1" - resolved "https://registry.yarnpkg.com/got/-/got-11.5.1.tgz#bf098a270fe80b3fb88ffd5a043a59ebb0a391db" +got@^11.8.2: + version "11.8.3" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770" + integrity sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg== dependencies: - "@sindresorhus/is" "^3.0.0" + "@sindresorhus/is" "^4.0.0" "@szmarczak/http-timer" "^4.0.5" "@types/cacheable-request" "^6.0.1" "@types/responselike" "^1.0.0" cacheable-lookup "^5.0.3" - cacheable-request "^7.0.1" + cacheable-request "^7.0.2" decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.0" + http2-wrapper "^1.0.0-beta.5.2" lowercase-keys "^2.0.0" p-cancelable "^2.0.0" responselike "^2.0.0" -got@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== dependencies: - create-error-class "^3.0.0" + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-redirect "^1.0.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - unzip-response "^2.0.1" - url-parse-lax "^1.0.0" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2: version "4.2.4" @@ -3488,6 +4164,11 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" +has-yarn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" + integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== + has@^1.0.0, has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -3561,31 +4242,32 @@ html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" -htmlparser2@^3.9.1: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" http-cache-semantics@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" -http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" +http-errors@1.8.1, http-errors@^1.8.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== dependencies: depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" -http-errors@~1.7.1, http-errors@~1.7.3: +http-errors@~1.7.3: version "1.7.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" dependencies: @@ -3595,9 +4277,10 @@ http-errors@~1.7.1, http-errors@~1.7.3: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http2-wrapper@^1.0.0-beta.5.0: - version "1.0.0-beta.5.2" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz#8b923deb90144aea65cf834b016a340fc98556f3" +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== dependencies: quick-lru "^5.1.1" resolve-alpn "^1.0.0" @@ -3628,21 +4311,17 @@ husky@^1.1.2: run-node "^1.0.0" slash "^2.0.0" -iconv-lite@0.4.23: - version "0.4.23" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@^0.4.24: +iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" @@ -3660,6 +4339,11 @@ ieee754@^1.1.4: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" @@ -3676,6 +4360,11 @@ ignore@^5.0.2, ignore@^5.1.1: version "5.1.8" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" +ignore@^5.1.8, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -3700,6 +4389,14 @@ import-fresh@^3.0.0: parent-module "^1.0.0" resolve-from "^4.0.0" +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-from@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" @@ -3748,28 +4445,15 @@ inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" -inquirer@^7.0.0: - version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.19" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.6.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - interpret@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" @@ -3836,12 +4520,6 @@ is-callable@^1.1.4, is-callable@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - dependencies: - ci-info "^1.5.0" - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -3859,6 +4537,13 @@ is-color-stop@^1.0.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" +is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -3935,12 +4620,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" + global-dirs "^3.0.0" + is-path-inside "^3.0.2" is-ip@^2.0.0: version "2.0.0" @@ -3948,9 +4634,10 @@ is-ip@^2.0.0: dependencies: ip-regex "^2.0.0" -is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" +is-npm@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" + integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== is-number@^3.0.0: version "3.0.0" @@ -3962,19 +4649,14 @@ is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - dependencies: - path-is-inside "^1.0.1" +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" @@ -3982,10 +4664,6 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - is-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" @@ -3996,11 +4674,7 @@ is-resolvable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" -is-retry-allowed@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - -is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: +is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -4020,6 +4694,11 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.1" +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -4028,6 +4707,11 @@ is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" +is-yarn-global@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" + integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -4111,9 +4795,10 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsdoctypeparser@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz#acfb936c26300d98f1405cb03e20b06748e512a8" +jsdoctypeparser@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/jsdoctypeparser/-/jsdoctypeparser-9.0.0.tgz#8c97e2fb69315eb274b0f01377eaa5c940bd7b26" + integrity sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw== jsesc@^2.5.1: version "2.5.2" @@ -4123,6 +4808,11 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -4135,6 +4825,11 @@ json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" @@ -4145,15 +4840,23 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + json5@^2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" dependencies: minimist "^1.2.5" -jsonwebtoken@^8.4.0: +jsonwebtoken@^8.5.1: version "8.5.1" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== dependencies: jws "^3.2.2" lodash.includes "^4.3.0" @@ -4185,6 +4888,13 @@ jws@^3.2.2: jwa "^1.4.1" safe-buffer "^5.0.1" +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + keyv@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.1.tgz#9fe703cb4a94d6d11729d320af033307efd02ee6" @@ -4211,11 +4921,12 @@ kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" -latest-version@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" +latest-version@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== dependencies: - package-json "^4.0.0" + package-json "^6.3.0" lcid@^2.0.0: version "2.0.0" @@ -4233,12 +4944,13 @@ levenary@^1.1.1: dependencies: leven "^3.1.0" -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" + prelude-ls "^1.2.1" + type-check "~0.4.0" lie@3.1.1: version "3.1.1" @@ -4296,16 +5008,20 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -locutus@^2.0.5: - version "2.0.11" - resolved "https://registry.yarnpkg.com/locutus/-/locutus-2.0.11.tgz#83f85109971fd3dd620482a04381916e4a31d4f0" - dependencies: - es6-promise "^4.2.5" +locutus@^2.0.11: + version "2.0.16" + resolved "https://registry.yarnpkg.com/locutus/-/locutus-2.0.16.tgz#1da15532f1d735712a27e35a1caf0ccb7041f6b3" + integrity sha512-pGfl6Hb/1mXLzrX5kl5lH7gz25ey0vwQssZp8Qo2CEF59di6KrAgdFm+0pW8ghLnvNzzJGj5tlWhhv2QbK3jeQ== lodash.flattendeep@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" @@ -4334,27 +5050,32 @@ lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4: +lodash@^4.17.11, lodash@^4.17.19, lodash@^4.17.4: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" -lolex@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-4.2.0.tgz#ddbd7f6213ca1ea5826901ab1222b65d714b3cd7" - -lolex@^5.0.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" - dependencies: - "@sinonjs/commons" "^1.7.0" +lodash@^4.17.20: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== loose-envify@^1.0.0: version "1.4.0" @@ -4362,9 +5083,10 @@ loose-envify@^1.0.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -lowercase-keys@^1.0.0: +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== lowercase-keys@^2.0.0: version "2.0.0" @@ -4389,7 +5111,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -make-dir@^1.0.0, make-dir@^1.3.0: +make-dir@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" dependencies: @@ -4402,12 +5124,17 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.1.0: +make-dir@^3.0.0, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" dependencies: semver "^6.0.0" +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + map-age-cleaner@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -4476,6 +5203,11 @@ merge-source-map@^1.1.0: dependencies: source-map "^0.6.1" +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -4498,6 +5230,14 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -4509,29 +5249,39 @@ mime-db@1.44.0: version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" +mime-db@1.51.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + mime-types@^2.1.12, mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" dependencies: mime-db "1.44.0" -mime@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" +mime-types@~2.1.34: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" -mime@^1.4.1: +mime@1.6.0, mime@^1.4.1: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.4.0: - version "2.4.6" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" +mime@^2.5.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== -mimic-fn@^2.0.0, mimic-fn@^2.1.0: +mimic-fn@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" -mimic-response@^1.0.0: +mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" @@ -4610,19 +5360,21 @@ mkdirp@0.5.1: dependencies: minimist "0.0.8" -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" -mkdirp@^1.0.3: +mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" -mocha-sinon@^2.1.0: +mocha-sinon@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/mocha-sinon/-/mocha-sinon-2.1.2.tgz#8db30195fa45611e565a9f1743ffd0cb4bf1eb9d" + integrity sha512-j6eIQGgOFddcgE1kUFKSvXR9oCuSEiRzv2XUK4iJcntObi2X2vYDvRwvOWxECUZl2dJ+Ciex5fYYni05Lx4azA== mocha@^5.2.0: version "5.2.0" @@ -4644,15 +5396,16 @@ module-dispatcher@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/module-dispatcher/-/module-dispatcher-2.0.0.tgz#67701ff90cca9b51d500be4782abb1014ccb2b10" -morgan@~1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" +morgan@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" + integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== dependencies: - basic-auth "~2.0.0" + basic-auth "~2.0.1" debug "2.6.9" - depd "~1.1.2" + depd "~2.0.0" on-finished "~2.3.0" - on-headers "~1.0.1" + on-headers "~1.0.2" move-concurrently@^1.0.1: version "1.0.1" @@ -4673,23 +5426,25 @@ ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" -multer@^1.3.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.2.tgz#2f1f4d12dbaeeba74cb37e623f234bf4d3d2057a" +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multer@^1.4.2: + version "1.4.4" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.4.tgz#e2bc6cac0df57a8832b858d7418ccaa8ebaf7d8c" + integrity sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw== dependencies: append-field "^1.0.0" busboy "^0.2.11" concat-stream "^1.5.2" - mkdirp "^0.5.1" + mkdirp "^0.5.4" object-assign "^4.1.1" on-finished "^2.3.0" type-is "^1.6.4" xtend "^4.0.0" -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - nan@^2.12.1: version "2.14.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" @@ -4728,9 +5483,10 @@ nedb@^1.8.0: mkdirp "~0.5.1" underscore "~1.4.4" -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== neo-async@^2.5.0, neo-async@^2.6.1: version "2.6.2" @@ -4740,14 +5496,15 @@ nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" -nise@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/nise/-/nise-1.5.3.tgz#9d2cfe37d44f57317766c6e9408a359c5d3ac1f7" +nise@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.1.tgz#ac4237e0d785ecfcb83e20f389185975da5c31f3" + integrity sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A== dependencies: - "@sinonjs/formatio" "^3.2.1" + "@sinonjs/commons" "^1.8.3" + "@sinonjs/fake-timers" ">=5" "@sinonjs/text-encoding" "^0.7.1" just-extend "^4.0.2" - lolex "^5.0.1" path-to-regexp "^1.7.0" node-addon-api@^3.1.0: @@ -4790,20 +5547,21 @@ node-releases@^1.1.58: version "1.1.60" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084" -nodemon@^1.18.3: - version "1.19.4" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-1.19.4.tgz#56db5c607408e0fdf8920d2b444819af1aae0971" +nodemon@^2.0.12: + version "2.0.15" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.15.tgz#504516ce3b43d9dc9a955ccd9ec57550a31a8d4e" + integrity sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA== dependencies: - chokidar "^2.1.8" - debug "^3.2.6" + chokidar "^3.5.2" + debug "^3.2.7" ignore-by-default "^1.0.1" minimatch "^3.0.4" - pstree.remy "^1.1.7" + pstree.remy "^1.1.8" semver "^5.7.1" supports-color "^5.5.0" touch "^3.1.0" - undefsafe "^2.0.2" - update-notifier "^2.5.0" + undefsafe "^2.0.5" + update-notifier "^5.1.0" nopt@^5.0.0: version "5.0.0" @@ -4848,6 +5606,11 @@ normalize-url@^4.1.0: version "4.5.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + normalize.css@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-8.0.1.tgz#9b98a208738b9cc2634caacbc42d131c97487bf3" @@ -4867,12 +5630,19 @@ npmlog@^4.1.2: gauge "~2.7.3" set-blocking "~2.0.0" -nth-check@^1.0.2, nth-check@~1.0.1: +nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" dependencies: boolbase "~1.0.0" +nth-check@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" + integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== + dependencies: + boolbase "^1.0.0" + num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" @@ -4973,9 +5743,10 @@ on-finished@^2.3.0, on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.0.1: +on-headers@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" @@ -4983,32 +5754,28 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -onetime@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" +open-graph-scraper@^4.9.0: + version "4.11.0" + resolved "https://registry.yarnpkg.com/open-graph-scraper/-/open-graph-scraper-4.11.0.tgz#ac342e2a3365d2b62c557d066e0eef5328245665" + integrity sha512-APlovc5JOWXXUIyNc/1o340ik5d7RA/0TBTRMxpOMvsUXX4/uyjpHQijBUU7NxhjJpDHpc3d/lg7KcHBaSpKEw== dependencies: - mimic-fn "^2.1.0" + chardet "^1.4.0" + cheerio "^1.0.0-rc.10" + got "^11.8.2" + iconv-lite "^0.6.3" + validator "^13.7.0" -open-graph-scraper@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/open-graph-scraper/-/open-graph-scraper-4.5.0.tgz#498c45e0481f57e66c001c0a57e6793dd599bbcb" +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: - chardet "^1.2.1" - cheerio "^1.0.0-rc.3" - got "^11.5.1" - iconv-lite "^0.6.2" - validator "^13.0.0" - -optionator@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - dependencies: - 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-browserify@^0.3.0: version "0.3.0" @@ -5026,9 +5793,10 @@ os-locale@^3.0.0: lcid "^2.0.0" mem "^4.0.0" -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== p-cancelable@^2.0.0: version "2.0.0" @@ -5087,14 +5855,15 @@ package-hash@^3.0.0: lodash.flattendeep "^4.4.0" release-zalgo "^1.0.0" -package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" +package-json@^6.3.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" pako@~1.0.5: version "1.0.11" @@ -5142,15 +5911,22 @@ parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" -parse5@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" +parse5-htmlparser2-tree-adapter@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== dependencies: - "@types/node" "*" + parse5 "^6.0.1" -parseurl@~1.3.2: +parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== pascalcase@^0.1.1: version "0.1.1" @@ -5172,18 +5948,24 @@ path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" @@ -5206,6 +5988,11 @@ path-type@^3.0.0: dependencies: pify "^3.0.0" +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + pathval@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" @@ -5220,10 +6007,25 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" +peek-readable@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" + integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== + +peek-readable@^5.0.0-alpha.5: + version "5.0.0-alpha.5" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0-alpha.5.tgz#ace5dfedf7bc33f17c9b5170b9d54f69a4fba79b" + integrity sha512-pJohF/tDwV3ntnT5+EkUo4E700q/j/OCDuPxtM+5/kFGjyOai/sK4/We4Cy1MB2OiTQliWU5DxPvYIKQAdPqAA== + picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" +picomatch@^2.2.3: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -5688,13 +6490,15 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2 source-map "^0.6.1" supports-color "^6.1.0" -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= process-nextick-args@~2.0.0: version "2.0.1" @@ -5718,11 +6522,12 @@ promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" -proxy-addr@~2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== dependencies: - forwarded "~0.1.2" + forwarded "0.2.0" ipaddr.js "1.9.1" prr@~1.0.1: @@ -5733,9 +6538,10 @@ pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" -pstree.remy@^1.1.7: +pstree.remy@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== public-encrypt@^4.0.0: version "4.0.3" @@ -5782,13 +6588,21 @@ punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" +pupa@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== + dependencies: + escape-goat "^2.0.0" + q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" -qs@6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" +qs@6.9.7: + version "6.9.7" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" + integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== qs@^6.5.1: version "6.9.4" @@ -5802,6 +6616,11 @@ querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" @@ -5823,22 +6642,25 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -range-parser@~1.2.0: +range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" +raw-body@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" + integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== dependencies: - bytes "3.0.0" - http-errors "1.6.3" - iconv-lite "0.4.23" + bytes "3.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" unpipe "1.0.0" -rc@^1.0.1, rc@^1.1.6: +rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: deep-extend "^0.6.0" ini "~1.3.0" @@ -5910,7 +6732,7 @@ readable-stream@1.1.x: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^3.1.1, readable-stream@^3.6.0: +readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" dependencies: @@ -5918,6 +6740,13 @@ readable-stream@^3.1.1, readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-web-to-node-stream@^3.0.0, readable-web-to-node-stream@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== + dependencies: + readable-stream "^3.6.0" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -5932,6 +6761,13 @@ readdirp@~3.4.0: dependencies: picomatch "^2.2.1" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + regenerate-unicode-properties@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" @@ -5971,6 +6807,11 @@ regexpp@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" +regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + regexpu-core@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" @@ -5982,22 +6823,24 @@ regexpu-core@^4.7.0: unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.2.0" -regextras@^0.7.0: +regextras@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.7.1.tgz#be95719d5f43f9ef0b9fa07ad89b7c606995a3b2" + integrity sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w== -registry-auth-token@^3.0.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" +registry-auth-token@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" + rc "^1.2.8" -registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== dependencies: - rc "^1.0.1" + rc "^1.2.8" regjsgen@^0.5.1: version "0.5.2" @@ -6031,6 +6874,11 @@ require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" @@ -6074,23 +6922,37 @@ resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.1 dependencies: path-parse "^1.0.6" +resolve@^1.20.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + responselike@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" dependencies: lowercase-keys "^2.0.0" -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rgb-regex@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" @@ -6099,12 +6961,6 @@ rgba-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - dependencies: - glob "^7.1.3" - rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" @@ -6128,33 +6984,31 @@ rndm@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/rndm/-/rndm-1.2.0.tgz#f33fe9cfb52bbfd520aa18323bc65db110a1b76c" -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - run-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" dependencies: aproba "^1.1.1" -rxjs@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.0.tgz#af2901eedf02e3a83ffa7f886240ff9018bbec84" - dependencies: - tslib "^1.9.0" - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-regex@^1.1.0: version "1.1.0" @@ -6190,13 +7044,14 @@ semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" -semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" +semver-diff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" + integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== dependencies: - semver "^5.0.3" + semver "^6.3.0" -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -6204,23 +7059,20 @@ semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" -semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.0, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" -semver@^7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - -semver@^7.3.4: +semver@^7.2.1, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" dependencies: lru-cache "^6.0.0" -send@0.16.2: - version "0.16.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== dependencies: debug "2.6.9" depd "~1.1.2" @@ -6229,12 +7081,12 @@ send@0.16.2: escape-html "~1.0.3" etag "~1.8.1" fresh "0.5.2" - http-errors "~1.6.2" - mime "1.4.1" - ms "2.0.0" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" on-finished "~2.3.0" - range-parser "~1.2.0" - statuses "~1.4.0" + range-parser "~1.2.1" + statuses "~1.5.0" serialize-javascript@^3.1.0: version "3.1.0" @@ -6242,14 +7094,15 @@ serialize-javascript@^3.1.0: dependencies: randombytes "^2.1.0" -serve-static@1.13.2: - version "1.13.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" +serve-static@1.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" - parseurl "~1.3.2" - send "0.16.2" + parseurl "~1.3.3" + send "0.17.2" set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" @@ -6268,14 +7121,15 @@ setimmediate@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - setprototypeof@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" @@ -6289,10 +7143,22 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -6303,29 +7169,35 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" -sinon@^7.0.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-7.5.0.tgz#e9488ea466070ea908fd44a3d6478fd4923c67ec" +sinon@^11.1.2: + version "11.1.2" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-11.1.2.tgz#9e78850c747241d5c59d1614d8f9cbe8840e8674" + integrity sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw== dependencies: - "@sinonjs/commons" "^1.4.0" - "@sinonjs/formatio" "^3.2.1" - "@sinonjs/samsam" "^3.3.3" - diff "^3.5.0" - lolex "^4.2.0" - nise "^1.5.2" - supports-color "^5.5.0" + "@sinonjs/commons" "^1.8.3" + "@sinonjs/fake-timers" "^7.1.2" + "@sinonjs/samsam" "^6.0.2" + diff "^5.0.0" + nise "^5.1.0" + supports-color "^7.2.0" slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" snapdragon-node@^2.0.1: version "2.1.1" @@ -6368,6 +7240,14 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@^0.5.6: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-support@~0.5.12: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" @@ -6409,7 +7289,7 @@ spdx-exceptions@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" -spdx-expression-parse@^3.0.0: +spdx-expression-parse@^3.0.0, spdx-expression-parse@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" dependencies: @@ -6447,14 +7327,10 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2": +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" -statuses@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" - stream-browserify@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" @@ -6510,6 +7386,15 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string-width@^4.0.0, string-width@^4.2.2, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" @@ -6572,6 +7457,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -6580,14 +7472,31 @@ strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" -strip-json-comments@^3.0.1: +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" +strtok3@^6.2.4: + version "6.3.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" + integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^4.1.0" + +strtok3@^7.0.0-alpha.7: + version "7.0.0-alpha.8" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0-alpha.8.tgz#23a7870974e0494b58b14af6dd1c2c67cf13314d" + integrity sha512-u+k19v+rTxBjGYxncRQjGvZYwYvEd0uP3D+uHKe/s4WB1eXS5ZwpZsTlBu5xSS4zEd89mTXECXg6WW3FSeV8cA== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^5.0.0-alpha.5" + stylehacks@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" @@ -6645,6 +7554,18 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + svgo@^1.0.0: version "1.3.2" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" @@ -6663,14 +7584,16 @@ svgo@^1.0.0: unquote "~1.1.1" util.promisify "~1.0.0" -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" +table@^6.0.9: + version "6.8.0" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" + integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" + ajv "^8.0.1" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" @@ -6687,12 +7610,6 @@ tar@^6.1.0: mkdirp "^1.0.3" yallist "^4.0.0" -term-size@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - dependencies: - execa "^0.7.0" - terser-webpack-plugin@^1.4.3: version "1.4.4" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz#2c63544347324baafa9a56baaddf1634c8abfc2f" @@ -6735,14 +7652,6 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - -timed-out@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - timers-browserify@^2.0.4: version "2.0.11" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" @@ -6753,12 +7662,6 @@ timsort@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - dependencies: - os-tmpdir "~1.0.2" - to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -6773,6 +7676,11 @@ to-object-path@^0.3.0: dependencies: kind-of "^3.0.2" +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" @@ -6799,12 +7707,85 @@ toidentifier@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +token-types@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.0.tgz#b66bc3d67420c6873222a424eee64a744f4c2f13" + integrity sha512-P0rrp4wUpefLncNamWIef62J0v0kQR/GfDVji9WKY7GDCWy5YbVSrKUTam07iWPZQGy0zWNOfstYTykMmPNR7w== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + +token-types@^5.0.0-alpha.2: + version "5.0.0-alpha.2" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.0-alpha.2.tgz#e43d63b2a8223a593d1c782a5149bec18f1abf97" + integrity sha512-EsG9UxAW4M6VATrEEjhPFTKEUi1OiJqTUMIZOGBN49fGxYjZB36k0p7to3HZSmWRoHm1QfZgrg3e02fpqAt5fQ== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + touch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" dependencies: nopt "~1.0.10" +ts-mocha@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-8.0.0.tgz#962d0fa12eeb6468aa1a6b594bb3bbc818da3ef0" + integrity sha512-Kou1yxTlubLnD5C3unlCVO7nh0HERTezjoVhVw/M5S1SqoUec0WgllQvPk3vzPMc6by8m6xD1uR1yRf8lnVUbA== + dependencies: + ts-node "7.0.1" + optionalDependencies: + tsconfig-paths "^3.5.0" + +ts-node@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" + integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== + dependencies: + arrify "^1.0.0" + buffer-from "^1.1.0" + diff "^3.1.0" + make-error "^1.1.1" + minimist "^1.2.0" + mkdirp "^0.5.1" + source-map-support "^0.5.6" + yn "^2.0.0" + +ts-node@^10.1.0: + version "10.6.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.6.0.tgz#c3f4195d5173ce3affdc8f2fd2e9a7ac8de5376a" + integrity sha512-CJen6+dfOXolxudBQXnVjRVvYTmTWbyz7cn+xq2XTsvnaXbHqr4gXSCNbS2Jj8yTZMuGwUoBESLaOkLascVVvg== + dependencies: + "@cspotcode/source-map-support" "0.7.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.0" + yn "3.1.1" + +tsconfig-paths@^3.5.0: + version "3.13.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz#f3e9b8f6876698581d94470c03c95b3a48c0e3d7" + integrity sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + tsconfig-paths@^3.9.0: version "3.9.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" @@ -6818,13 +7799,19 @@ tslib@^1.8.1, tslib@^1.9.0: version "1.13.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" +tslib@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + tsscmp@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" -tsutils@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" @@ -6832,39 +7819,47 @@ tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" -twig@~1.12.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/twig/-/twig-1.12.0.tgz#04450bf18ee05532ff70098f10b07227f956b8cf" +twig@^1.15.4: + version "1.15.4" + resolved "https://registry.yarnpkg.com/twig/-/twig-1.15.4.tgz#314b00eaf98a57e70ed7dcfd6def93d0d8f3d627" + integrity sha512-gRpGrpdf+MswqF6eSjEdYZTa/jt3ZWHK/NU59IbTYJMBQXJ1W+7IxaGEwLkQjd+mNT15j9sQTzQumxUBkuQueQ== dependencies: - locutus "^2.0.5" + "@babel/runtime" "^7.8.4" + locutus "^2.0.11" minimatch "3.0.x" walk "2.3.x" -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: - prelude-ls "~1.1.2" + prelude-ls "^1.2.1" -type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5: +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" -type-fest@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - -type-is@^1.6.4, type-is@~1.6.16: +type-is@^1.6.4, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== dependencies: media-typer "0.3.0" mime-types "~2.1.24" +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -6873,9 +7868,10 @@ typescript-eslint@^0.0.1-alpha.0: version "0.0.1-alpha.0" resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-0.0.1-alpha.0.tgz#285d68a4e96588295cd436278801bcb6a6b916c1" -typescript@^3.7.3: - version "3.9.7" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" +typescript@^4.3.5: + version "4.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4" + integrity sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg== uid-safe@2.1.5: version "2.1.5" @@ -6883,11 +7879,10 @@ uid-safe@2.1.5: dependencies: random-bytes "~1.0.0" -undefsafe@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" - dependencies: - debug "^2.2.0" +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== underscore@~1.4.4: version "1.4.4" @@ -6941,11 +7936,12 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== dependencies: - crypto-random-string "^1.0.0" + crypto-random-string "^2.0.0" unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" @@ -6962,28 +7958,29 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - upath@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" -update-notifier@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" +update-notifier@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" + integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" + boxen "^5.0.0" + chalk "^4.1.0" + configstore "^5.0.1" + has-yarn "^2.1.0" import-lazy "^2.1.0" - is-ci "^1.0.10" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" + is-ci "^2.0.0" + is-installed-globally "^0.4.0" + is-npm "^5.0.0" + is-yarn-global "^0.3.0" + latest-version "^5.1.0" + pupa "^2.1.1" + semver "^7.3.4" + semver-diff "^3.1.1" + xdg-basedir "^4.0.0" uri-js@^4.2.2: version "4.2.2" @@ -6995,11 +7992,12 @@ urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= dependencies: - prepend-http "^1.0.1" + prepend-http "^2.0.0" url@^0.11.0: version "0.11.0" @@ -7041,14 +8039,20 @@ utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" -uuid4@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/uuid4/-/uuid4-1.1.4.tgz#80fa0618749110bdb8aa47cc2cc2167c6331f4eb" +uuid4@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/uuid4/-/uuid4-2.0.2.tgz#d33169f4a8fe84b217f50a0f28f971cd9ff56216" + integrity sha512-TzsQS8sN1B2m9WojyNp0X/3JL8J2RScnrAJnooNPL6lq3lA02/XdoWysyUgI6rAif0DzkkWk51N6OggujPy2RA== uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" +v8-compile-cache-lib@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" + integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA== + v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" @@ -7060,9 +8064,10 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -validator@^13.0.0: - version "13.1.1" - resolved "https://registry.yarnpkg.com/validator/-/validator-13.1.1.tgz#f8811368473d2173a9d8611572b58c5783f223bf" +validator@^13.7.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" + integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== vary@~1.1.2: version "1.1.2" @@ -7159,21 +8164,30 @@ which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" dependencies: string-width "^1.0.2 || 2" -widest-line@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== dependencies: - string-width "^2.1.1" + string-width "^4.0.0" -word-wrap@~1.2.3: +word-wrap@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== worker-farm@^1.7.0: version "1.7.0" @@ -7196,11 +8210,20 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -write-file-atomic@^2.0.0, write-file-atomic@^2.4.2: +write-file-atomic@^2.4.2: version "2.4.3" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" dependencies: @@ -7208,15 +8231,20 @@ write-file-atomic@^2.0.0, write-file-atomic@^2.4.2: imurmurhash "^0.1.4" signal-exit "^3.0.2" -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: - mkdirp "^0.5.1" + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" @@ -7283,3 +8311,13 @@ yargs@^13.3.2: which-module "^2.0.0" y18n "^4.0.0" yargs-parser "^13.1.2" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=