From 562431449b67f7cd17f9e0c2f78430418805b77a Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sat, 20 Feb 2021 20:18:03 +0100 Subject: [PATCH 01/13] Allow users to remove their password in case they forget it Closes #23 --- src/Mails.ts | 5 +++ src/auth/AccountController.ts | 39 +++++++++++++--- .../magic_link/AuthMagicLinkActionType.ts | 1 + src/auth/magic_link/MagicLinkController.ts | 24 ++++++++++ src/auth/password/UserPasswordComponent.ts | 6 ++- views/auth/account.njk | 18 ++------ views/auth/password_panel.njk | 45 +++++++++++++++++++ views/mails/remove_password.mjml.njk | 27 +++++++++++ 8 files changed, 144 insertions(+), 21 deletions(-) create mode 100644 views/auth/password_panel.njk create mode 100644 views/mails/remove_password.mjml.njk diff --git a/src/Mails.ts b/src/Mails.ts index b1d619f..0208a9c 100644 --- a/src/Mails.ts +++ b/src/Mails.ts @@ -22,3 +22,8 @@ export const ADD_EMAIL_MAIL_TEMPLATE: MailTemplate = new MailTemplate( 'add_email', (data) => `Add ${data.email} address to your ${config.get('app.name')} account.`, ); + +export const REMOVE_PASSWORD_MAIL_TEMPLATE: MailTemplate = new MailTemplate( + 'remove_password', + () => `Remove password from your ${config.get('app.name')} account.`, +); diff --git a/src/auth/AccountController.ts b/src/auth/AccountController.ts index a68d0e4..851c0ac 100644 --- a/src/auth/AccountController.ts +++ b/src/auth/AccountController.ts @@ -10,15 +10,16 @@ import ModelFactory from "../db/ModelFactory"; import UserEmail from "./models/UserEmail"; import MagicLinkController from "./magic_link/MagicLinkController"; import {MailTemplate} from "../mail/Mail"; -import {ADD_EMAIL_MAIL_TEMPLATE} from "../Mails"; +import {ADD_EMAIL_MAIL_TEMPLATE, REMOVE_PASSWORD_MAIL_TEMPLATE} from "../Mails"; import AuthMagicLinkActionType from "./magic_link/AuthMagicLinkActionType"; export default class AccountController extends Controller { - private readonly addEmailMailTemplate: MailTemplate; - public constructor(addEmailMailTemplate: MailTemplate = ADD_EMAIL_MAIL_TEMPLATE) { + public constructor( + private readonly addEmailMailTemplate: MailTemplate = ADD_EMAIL_MAIL_TEMPLATE, + private readonly removePasswordMailTemplate: MailTemplate = REMOVE_PASSWORD_MAIL_TEMPLATE, + ) { super(); - this.addEmailMailTemplate = addEmailMailTemplate; } public getRoutesPrefix(): string { @@ -30,6 +31,7 @@ export default class AccountController extends Controller { if (ModelFactory.get(User).hasComponent(UserPasswordComponent)) { this.post('/change-password', this.postChangePassword, 'change-password', RequireAuthMiddleware); + this.post('/remove-password', this.postRemovePassword, 'remove-password', RequireAuthMiddleware); } this.post('/add-email', this.addEmail, 'add-email', RequireAuthMiddleware); @@ -40,11 +42,13 @@ export default class AccountController extends Controller { protected async getAccount(req: Request, res: Response): Promise { const user = req.as(RequireAuthMiddleware).getUser(); + const passwordComponent = user.asOptional(UserPasswordComponent); res.render('auth/account', { main_email: await user.mainEmail.get(), emails: await user.emails.get(), display_email_warning: config.get('app.display_email_warning'), - has_password: user.asOptional(UserPasswordComponent)?.hasPassword(), + has_password_component: !!passwordComponent, + has_password: passwordComponent?.hasPassword(), }); } @@ -69,6 +73,31 @@ export default class AccountController extends Controller { res.redirect(Controller.route('account')); } + protected async postRemovePassword(req: Request, res: Response): Promise { + const user = req.as(RequireAuthMiddleware).getUser(); + const mainEmail = await user.mainEmail.get(); + if (!mainEmail || !mainEmail.email) { + req.flash('error', 'You can\'t remove your password without adding an email address first.'); + res.redirect(Controller.route('account')); + + return; + } + + await MagicLinkController.sendMagicLink( + this.getApp(), + req.getSession().id, + AuthMagicLinkActionType.REMOVE_PASSWORD, + Controller.route('account'), + mainEmail.email, + this.removePasswordMailTemplate, + {}, + ); + + res.redirect(Controller.route('magic_link_lobby', undefined, { + redirect_uri: Controller.route('account'), + })); + } + protected async addEmail(req: Request, res: Response): Promise { await Validator.validate({ diff --git a/src/auth/magic_link/AuthMagicLinkActionType.ts b/src/auth/magic_link/AuthMagicLinkActionType.ts index 7e907cf..33bb26b 100644 --- a/src/auth/magic_link/AuthMagicLinkActionType.ts +++ b/src/auth/magic_link/AuthMagicLinkActionType.ts @@ -2,4 +2,5 @@ export default { LOGIN: 'login', REGISTER: 'register', ADD_EMAIL: 'add_email', + REMOVE_PASSWORD: 'remove_password', }; diff --git a/src/auth/magic_link/MagicLinkController.ts b/src/auth/magic_link/MagicLinkController.ts index e10163f..2aca47c 100644 --- a/src/auth/magic_link/MagicLinkController.ts +++ b/src/auth/magic_link/MagicLinkController.ts @@ -18,6 +18,7 @@ import {QueryVariable} from "../../db/MysqlConnectionManager"; import UserNameComponent from "../models/UserNameComponent"; import MagicLinkUserNameComponent from "../models/MagicLinkUserNameComponent"; import {logger} from "../../Logger"; +import UserPasswordComponent from "../password/UserPasswordComponent"; export default class MagicLinkController extends Controller { public static async sendMagicLink( @@ -233,6 +234,29 @@ export default class MagicLinkController extends Controll res.redirect(Controller.route('account')); break; } + + case AuthMagicLinkActionType.REMOVE_PASSWORD: { + const session = req.getSessionOptional(); + if (!session || magicLink.session_id !== session.id) throw new BadOwnerMagicLink(); + + await magicLink.delete(); + + const authGuard = this.getApp().as(AuthComponent).getAuthGuard(); + const proofs = await authGuard.getProofsForSession(session); + const user = await proofs[0]?.getResource(); + if (!user) return; + + const passwordComponent = user.asOptional(UserPasswordComponent); + if (passwordComponent) { + passwordComponent.removePassword(); + await user.save(); + } + + req.flash('success', `Password successfully removed.`); + res.redirect(Controller.route('account')); + break; + } + default: logger.warn('Unknown magic link action type ' + magicLink.action_type); break; diff --git a/src/auth/password/UserPasswordComponent.ts b/src/auth/password/UserPasswordComponent.ts index e1c25a7..a8bbc13 100644 --- a/src/auth/password/UserPasswordComponent.ts +++ b/src/auth/password/UserPasswordComponent.ts @@ -6,7 +6,7 @@ import Validator from "../../db/Validator"; export default class UserPasswordComponent extends ModelComponent { public static readonly PASSWORD_MIN_LENGTH = 12; - private password?: string = undefined; + private password?: string | null = undefined; public init(): void { this.setValidation('password').acceptUndefined().maxLength(128); @@ -36,4 +36,8 @@ export default class UserPasswordComponent extends ModelComponent { public hasPassword(): boolean { return typeof this.password === 'string'; } + + public removePassword(): void { + this.password = null; + } } diff --git a/views/auth/account.njk b/views/auth/account.njk index 77925ad..6f4e633 100644 --- a/views/auth/account.njk +++ b/views/auth/account.njk @@ -22,21 +22,9 @@ {% endif %} -
-

{% if has_password %}Change{% else %}Set{% endif %} password

- -
- {% if has_password %} - {{ macros.field(_locals, 'password', 'current_password', null, 'Current password') }} - {% endif %} - {{ macros.field(_locals, 'password', 'new_password', null, 'New password') }} - {{ macros.field(_locals, 'password', 'new_password_confirmation', null, 'New password confirmation') }} - - - - {{ macros.csrf(getCsrfToken) }} -
-
+ {% if has_password_component %} + {% include './password_panel.njk' %} + {% endif %}

Email addresses

diff --git a/views/auth/password_panel.njk b/views/auth/password_panel.njk new file mode 100644 index 0000000..fe5dbd1 --- /dev/null +++ b/views/auth/password_panel.njk @@ -0,0 +1,45 @@ +
+

{% if has_password %}Change{% else %}Set{% endif %} password

+ +
+ {% if has_password %} + {{ macros.field(_locals, 'password', 'current_password', null, 'Current password') }} +

Forgot your password?

+ {% endif %} + {{ macros.field(_locals, 'password', 'new_password', null, 'New password') }} + {{ macros.field(_locals, 'password', 'new_password_confirmation', null, 'New password confirmation') }} + + + + {{ macros.csrf(getCsrfToken) }} +
+ + {% if has_password %} + + + + {% endif %} +
diff --git a/views/mails/remove_password.mjml.njk b/views/mails/remove_password.mjml.njk new file mode 100644 index 0000000..5681303 --- /dev/null +++ b/views/mails/remove_password.mjml.njk @@ -0,0 +1,27 @@ +{% extends 'mails/base_layout.mjml.njk' %} + +{% block body %} + + + + Remove your password on your {{ app.name }} account + + + Someone wants to remove your password from your account. +

+ Do not click on this if this is not you! +
+ + + Remove my {{ app.name }} password + +
+
+{% endblock %} + +{% block text %} + Hi! + Someone wants to remove your password from your {{ app.name }} account. + + To confirm this action and remove your password, please follow this link: {{ link|safe }} +{% endblock %} From 21f161a83ae109e861c39ac88dad2d9896d0381a Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 21 Feb 2021 13:19:28 +0100 Subject: [PATCH 02/13] Update repository URL --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index df1fe86..cad254e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "swaf", "version": "0.23.6", "description": "Structure Web Application Framework.", - "repository": "https://eternae.ink/arisu/swaf", + "repository": "https://eternae.ink/ashpie/swaf", "author": "Alice Gaudon ", "license": "MIT", "readme": "README.md", From 3ce81e25cfe7ce2083decfc3dd34370efb00b37c Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 21 Feb 2021 16:28:13 +0100 Subject: [PATCH 03/13] Add tests for password remove flow Closes #28 --- test/Authentication.test.ts | 63 +++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/test/Authentication.test.ts b/test/Authentication.test.ts index ad4e907..293f322 100644 --- a/test/Authentication.test.ts +++ b/test/Authentication.test.ts @@ -806,6 +806,69 @@ describe('Change password', () => { expect(await user?.as(UserPasswordComponent).verifyPassword('a_very_strong_password_but_different')).toBeTruthy(); expect(await user?.as(UserPasswordComponent).verifyPassword('123')).toBeFalsy(); }); + + test('Remove password', async () => { + let user = await User.select() + .where('name', 'aang') + .first(); + expect(user).toBeDefined(); + expect(user?.as(UserPasswordComponent).hasPassword()).toBe(true); + + await agent.post('/account/remove-password') + .set('Cookie', cookies) + .send({ + csrf: csrf, + }) + .expect(302) + .expect('Location', '/magic/lobby?redirect_uri=%2Faccount%2F'); + + await followMagicLinkFromMail(agent, cookies, '/account/'); + + user = await User.select() + .where('name', 'aang') + .first(); + expect(user).toBeDefined(); + expect(user?.as(UserPasswordComponent).hasPassword()).toBe(false); + }); + + test('Can\'t remove password without contact email', async () => { + const res = await agent.get('/csrf').expect(200); + cookies = res.get('Set-Cookie'); + csrf = res.text; + + await agent.post('/auth/register') + .set('Cookie', cookies) + .send({ + csrf: csrf, + auth_method: 'password', + identifier: 'eleanor', + password: 'this_is_a_very_strong_password', + password_confirmation: 'this_is_a_very_strong_password', + terms: 'on', + }) + .expect(302) + .expect('Location', '/'); + + let user = await User.select() + .where('name', 'eleanor') + .first(); + expect(user).toBeDefined(); + expect(user?.as(UserPasswordComponent).hasPassword()).toBe(true); + + await agent.post('/account/remove-password') + .set('Cookie', cookies) + .send({ + csrf: csrf, + }) + .expect(302) + .expect('Location', '/account/'); + + user = await User.select() + .where('name', 'eleanor') + .first(); + expect(user).toBeDefined(); + expect(user?.as(UserPasswordComponent).hasPassword()).toBe(true); + }); }); From dcfb0b8f1cf1bfb0a963aa847f00a769d16cfb7f Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 23 Feb 2021 17:40:28 +0100 Subject: [PATCH 04/13] Add Time util class --- src/Time.ts | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/Time.ts diff --git a/src/Time.ts b/src/Time.ts new file mode 100644 index 0000000..fbaf98f --- /dev/null +++ b/src/Time.ts @@ -0,0 +1,93 @@ +export class TimeUnit { + public constructor( + public readonly milliseconds: number, + public readonly longName: string, + public readonly shortName: string, + ) { + } +} + +export default class Time { + public static readonly UNITS = { + MILLISECOND: { + milliseconds: 1, + longName: 'millisecond', + shortName: 'ms', + }, + SECOND: { + milliseconds: 1000, + longName: 'second', + shortName: 's', + }, + MINUTE: { + milliseconds: 60 * 1000, + longName: 'minute', + shortName: 'm', + }, + HOUR: { + milliseconds: 60 * 60 * 1000, + longName: 'hour', + shortName: 'h', + }, + DAY: { + milliseconds: 24 * 60 * 60 * 1000, + longName: 'day', + shortName: 'd', + }, + MONTH: { + milliseconds: 30 * 24 * 60 * 60 * 1000, + longName: 'month', + shortName: 'M', + }, + YEAR: { + milliseconds: 365 * 24 * 60 * 60 * 1000, + longName: 'year', + shortName: 'y', + }, + }; + + public static humanizeTimeSince( + since: Date, + short?: boolean, + skipOneUnitNumber?: boolean, + units?: TimeUnit[], + ): string { + return this.humanizeDuration(Date.now() - since.getTime(), short, skipOneUnitNumber, units); + } + + public static humanizeTimeTo( + to: Date, + short?: boolean, + skipOneUnitNumber?: boolean, + units?: TimeUnit[], + ): string { + return this.humanizeDuration(to.getTime() - Date.now(), short, skipOneUnitNumber, units); + } + + public static humanizeDuration( + duration: number, + short: boolean = false, + skipOneUnitNumber: boolean = false, + units: TimeUnit[] = [ + this.UNITS.SECOND, + this.UNITS.MINUTE, + this.UNITS.HOUR, + this.UNITS.DAY, + this.UNITS.MONTH, + this.UNITS.YEAR, + ], + ): string { + for (let i = units.length - 1; i > 0; i--) { + if (duration >= units[i - 1].milliseconds && duration < units[i].milliseconds) { + const amount = Math.floor(duration / units[i - 1].milliseconds); + const unit = short ? + units[i - 1].shortName : + ' ' + units[i - 1].longName + (amount > 1 ? 's' : ''); + return (amount > 1 || !skipOneUnitNumber ? amount : '') + unit; + } + } + + return 'now'; + } + +} From caae753d748b73d30079ede321920d385dec2fb5 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 23 Feb 2021 17:42:25 +0100 Subject: [PATCH 05/13] Allow users to change their username every configurable period of time Closes #22 --- config/default.json5 | 5 +- src/TestApp.ts | 2 + src/auth/AccountController.ts | 40 ++++++++- src/auth/AuthGuard.ts | 2 +- src/auth/magic_link/MagicLinkController.ts | 9 +- .../AddNameChangedAtToUsersMigration.ts | 12 +++ src/auth/models/User.ts | 6 +- src/auth/models/UserNameComponent.ts | 34 ++++++- src/auth/password/PasswordAuthMethod.ts | 4 +- test/Authentication.test.ts | 89 ++++++++++++++++++- views/auth/{ => account}/account.njk | 4 + views/auth/account/name_panel.njk | 16 ++++ views/auth/{ => account}/password_panel.njk | 0 13 files changed, 209 insertions(+), 14 deletions(-) create mode 100644 src/auth/migrations/AddNameChangedAtToUsersMigration.ts rename views/auth/{ => account}/account.njk (97%) create mode 100644 views/auth/account/name_panel.njk rename views/auth/{ => account}/password_panel.njk (100%) diff --git a/config/default.json5 b/config/default.json5 index a1c8c4d..0e62cad 100644 --- a/config/default.json5 +++ b/config/default.json5 @@ -50,5 +50,8 @@ magic_link: { validity_period: 20, }, - approval_mode: false, + auth: { + approval_mode: false, // Registered accounts need to be approved by an administrator + name_change_wait_period: 2592000000, // 30 days + }, } diff --git a/src/TestApp.ts b/src/TestApp.ts index ee5253c..dd2333a 100644 --- a/src/TestApp.ts +++ b/src/TestApp.ts @@ -31,6 +31,7 @@ import MakeMagicLinksSessionNotUniqueMigration from "./auth/magic_link/MakeMagic import AddUsedToMagicLinksMigration from "./auth/magic_link/AddUsedToMagicLinksMigration"; import packageJson = require('./package.json'); import PreviousUrlComponent from "./components/PreviousUrlComponent"; +import AddNameChangedAtToUsersMigration from "./auth/migrations/AddNameChangedAtToUsersMigration"; export const MIGRATIONS = [ CreateMigrationsTable, @@ -40,6 +41,7 @@ export const MIGRATIONS = [ AddNameToUsersMigration, MakeMagicLinksSessionNotUniqueMigration, AddUsedToMagicLinksMigration, + AddNameChangedAtToUsersMigration, ]; export default class TestApp extends Application { diff --git a/src/auth/AccountController.ts b/src/auth/AccountController.ts index 851c0ac..a3f7c15 100644 --- a/src/auth/AccountController.ts +++ b/src/auth/AccountController.ts @@ -12,6 +12,8 @@ import MagicLinkController from "./magic_link/MagicLinkController"; import {MailTemplate} from "../mail/Mail"; import {ADD_EMAIL_MAIL_TEMPLATE, REMOVE_PASSWORD_MAIL_TEMPLATE} from "../Mails"; import AuthMagicLinkActionType from "./magic_link/AuthMagicLinkActionType"; +import UserNameComponent from "./models/UserNameComponent"; +import Time from "../Time"; export default class AccountController extends Controller { @@ -29,6 +31,10 @@ export default class AccountController extends Controller { public routes(): void { this.get('/', this.getAccount, 'account', RequireAuthMiddleware); + if (ModelFactory.get(User).hasComponent(UserNameComponent)) { + this.post('/change-name', this.postChangeName, 'change-name', RequireAuthMiddleware); + } + if (ModelFactory.get(User).hasComponent(UserPasswordComponent)) { this.post('/change-password', this.postChangePassword, 'change-password', RequireAuthMiddleware); this.post('/remove-password', this.postRemovePassword, 'remove-password', RequireAuthMiddleware); @@ -43,15 +49,47 @@ export default class AccountController extends Controller { const user = req.as(RequireAuthMiddleware).getUser(); const passwordComponent = user.asOptional(UserPasswordComponent); - res.render('auth/account', { + + const nameComponent = user.asOptional(UserNameComponent); + const nameChangeWaitPeriod = config.get('auth.name_change_wait_period'); + const nameChangedAt = nameComponent?.getNameChangedAt()?.getTime() || Date.now(); + const nameChangeRemainingTime = new Date(nameChangedAt + nameChangeWaitPeriod); + + res.render('auth/account/account', { main_email: await user.mainEmail.get(), emails: await user.emails.get(), display_email_warning: config.get('app.display_email_warning'), has_password_component: !!passwordComponent, has_password: passwordComponent?.hasPassword(), + has_name_component: !!nameComponent, + name_change_wait_period: Time.humanizeDuration(nameChangeWaitPeriod, false, true), + can_change_name: nameComponent?.canChangeName(), + can_change_name_in: Time.humanizeTimeTo(nameChangeRemainingTime), }); } + protected async postChangeName(req: Request, res: Response): Promise { + await Validator.validate({ + 'name': new Validator().defined(), + }, req.body); + + const user = req.as(RequireAuthMiddleware).getUser(); + const userNameComponent = user.as(UserNameComponent); + + if (!userNameComponent.setName(req.body.name)) { + const nameChangedAt = userNameComponent.getNameChangedAt()?.getTime() || Date.now(); + const nameChangeWaitPeriod = config.get('auth.name_change_wait_period'); + req.flash('error', `Your can't change your name until ${new Date(nameChangedAt + nameChangeWaitPeriod)}.`); + res.redirect(Controller.route('account')); + return; + } + + await user.save(); + + req.flash('success', `Your name was successfully changed to ${req.body.name}.`); + res.redirect(Controller.route('account')); + } + protected async postChangePassword(req: Request, res: Response): Promise { const validationMap = { 'new_password': new Validator().defined(), diff --git a/src/auth/AuthGuard.ts b/src/auth/AuthGuard.ts index 2742f62..cdce13b 100644 --- a/src/auth/AuthGuard.ts +++ b/src/auth/AuthGuard.ts @@ -141,7 +141,7 @@ export default class AuthGuard { if (!user.isApproved()) { await new Mail(this.app.as(NunjucksComponent).getEnvironment(), PENDING_ACCOUNT_REVIEW_MAIL_TEMPLATE, { - username: user.asOptional(UserNameComponent)?.name || + username: user.asOptional(UserNameComponent)?.getName() || (await user.mainEmail.get())?.getOrFail('email') || 'Could not find an identifier', link: config.get('public_url') + Controller.route('accounts-approval'), diff --git a/src/auth/magic_link/MagicLinkController.ts b/src/auth/magic_link/MagicLinkController.ts index 2aca47c..402bd3b 100644 --- a/src/auth/magic_link/MagicLinkController.ts +++ b/src/auth/magic_link/MagicLinkController.ts @@ -65,7 +65,12 @@ export default class MagicLinkController extends Controll return await req.as(AuthMiddleware).getAuthGuard().authenticateOrRegister( session, magicLink, !!session.wantsSessionPersistence, undefined, async (connection, user) => { const userNameComponent = user.asOptional(UserNameComponent); - if (userNameComponent) userNameComponent.name = magicLink.as(MagicLinkUserNameComponent).username; + const magicLinkUserNameComponent = magicLink.asOptional(MagicLinkUserNameComponent); + + if (userNameComponent && magicLinkUserNameComponent?.username) { + userNameComponent.setName(magicLinkUserNameComponent.username); + } + return []; }, async (connection, user) => { const callbacks: RegisterCallback[] = []; @@ -192,7 +197,7 @@ export default class MagicLinkController extends Controll if (!res.headersSent && user) { // Auth success - const name = user.asOptional(UserNameComponent)?.name; + const name = user.asOptional(UserNameComponent)?.getName(); req.flash('success', `Authentication success. Welcome${name ? `, ${name}` : ''}`); res.redirect(req.getIntendedUrl() || Controller.route('home')); } diff --git a/src/auth/migrations/AddNameChangedAtToUsersMigration.ts b/src/auth/migrations/AddNameChangedAtToUsersMigration.ts new file mode 100644 index 0000000..c83d6f1 --- /dev/null +++ b/src/auth/migrations/AddNameChangedAtToUsersMigration.ts @@ -0,0 +1,12 @@ +import Migration from "../../db/Migration"; + +export default class AddNameChangedAtToUsersMigration extends Migration { + public async install(): Promise { + await this.query(`ALTER TABLE users + ADD COLUMN name_changed_at DATETIME`); + } + + public async rollback(): Promise { + await this.query('ALTER TABLE users DROP COLUMN IF EXISTS name_changed_at'); + } +} diff --git a/src/auth/models/User.ts b/src/auth/models/User.ts index a08dc69..09c22f7 100644 --- a/src/auth/models/User.ts +++ b/src/auth/models/User.ts @@ -9,7 +9,7 @@ import UserNameComponent from "./UserNameComponent"; export default class User extends Model { public static isApprovalMode(): boolean { - return config.get('approval_mode') && + return config.get('auth.approval_mode') && MysqlConnectionManager.hasMigration(AddApprovedFieldToUsersTableMigration); } @@ -42,10 +42,10 @@ export default class User extends Model { protected getPersonalInfoFields(): { name: string, value: string }[] { const fields: { name: string, value: string }[] = []; const nameComponent = this.asOptional(UserNameComponent); - if (nameComponent && nameComponent.name) { + if (nameComponent && nameComponent.hasName()) { fields.push({ name: 'Name', - value: nameComponent.name, + value: nameComponent.getName(), }); } return fields; diff --git a/src/auth/models/UserNameComponent.ts b/src/auth/models/UserNameComponent.ts index 930b794..9440329 100644 --- a/src/auth/models/UserNameComponent.ts +++ b/src/auth/models/UserNameComponent.ts @@ -1,12 +1,44 @@ import ModelComponent from "../../db/ModelComponent"; import User from "../models/User"; +import config from "config"; export const USERNAME_REGEXP = /^[0-9a-z_-]+$/; export default class UserNameComponent extends ModelComponent { - public name?: string = undefined; + private name?: string = undefined; + private name_changed_at?: Date | null = undefined; public init(): void { this.setValidation('name').defined().between(3, 64).regexp(USERNAME_REGEXP).unique(this._model); } + + public hasName(): boolean { + return !!this.name; + } + + public getName(): string { + if (!this.name) throw new Error('User has no name.'); + return this.name; + } + + public setName(newName: string): boolean { + if (!this.canChangeName()) return false; + + this.name = newName; + this.name_changed_at = new Date(); + return true; + } + + public getNameChangedAt(): Date | null { + return this.name_changed_at || null; + } + + public forgetNameChangeDate(): void { + this.name_changed_at = null; + } + + public canChangeName(): boolean { + return !this.name_changed_at || + Date.now() - this.name_changed_at.getTime() >= config.get('auth.name_change_wait_period'); + } } diff --git a/src/auth/password/PasswordAuthMethod.ts b/src/auth/password/PasswordAuthMethod.ts index 27bd85e..6372c2e 100644 --- a/src/auth/password/PasswordAuthMethod.ts +++ b/src/auth/password/PasswordAuthMethod.ts @@ -113,7 +113,7 @@ export default class PasswordAuthMethod implements AuthMethod await user.as(UserPasswordComponent).setPassword(req.body.password); // Username - user.as(UserNameComponent).name = req.body.identifier; + user.as(UserNameComponent).setName(req.body.identifier); return callbacks; }, async (connection, user) => { @@ -132,7 +132,7 @@ export default class PasswordAuthMethod implements AuthMethod const user = await passwordAuthProof.getResource(); - req.flash('success', `Your account was successfully created! Welcome, ${user?.as(UserNameComponent).name}.`); + req.flash('success', `Your account was successfully created! Welcome, ${user?.as(UserNameComponent).getName()}.`); res.redirect(req.getIntendedUrl() || Controller.route('home')); } diff --git a/test/Authentication.test.ts b/test/Authentication.test.ts index 293f322..fff1ef0 100644 --- a/test/Authentication.test.ts +++ b/test/Authentication.test.ts @@ -72,7 +72,7 @@ describe('Register with username and password (password)', () => { .first(); expect(user).toBeDefined(); - expect(user?.as(UserNameComponent).name).toStrictEqual('entrapta'); + expect(user?.as(UserNameComponent).getName()).toStrictEqual('entrapta'); await expect(user?.as(UserPasswordComponent).verifyPassword('darla_is_cute')).resolves.toStrictEqual(true); }); @@ -186,7 +186,7 @@ describe('Register with email (magic_link)', () => { expect(email).toBeDefined(); expect(email?.email).toStrictEqual('glimmer@example.org'); - expect(user?.as(UserNameComponent).name).toStrictEqual('glimmer'); + expect(user?.as(UserNameComponent).getName()).toStrictEqual('glimmer'); await expect(user?.as(UserPasswordComponent).verifyPassword('')).resolves.toStrictEqual(false); }); @@ -575,7 +575,7 @@ describe('Authenticate with email and password (password)', () => { expect(email).toBeDefined(); expect(email?.email).toStrictEqual('double-trouble@example.org'); - expect(user?.as(UserNameComponent).name).toStrictEqual('double-trouble'); + expect(user?.as(UserNameComponent).getName()).toStrictEqual('double-trouble'); await expect(user?.as(UserPasswordComponent).verifyPassword('trick-or-treat')).resolves.toStrictEqual(true); }); @@ -871,6 +871,89 @@ describe('Change password', () => { }); }); +describe('Change username', () => { + let cookies: string[], csrf: string; + test('Prepare user', async () => { + const res = await agent.get('/csrf').expect(200); + cookies = res.get('Set-Cookie'); + csrf = res.text; + + await agent.post('/auth/register') + .set('Cookie', cookies) + .send({ + csrf: csrf, + auth_method: 'password', + identifier: 'richard', + password: 'a_very_strong_password', + password_confirmation: 'a_very_strong_password', + terms: 'on', + }) + .expect(302) + .expect('Location', '/'); + }); + + test('Initial value of name_changed_at should be the same as created_at', async () => { + const user = await User.select().where('name', 'richard').first(); + expect(user).toBeDefined(); + expect(user?.as(UserNameComponent).getNameChangedAt()?.getTime()).toBe(user?.created_at?.getTime()); + }); + + test('Cannot change username just after registration', async () => { + expect(await User.select().where('name', 'richard').count()).toBe(1); + + await agent.post('/account/change-name') + .set('Cookie', cookies) + .send({ + csrf: csrf, + name: 'robert', + }) + .expect(302) + .expect('Location', '/account/'); + + expect(await User.select().where('name', 'richard').count()).toBe(1); + }); + + test('Can change username after hold period', async () => { + // Set last username change to older date + const user = await User.select().where('name', 'richard').first(); + if (user) { + user.as(UserNameComponent).forgetNameChangeDate(); + await user.save(); + } + + expect(await User.select().where('name', 'richard').count()).toBe(1); + expect(await User.select().where('name', 'robert').count()).toBe(0); + + await agent.post('/account/change-name') + .set('Cookie', cookies) + .send({ + csrf: csrf, + name: 'robert', + }) + .expect(302) + .expect('Location', '/account/'); + + expect(await User.select().where('name', 'richard').count()).toBe(0); + expect(await User.select().where('name', 'robert').count()).toBe(1); + }); + + test('Cannot change username just after changing username', async () => { + expect(await User.select().where('name', 'robert').count()).toBe(1); + expect(await User.select().where('name', 'bebert').count()).toBe(0); + + await agent.post('/account/change-name') + .set('Cookie', cookies) + .send({ + csrf: csrf, + name: 'bebert', + }) + .expect(302) + .expect('Location', '/account/'); + + expect(await User.select().where('name', 'robert').count()).toBe(1); + expect(await User.select().where('name', 'bebert').count()).toBe(0); + }); +}); describe('Manage email addresses', () => { diff --git a/views/auth/account.njk b/views/auth/account/account.njk similarity index 97% rename from views/auth/account.njk rename to views/auth/account/account.njk index 6f4e633..c4f55dc 100644 --- a/views/auth/account.njk +++ b/views/auth/account/account.njk @@ -22,6 +22,10 @@ {% endif %} + {% if has_name_component %} + {% include './name_panel.njk' %} + {% endif %} + {% if has_password_component %} {% include './password_panel.njk' %} {% endif %} diff --git a/views/auth/account/name_panel.njk b/views/auth/account/name_panel.njk new file mode 100644 index 0000000..d2a5cdf --- /dev/null +++ b/views/auth/account/name_panel.njk @@ -0,0 +1,16 @@ +
+

Change name

+ {% if can_change_name %} +
+ {{ macros.field(_locals, 'text', 'name', null, 'New name', null, 'required') }} + + {{ macros.field(_locals, 'checkbox', 'terms', null, 'I understand that I can only change my name once every ' + name_change_wait_period, '', 'required') }} + + + + {{ macros.csrf(getCsrfToken) }} +
+ {% else %} + {{ macros.message('info', 'You can change your name in ' + can_change_name_in) }} + {% endif %} +
diff --git a/views/auth/password_panel.njk b/views/auth/account/password_panel.njk similarity index 100% rename from views/auth/password_panel.njk rename to views/auth/account/password_panel.njk From 4692a236968100ac362f838760dcdb6db6a1f006 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 30 Mar 2021 10:20:38 +0200 Subject: [PATCH 06/13] Properly implement pagination --- src/Pagination.ts | 76 +++++++++++++++++++++++++--- src/db/ModelFactory.ts | 23 ++++++--- src/db/ModelQuery.ts | 4 +- test/Pagination.test.ts | 107 ++++++++++++++++++++++++++++++++++++++++ views/macros.njk | 36 ++++++++++---- 5 files changed, 222 insertions(+), 24 deletions(-) create mode 100644 test/Pagination.test.ts diff --git a/src/Pagination.ts b/src/Pagination.ts index 50055d9..b86cd07 100644 --- a/src/Pagination.ts +++ b/src/Pagination.ts @@ -1,16 +1,18 @@ -import Model from "./db/Model"; +import {WrappingError} from "./Utils"; -export default class Pagination { - private readonly models: T[]; +export default class Pagination { public readonly page: number; public readonly perPage: number; public readonly totalCount: number; - public constructor(models: T[], page: number, perPage: number, totalCount: number) { - this.models = models; + public constructor(page: number, perPage: number, totalCount: number) { this.page = page; this.perPage = perPage; this.totalCount = totalCount; + + if (this.page < 1 || this.page > this.lastPage) { + throw new PageNotFoundError(this.page); + } } public hasPrevious(): boolean { @@ -18,7 +20,69 @@ export default class Pagination { } public hasNext(): boolean { - return this.models.length >= this.perPage && this.page * this.perPage < this.totalCount; + return this.page < this.lastPage; } + public get lastPage(): number { + return Math.ceil(this.totalCount / this.perPage); + } + + public previousPages(contextSize: number): number[] { + const pages = []; + + let i = 1; + + // Leftmost context + while (i < this.page && i <= contextSize) { + pages.push(i); + i++; + } + + // Ellipsis + if (i < this.page - contextSize) { + pages.push(-1); + } + + // Middle left context + i = Math.max(i, this.page - contextSize); + while (i < this.page) { + pages.push(i); + i++; + } + + return pages; + } + + public nextPages(contextSize: number): number[] { + const pages = []; + + let i = this.page + 1; + // Middle right context + while (i <= this.lastPage && i <= this.page + contextSize) { + pages.push(i); + i++; + } + + // Ellipsis + if (this.page + contextSize + 1 < this.lastPage - contextSize + 1) { + pages.push(-1); + } + + // Rightmost context + i = Math.max(i, this.lastPage - contextSize + 1); + while (i <= this.lastPage) { + pages.push(i); + i++; + } + + return pages; + } +} + +export class PageNotFoundError extends WrappingError { + public constructor( + public readonly page: number, + ) { + super(`Page ${page} not found.`); + } } diff --git a/src/db/ModelFactory.ts b/src/db/ModelFactory.ts index 6d91c81..e24d2d2 100644 --- a/src/db/ModelFactory.ts +++ b/src/db/ModelFactory.ts @@ -2,6 +2,8 @@ import ModelComponent from "./ModelComponent"; import Model, {ModelType} from "./Model"; import ModelQuery, {ModelQueryResult, QueryFields} from "./ModelQuery"; import {Request} from "express"; +import {PageNotFoundError} from "../Pagination"; +import {NotFoundHttpError} from "../HttpError"; export default class ModelFactory { private static readonly factories: { [modelType: string]: ModelFactory | undefined } = {}; @@ -86,16 +88,25 @@ export default class ModelFactory { return await query.first(); } - public async paginate(request: Request, perPage: number = 20, query?: ModelQuery): Promise> { - const page = request.params.page ? parseInt(request.params.page) : 1; + public async paginate(req: Request, perPage: number = 20, query?: ModelQuery): Promise> { + const page = req.params.page ? parseInt(req.params.page) : 1; if (!query) query = this.select(); - if (request.params.sortBy) { - const dir = request.params.sortDirection; - query = query.sortBy(request.params.sortBy, dir === 'ASC' || dir === 'DESC' ? dir : undefined); + if (req.params.sortBy) { + const dir = req.params.sortDirection; + query = query.sortBy(req.params.sortBy, dir === 'ASC' || dir === 'DESC' ? dir : undefined); } else { query = query.sortBy('id'); } - return await query.paginate(page, perPage); + + try { + return await query.paginate(page, perPage); + } catch (e) { + if (e instanceof PageNotFoundError) { + throw new NotFoundHttpError(`page ${e.page}`, req.url, e); + } else { + throw e; + } + } } } diff --git a/src/db/ModelQuery.ts b/src/db/ModelQuery.ts index 472744d..c70caf6 100644 --- a/src/db/ModelQuery.ts +++ b/src/db/ModelQuery.ts @@ -347,7 +347,7 @@ export default class ModelQuery implements WhereFieldConsumer> { this.limit(perPage, (page - 1) * perPage); const result = await this.get(connection); - result.pagination = new Pagination(result, page, perPage, await this.count(true, connection)); + result.pagination = new Pagination(page, perPage, await this.count(true, connection)); return result; } @@ -385,7 +385,7 @@ function inputToFieldOrValue(input: string, addTable?: string): string { export interface ModelQueryResult extends Array { originalData?: Record[]; - pagination?: Pagination; + pagination?: Pagination; pivot?: Record[]; } diff --git a/test/Pagination.test.ts b/test/Pagination.test.ts new file mode 100644 index 0000000..8cf66bc --- /dev/null +++ b/test/Pagination.test.ts @@ -0,0 +1,107 @@ +import Pagination from "../src/Pagination"; + +describe('Pagination', () => { + const pagination = new Pagination(3, 5, 31); + test('Should have correct page', () => { + expect(pagination.page).toBe(3); + }); + + test('Should have correct perPage', () => { + expect(pagination.perPage).toBe(5); + }); + + test('Should have correct totalCount', () => { + expect(pagination.totalCount).toBe(31); + }); + + test('Should calculate correct last page', () => { + expect(new Pagination(3, 5, 30).lastPage).toBe(6); + expect(new Pagination(3, 5, 31).lastPage).toBe(7); + expect(new Pagination(3, 5, 32).lastPage).toBe(7); + expect(new Pagination(3, 5, 34).lastPage).toBe(7); + expect(new Pagination(3, 5, 35).lastPage).toBe(7); + expect(new Pagination(3, 5, 36).lastPage).toBe(8); + }); + + test('Should properly tell whether has a previous page', () => { + expect(pagination.hasPrevious()).toBe(true); + expect(new Pagination(1, 5, 15).hasPrevious()).toBe(false); + expect(new Pagination(2, 5, 15).hasPrevious()).toBe(true); + expect(new Pagination(3, 5, 15).hasPrevious()).toBe(true); + + expect(new Pagination(1, 5, 17).hasPrevious()).toBe(false); + expect(new Pagination(2, 5, 17).hasPrevious()).toBe(true); + expect(new Pagination(3, 5, 17).hasPrevious()).toBe(true); + expect(new Pagination(4, 5, 17).hasPrevious()).toBe(true); + }); + + test('Should properly tell whether has a next page', () => { + expect(pagination.hasPrevious()).toBe(true); + expect(new Pagination(1, 5, 15).hasNext()).toBe(true); + expect(new Pagination(2, 5, 15).hasNext()).toBe(true); + expect(new Pagination(3, 5, 15).hasNext()).toBe(false); + + expect(new Pagination(1, 5, 17).hasNext()).toBe(true); + expect(new Pagination(2, 5, 17).hasNext()).toBe(true); + expect(new Pagination(3, 5, 17).hasNext()).toBe(true); + expect(new Pagination(4, 5, 17).hasNext()).toBe(false); + }); + + test('Should throw on out of bound creation attempt', () => { + expect(() => { + new Pagination(-1, 5, 15); + }).toThrow('Page -1 not found.'); + expect(() => { + new Pagination(-20, 5, 15); + }).toThrow('Page -20 not found.'); + expect(() => { + new Pagination(3, 5, 15); + }).not.toThrow(); + expect(() => { + new Pagination(4, 5, 15); + }).toThrow('Page 4 not found.'); + expect(() => { + new Pagination(20, 5, 15); + }).toThrow('Page 20 not found.'); + }); + + test('Should generate proper previous pages with context', () => { + expect(new Pagination(1, 1, 100).previousPages(1)).toStrictEqual([]); + expect(new Pagination(1, 1, 100).previousPages(2)).toStrictEqual([]); + expect(new Pagination(1, 1, 100).previousPages(3)).toStrictEqual([]); + + expect(new Pagination(2, 1, 100).previousPages(1)).toStrictEqual([1]); + expect(new Pagination(2, 1, 100).previousPages(2)).toStrictEqual([1]); + expect(new Pagination(2, 1, 100).previousPages(3)).toStrictEqual([1]); + + expect(new Pagination(3, 1, 100).previousPages(1)).toStrictEqual([1, 2]); + expect(new Pagination(3, 1, 100).previousPages(2)).toStrictEqual([1, 2]); + expect(new Pagination(3, 1, 100).previousPages(3)).toStrictEqual([1, 2]); + + expect(new Pagination(10, 1, 100).previousPages(1)).toStrictEqual([1, -1, 9]); + expect(new Pagination(10, 1, 100).previousPages(2)).toStrictEqual([1, 2, -1, 8, 9]); + expect(new Pagination(10, 1, 100).previousPages(3)).toStrictEqual([1, 2, 3, -1, 7, 8, 9]); + }); + + test('Should generate proper next pages with context', () => { + let pagination = new Pagination(100, 1, 100); + expect(pagination.nextPages(1)).toStrictEqual([]); + expect(pagination.nextPages(2)).toStrictEqual([]); + expect(pagination.nextPages(3)).toStrictEqual([]); + + pagination = new Pagination(99, 1, 100); + expect(pagination.nextPages(1)).toStrictEqual([100]); + expect(pagination.nextPages(2)).toStrictEqual([100]); + expect(pagination.nextPages(3)).toStrictEqual([100]); + + pagination = new Pagination(98, 1, 100); + expect(pagination.nextPages(1)).toStrictEqual([99, 100]); + expect(pagination.nextPages(2)).toStrictEqual([99, 100]); + expect(pagination.nextPages(3)).toStrictEqual([99, 100]); + + pagination = new Pagination(90, 1, 100); + expect(pagination.nextPages(1)).toStrictEqual([91, -1, 100]); + expect(pagination.nextPages(2)).toStrictEqual([91, 92, -1, 99, 100]); + expect(pagination.nextPages(3)).toStrictEqual([91, 92, 93, -1, 98, 99, 100]); + }); +}); diff --git a/views/macros.njk b/views/macros.njk index e52ed06..8857876 100644 --- a/views/macros.njk +++ b/views/macros.njk @@ -141,19 +141,35 @@ {% endmacro %} -{% macro paginate(pagination, routeName) %} +{% macro paginate(pagination, routeName, contextSize) %} {% if pagination.hasPrevious() or pagination.hasNext() %} -
+ {% if pagination.hasNext() %} + {% for i in pagination.nextPages(contextSize) %} + {% if i == -1 %} +
  • ...
  • + {% else %} +
  • {{ i }}
  • + {% endif %} + {% endfor %} +
  • Next
  • + {% endif %} + + {% endif %} {% endmacro %} From 69e9f3ce9c0d47791aed4eaca9f498ea911d3dfb Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 30 Mar 2021 10:45:14 +0200 Subject: [PATCH 07/13] Controller: fix route() parsing with regexp params Also allow numbers in route param names --- src/Controller.ts | 16 ++++++++++++---- test/Controller.test.ts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 test/Controller.test.ts diff --git a/src/Controller.ts b/src/Controller.ts index abdd228..7a26ad6 100644 --- a/src/Controller.ts +++ b/src/Controller.ts @@ -9,6 +9,9 @@ import Middleware, {MiddlewareType} from "./Middleware"; import Application from "./Application"; export default abstract class Controller { + /** + * TODO: this should not be static, it should actually be bound to an app instance. + */ private static readonly routes: { [p: string]: string | undefined } = {}; public static route( @@ -20,11 +23,12 @@ export default abstract class Controller { let path = this.routes[route]; if (path === undefined) throw new Error(`Unknown route for name ${route}.`); + const regExp = this.getRouteParamRegExp('[a-zA-Z0-9_-]+', 'g'); if (typeof params === 'string' || typeof params === 'number') { - path = path.replace(/:[a-zA-Z_-]+\??/g, '' + params); + path = path.replace(regExp, '' + params); } else if (Array.isArray(params)) { let i = 0; - for (const match of path.matchAll(/:[a-zA-Z_-]+(\(.*\))?\??/g)) { + for (const match of path.matchAll(regExp)) { if (match.length > 0) { path = path.replace(match[0], typeof params[i] !== 'undefined' ? params[i] : ''); } @@ -33,7 +37,7 @@ export default abstract class Controller { path = path.replace(/\/+/g, '/'); } else { for (const key of Object.keys(params)) { - path = path.replace(new RegExp(`:${key}\\??`), params[key]); + path = path.replace(this.getRouteParamRegExp(key), params[key].toString()); } } @@ -41,6 +45,10 @@ export default abstract class Controller { return `${absolute ? config.get('public_url') : ''}${path}` + (queryStr.length > 0 ? '?' + queryStr : ''); } + private static getRouteParamRegExp(key: string, flags?: string): RegExp { + return new RegExp(`:${key}(\\(.+?\\))?\\??`, flags); + } + private readonly router: Router = express.Router(); private readonly fileUploadFormRouter: Router = express.Router(); private app?: Application; @@ -194,4 +202,4 @@ export default abstract class Controller { } } -export type RouteParams = { [p: string]: string } | string[] | string | number; +export type RouteParams = { [p: string]: string | number } | string[] | string | number; diff --git a/test/Controller.test.ts b/test/Controller.test.ts new file mode 100644 index 0000000..e296a68 --- /dev/null +++ b/test/Controller.test.ts @@ -0,0 +1,35 @@ +import Controller from "../src/Controller"; + +describe('Controller.route()', () => { + new class extends Controller { + public routes(): void { + const emptyHandler = () => { + // + }; + this.get('/test/no-param', emptyHandler, 'test.no-param'); + this.get('/test/no-param/', emptyHandler, 'test.no-param-slash'); + this.get('/test/one-param/:param', emptyHandler, 'test.one-param'); + this.get('/test/two-params/:param1/:param2', emptyHandler, 'test.two-params'); + this.get('/test/paginated/:page([0-9]+)?', emptyHandler, 'test.paginated'); + this.get('/test/slug/:slug([a-zA-Z0-9]+)?', emptyHandler, 'test.slug'); + } + }().setupRoutes(); + + test('Empty params', () => { + expect(Controller.route('test.no-param')).toBe('/test/no-param'); + expect(Controller.route('test.no-param-slash')).toBe('/test/no-param/'); + expect(Controller.route('test.one-param')).toBe('/test/one-param/'); + expect(Controller.route('test.two-params')).toBe('/test/two-params/'); + expect(Controller.route('test.paginated')).toBe('/test/paginated/'); + expect(Controller.route('test.slug')).toBe('/test/slug/'); + }); + + test('Populated params', () => { + expect(Controller.route('test.no-param')).toBe('/test/no-param'); + expect(Controller.route('test.no-param-slash')).toBe('/test/no-param/'); + expect(Controller.route('test.one-param', {param: 'value'})).toBe('/test/one-param/value'); + expect(Controller.route('test.two-params', {param1: 'value1', param2: 'value2'})).toBe('/test/two-params/value1/value2'); + expect(Controller.route('test.paginated', {page: 5})).toBe('/test/paginated/5'); + expect(Controller.route('test.slug', {slug: 'abc'})).toBe('/test/slug/abc'); + }); +}); From 4cbc73a25f5fff5e161fc4f9c83714436de4a72f Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Wed, 24 Mar 2021 16:08:50 +0100 Subject: [PATCH 08/13] Fix ServeStaticDirectoryComponent while developping swaf Also move core version detection to Application --- src/Application.ts | 40 ++++++++++++++----- src/components/NunjucksComponent.ts | 15 +------ .../ServeStaticDirectoryComponent.ts | 11 +++-- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/Application.ts b/src/Application.ts index 02db79c..3b90dfc 100644 --- a/src/Application.ts +++ b/src/Application.ts @@ -21,6 +21,7 @@ import TemplateError = lib.TemplateError; export default abstract class Application implements Extendable> { private readonly version: string; + private coreVersion: string = 'unknown'; private readonly ignoreCommandLine: boolean; private readonly controllers: Controller[] = []; private readonly webSocketListeners: { [p: string]: WebSocketListener } = {}; @@ -58,7 +59,20 @@ export default abstract class Application implements Extendable { - logger.info(`${config.get('app.name')} v${this.version} - hi`); + // Load core version + const file = this.isInNodeModules() ? + path.join(__dirname, '../../package.json') : + path.join(__dirname, '../package.json'); + + try { + this.coreVersion = JSON.parse(fs.readFileSync(file).toString()).version; + } catch (e) { + logger.warn('Couldn\'t determine coreVersion.', e); + } + + logger.info(`${config.get('app.name')} v${this.version} | swaf v${this.coreVersion}`); + + // Catch interrupt signals process.once('SIGINT', () => { this.stop().catch(console.error); }); @@ -264,14 +278,6 @@ export default abstract class Application implements Extendable } { return this.webSocketListeners; } @@ -292,4 +298,20 @@ export default abstract class Application implements Extendable listener.constructor === type); return module ? module as C : null; } + + public isInNodeModules(): boolean { + return fs.existsSync(path.join(__dirname, '../../package.json')); + } + + public isReady(): boolean { + return this.ready; + } + + public getVersion(): string { + return this.version; + } + + public getCoreVersion(): string { + return this.coreVersion; + } } diff --git a/src/components/NunjucksComponent.ts b/src/components/NunjucksComponent.ts index a96ea61..4381fb0 100644 --- a/src/components/NunjucksComponent.ts +++ b/src/components/NunjucksComponent.ts @@ -7,8 +7,6 @@ import * as querystring from "querystring"; import {ParsedUrlQueryInput} from "querystring"; import * as util from "util"; import * as path from "path"; -import * as fs from "fs"; -import {logger} from "../Logger"; import Middleware from "../Middleware"; export default class NunjucksComponent extends ApplicationComponent { @@ -21,17 +19,6 @@ export default class NunjucksComponent extends ApplicationComponent { } public async start(app: Express): Promise { - let coreVersion = 'unknown'; - const file = fs.existsSync(path.join(__dirname, '../../package.json')) ? - path.join(__dirname, '../../package.json') : - path.join(__dirname, '../package.json'); - - try { - coreVersion = JSON.parse(fs.readFileSync(file).toString()).version; - } catch (e) { - logger.warn('Couldn\'t determine coreVersion.', e); - } - const opts = { autoescape: true, noCache: !config.get('view.cache'), @@ -51,7 +38,7 @@ export default class NunjucksComponent extends ApplicationComponent { return Controller.route(route, params, query, absolute); }) .addGlobal('app_version', this.getApp().getVersion()) - .addGlobal('core_version', coreVersion) + .addGlobal('core_version', this.getApp().getCoreVersion()) .addGlobal('querystring', querystring) .addGlobal('app', config.get('app')) diff --git a/src/components/ServeStaticDirectoryComponent.ts b/src/components/ServeStaticDirectoryComponent.ts index 191ac28..d81c8a0 100644 --- a/src/components/ServeStaticDirectoryComponent.ts +++ b/src/components/ServeStaticDirectoryComponent.ts @@ -2,6 +2,7 @@ import ApplicationComponent from "../ApplicationComponent"; import express, {Router} from "express"; import {PathParams} from "express-serve-static-core"; import * as path from "path"; +import {logger} from "../Logger"; export default class ServeStaticDirectoryComponent extends ApplicationComponent { private readonly root: string; @@ -9,16 +10,20 @@ export default class ServeStaticDirectoryComponent extends ApplicationComponent public constructor(root: string, routePath?: PathParams) { super(); - this.root = path.join(__dirname, '../../../', root); + this.root = root; this.path = routePath; } public async init(router: Router): Promise { + const resolvedRoot = path.join(__dirname, this.getApp().isInNodeModules() ? '../../../' : '../../', this.root); + if (this.path) { - router.use(this.path, express.static(this.root, {maxAge: 1000 * 3600 * 72})); + router.use(this.path, express.static(resolvedRoot, {maxAge: 1000 * 3600 * 72})); } else { - router.use(express.static(this.root, {maxAge: 1000 * 3600 * 72})); + router.use(express.static(resolvedRoot, {maxAge: 1000 * 3600 * 72})); } + + logger.info('Serving static files in', resolvedRoot, ' on ', this.path || '/'); } } From 60e32042f7389e67db863ad137e14816b489c1e0 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 30 Mar 2021 11:31:17 +0200 Subject: [PATCH 09/13] package.json scripts: use NodeJS instead of unix commands --- .eslintrc.json | 1 + package.json | 10 +++++----- scripts/clean.js | 10 ++++++++++ scripts/dist.js | 34 ++++++++++++++++++++++++++++++++++ scripts/prepare-sources.js | 4 ++++ 5 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 scripts/clean.js create mode 100644 scripts/dist.js create mode 100644 scripts/prepare-sources.js diff --git a/.eslintrc.json b/.eslintrc.json index 9a221c3..ab37f6e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -86,6 +86,7 @@ }, "ignorePatterns": [ "jest.config.js", + "scripts/**/*", "dist/**/*", "config/**/*" ], diff --git a/package.json b/package.json index cad254e..06ac2a8 100644 --- a/package.json +++ b/package.json @@ -14,12 +14,12 @@ "types": "dist/index.d.ts", "scripts": { "test": "jest --verbose --runInBand", - "clean": "(test ! -d dist || rm -r dist)", - "prepareSources": "cp package.json src/", + "clean": "node scripts/clean.js", + "prepare-sources": "node scripts/prepare-sources.js", "compile": "yarn clean && tsc", - "build": "yarn prepareSources && yarn compile && cp -r yarn.lock README.md config/ views/ dist/ && mkdir dist/types && cp src/types/* dist/types/", - "dev": "yarn prepareSources && concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"maildev\"", - "lint": "eslint . --ext .js,.jsx,.ts,.tsx", + "build": "yarn prepare-sources && yarn compile && node scripts/dist.js", + "dev": "yarn prepare-sources && concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"maildev\"", + "lint": "eslint .", "release": "yarn build && yarn lint && yarn test && cd dist && yarn publish" }, "devDependencies": { diff --git a/scripts/clean.js b/scripts/clean.js new file mode 100644 index 0000000..d5ef093 --- /dev/null +++ b/scripts/clean.js @@ -0,0 +1,10 @@ +const fs = require('fs'); + +[ + 'dist', +].forEach(file => { + if (fs.existsSync(file)) { + console.log('Cleaning', file, '...'); + fs.rmSync(file, {recursive: true}); + } +}); diff --git a/scripts/dist.js b/scripts/dist.js new file mode 100644 index 0000000..c586008 --- /dev/null +++ b/scripts/dist.js @@ -0,0 +1,34 @@ +const fs = require('fs'); +const path = require('path'); + +function copyRecursively(file, destination) { + const target = path.join(destination, path.basename(file)); + if (fs.statSync(file).isDirectory()) { + console.log('mkdir', target); + + fs.mkdirSync(target, {recursive: true}); + fs.readdirSync(file).forEach(f => { + copyRecursively(path.join(file, f), target); + }); + } else { + console.log('> cp ', target); + + fs.copyFileSync(file, target); + } +} + + +[ + 'yarn.lock', + 'README.md', + 'config/', + 'views/', +].forEach(file => { + copyRecursively(file, 'dist'); +}); + +fs.mkdirSync('dist/types', {recursive: true}); + +fs.readdirSync('src/types').forEach(file => { + copyRecursively(path.join('src/types', file), 'dist/types'); +}); diff --git a/scripts/prepare-sources.js b/scripts/prepare-sources.js new file mode 100644 index 0000000..a78c2f3 --- /dev/null +++ b/scripts/prepare-sources.js @@ -0,0 +1,4 @@ +const fs = require('fs'); +const path = require('path'); + +fs.copyFileSync('package.json', path.join('src', 'package.json')); From 714e747d6ed054d052a023ba0c0e0a64479c64e8 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Fri, 26 Mar 2021 10:32:02 +0100 Subject: [PATCH 10/13] Application: make start/stop sturdier, catch more stop signals --- src/Application.ts | 81 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/src/Application.ts b/src/Application.ts index 3b90dfc..b37b3be 100644 --- a/src/Application.ts +++ b/src/Application.ts @@ -29,6 +29,8 @@ export default abstract class Application implements Extendable { + if (this.started) throw new Error('Application already started'); + if (this.busy) throw new Error('Application busy'); + this.busy = true; + // Load core version const file = this.isInNodeModules() ? path.join(__dirname, '../../package.json') : @@ -73,22 +79,28 @@ export default abstract class Application implements Extendable { + const exitHandler = () => { this.stop().catch(console.error); - }); + }; + process.once('exit', exitHandler); + process.once('SIGINT', exitHandler); + process.once('SIGUSR1', exitHandler); + process.once('SIGUSR2', exitHandler); + process.once('uncaughtException', exitHandler); // Register migrations MysqlConnectionManager.registerMigrations(this.getMigrations()); - // Process command line - if (!this.ignoreCommandLine && await this.processCommandLine()) { - await this.stop(); - return; - } - // Register all components and alike await this.init(); + // Process command line + if (!this.ignoreCommandLine && await this.processCommandLine()) { + this.started = true; + this.busy = false; + return; + } + // Security if (process.env.NODE_ENV === 'production') { await this.checkSecuritySettings(); @@ -203,26 +215,54 @@ export default abstract class Application implements Extendable { const args = process.argv; + // Flags + const flags = { + verbose: false, + fullHttpRequests: false, + }; + let mainCommand: string | null = null; + const mainCommandArgs: string[] = []; for (let i = 2; i < args.length; i++) { switch (args[i]) { case '--verbose': - logger.setSettings({minLevel: "trace"}); + flags.verbose = true; break; case '--full-http-requests': - LogRequestsComponent.logFullHttpRequests(); + flags.fullHttpRequests = true; break; case 'migration': - await MysqlConnectionManager.migrationCommand(args.slice(i + 1)); - return true; + if (mainCommand === null) mainCommand = args[i]; + else throw new Error(`Only one main command can be used at once (${mainCommand},${args[i]})`); + break; default: - logger.warn('Unrecognized argument', args[i]); + if (mainCommand) mainCommandArgs.push(args[i]); + else logger.fatal('Unrecognized argument', args[i]); return true; } } + + if (flags.verbose) logger.setSettings({minLevel: "trace"}); + if (flags.fullHttpRequests) LogRequestsComponent.logFullHttpRequests(); + + if (mainCommand) { + switch (mainCommand) { + case 'migration': + await MysqlConnectionManager.migrationCommand(mainCommandArgs); + await this.stop(); + break; + default: + logger.fatal('Unimplemented main command', mainCommand); + break; + } + return true; + } + return false; } @@ -247,13 +287,18 @@ export default abstract class Application implements Extendable { - logger.info('Stopping application...'); + if (this.started && !this.busy) { + this.busy = true; + logger.info('Stopping application...'); - for (const component of this.components) { - await component.stop?.(); + for (const component of this.components) { + await component.stop?.(); + } + + logger.info(`${this.constructor.name} stopped properly.`); + this.started = false; + this.busy = false; } - - logger.info(`${this.constructor.name} v${this.version} - bye`); } private routes(initRouter: Router, handleRouter: Router) { From 9ff832fb6f9b9e77bb47cadf74f22e14e57a2b24 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Fri, 26 Mar 2021 10:38:58 +0100 Subject: [PATCH 11/13] TestApp: don't ignore commands by default --- src/TestApp.ts | 4 ++-- test/Authentication.test.ts | 2 +- test/AuthenticationNoUsername.test.ts | 2 +- test/CsrfProtectionComponent.test.ts | 2 +- test/_app.ts | 6 ++++-- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/TestApp.ts b/src/TestApp.ts index dd2333a..3aa39bd 100644 --- a/src/TestApp.ts +++ b/src/TestApp.ts @@ -48,8 +48,8 @@ export default class TestApp extends Application { private readonly addr: string; private readonly port: number; - public constructor(addr: string, port: number) { - super(packageJson.version, true); + public constructor(addr: string, port: number, ignoreCommandLine: boolean = false) { + super(packageJson.version, ignoreCommandLine); this.addr = addr; this.port = port; } diff --git a/test/Authentication.test.ts b/test/Authentication.test.ts index fff1ef0..6233458 100644 --- a/test/Authentication.test.ts +++ b/test/Authentication.test.ts @@ -34,7 +34,7 @@ useApp(async (addr, port) => { await super.init(); } - }(addr, port); + }(addr, port, true); }); let agent: supertest.SuperTest; diff --git a/test/AuthenticationNoUsername.test.ts b/test/AuthenticationNoUsername.test.ts index 8930d7d..ba7239d 100644 --- a/test/AuthenticationNoUsername.test.ts +++ b/test/AuthenticationNoUsername.test.ts @@ -37,7 +37,7 @@ useApp(async (addr, port) => { protected getMigrations(): MigrationType[] { return super.getMigrations().filter(m => m !== AddNameToUsersMigration); } - }(addr, port); + }(addr, port, true); }); let agent: supertest.SuperTest; diff --git a/test/CsrfProtectionComponent.test.ts b/test/CsrfProtectionComponent.test.ts index f83a5cb..1cc82f7 100644 --- a/test/CsrfProtectionComponent.test.ts +++ b/test/CsrfProtectionComponent.test.ts @@ -24,7 +24,7 @@ useApp(async (addr, port) => { await super.init(); } - }(addr, port); + }(addr, port, true); }); describe('Test CSRF protection', () => { diff --git a/test/_app.ts b/test/_app.ts index 643d66d..2992023 100644 --- a/test/_app.ts +++ b/test/_app.ts @@ -5,7 +5,7 @@ import MysqlConnectionManager from "../src/db/MysqlConnectionManager"; import config from "config"; -export default function useApp(appSupplier?: (addr: string, port: number) => Promise): void { +export default function useApp(appSupplier?: AppSupplier): void { let app: Application; beforeAll(async (done) => { @@ -14,7 +14,7 @@ export default function useApp(appSupplier?: (addr: string, port: number) => Pro await MysqlConnectionManager.endPool(); await setupMailServer(); - app = appSupplier ? await appSupplier('127.0.0.1', 8966) : new TestApp('127.0.0.1', 8966); + app = appSupplier ? await appSupplier('127.0.0.1', 8966) : new TestApp('127.0.0.1', 8966, true); await app.start(); done(); @@ -39,3 +39,5 @@ export default function useApp(appSupplier?: (addr: string, port: number) => Pro done(); }); } + +export type AppSupplier = (addr: string, port: number) => Promise; From 6973b2600c30f5eafccb8c879a62731b06cb3279 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 30 Mar 2021 12:06:10 +0200 Subject: [PATCH 12/13] Upgrade dependencies --- package.json | 2 +- src/FileUploadMiddleware.ts | 4 +- src/Logger.ts | 2 +- yarn.lock | 1323 ++++++++++++++++++----------------- 4 files changed, 686 insertions(+), 645 deletions(-) diff --git a/package.json b/package.json index 06ac2a8..228d134 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@types/ws": "^7.2.4", "@typescript-eslint/eslint-plugin": "^4.2.0", "@typescript-eslint/parser": "^4.2.0", - "concurrently": "^5.3.0", + "concurrently": "^6.0.0", "eslint": "^7.9.0", "jest": "^26.1.0", "maildev": "^1.1.0", diff --git a/src/FileUploadMiddleware.ts b/src/FileUploadMiddleware.ts index ba4946e..3d0f920 100644 --- a/src/FileUploadMiddleware.ts +++ b/src/FileUploadMiddleware.ts @@ -1,10 +1,10 @@ -import {IncomingForm} from "formidable"; +import Formidable from "formidable"; import Middleware from "./Middleware"; import {NextFunction, Request, Response} from "express"; import {FileError, ValidationBag} from "./db/Validator"; export default abstract class FileUploadMiddleware extends Middleware { - protected abstract makeForm(): IncomingForm; + protected abstract makeForm(): Formidable; protected abstract getDefaultField(): string; diff --git a/src/Logger.ts b/src/Logger.ts index 05ceee6..6384fdd 100644 --- a/src/Logger.ts +++ b/src/Logger.ts @@ -33,7 +33,7 @@ export const preventContextCorruptionMiddleware = (delegate: RequestHandler): Re ) => { const data = requestIdStorage.getStore() as string; - delegate(req, res, (err?: Error | 'router') => { + delegate(req, res, (err?: unknown | 'router') => { requestIdStorage.enterWith(data); next(err); }); diff --git a/yarn.lock b/yarn.lock index e851ac0..10f026a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,36 +16,51 @@ dependencies: "@babel/highlight" "^7.12.13" +"@babel/compat-data@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.12.tgz#a8a5ccac19c200f9dd49624cac6e19d7be1236a1" + integrity sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ== + "@babel/core@^7.1.0", "@babel/core@^7.7.5": - version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.16.tgz#8c6ba456b23b680a6493ddcfcd9d3c3ad51cab7c" - integrity sha512-t/hHIB504wWceOeaOoONOhu+gX+hpjfeN6YRBT209X/4sibZQfSF1I0HFRRlBe97UZZosGx5XwUg1ZgNbelmNw== + version "7.13.14" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.14.tgz#8e46ebbaca460a63497c797e574038ab04ae6d06" + integrity sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA== dependencies: "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.12.15" - "@babel/helper-module-transforms" "^7.12.13" - "@babel/helpers" "^7.12.13" - "@babel/parser" "^7.12.16" + "@babel/generator" "^7.13.9" + "@babel/helper-compilation-targets" "^7.13.13" + "@babel/helper-module-transforms" "^7.13.14" + "@babel/helpers" "^7.13.10" + "@babel/parser" "^7.13.13" "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/traverse" "^7.13.13" + "@babel/types" "^7.13.14" convert-source-map "^1.7.0" debug "^4.1.0" - gensync "^1.0.0-beta.1" + gensync "^1.0.0-beta.2" json5 "^2.1.2" - lodash "^4.17.19" - semver "^5.4.1" + semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.12.13", "@babel/generator@^7.12.15": - version "7.12.15" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.15.tgz#4617b5d0b25cc572474cc1aafee1edeaf9b5368f" - integrity sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ== +"@babel/generator@^7.13.9": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39" + integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw== dependencies: - "@babel/types" "^7.12.13" + "@babel/types" "^7.13.0" jsesc "^2.5.1" source-map "^0.5.0" +"@babel/helper-compilation-targets@^7.13.13": + version "7.13.13" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz#2b2972a0926474853f41e4adbc69338f520600e5" + integrity sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ== + dependencies: + "@babel/compat-data" "^7.13.12" + "@babel/helper-validator-option" "^7.12.17" + browserslist "^4.14.5" + semver "^6.3.0" + "@babel/helper-function-name@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" @@ -62,34 +77,33 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-member-expression-to-functions@^7.12.13": - version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.16.tgz#41e0916b99f8d5f43da4f05d85f4930fa3d62b22" - integrity sha512-zYoZC1uvebBFmj1wFAlXwt35JLEgecefATtKp20xalwEK8vHAixLBXTGxNrVGEmTT+gzOThUgr8UEdgtalc1BQ== +"@babel/helper-member-expression-to-functions@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" + integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== dependencies: - "@babel/types" "^7.12.13" + "@babel/types" "^7.13.12" -"@babel/helper-module-imports@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz#ec67e4404f41750463e455cc3203f6a32e93fcb0" - integrity sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g== +"@babel/helper-module-imports@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" + integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== dependencies: - "@babel/types" "^7.12.13" + "@babel/types" "^7.13.12" -"@babel/helper-module-transforms@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz#01afb052dcad2044289b7b20beb3fa8bd0265bea" - integrity sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA== +"@babel/helper-module-transforms@^7.13.14": + version "7.13.14" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz#e600652ba48ccb1641775413cb32cfa4e8b495ef" + integrity sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g== dependencies: - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-replace-supers" "^7.12.13" - "@babel/helper-simple-access" "^7.12.13" + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-simple-access" "^7.13.12" "@babel/helper-split-export-declaration" "^7.12.13" "@babel/helper-validator-identifier" "^7.12.11" "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" - lodash "^4.17.19" + "@babel/traverse" "^7.13.13" + "@babel/types" "^7.13.14" "@babel/helper-optimise-call-expression@^7.12.13": version "7.12.13" @@ -99,26 +113,26 @@ "@babel/types" "^7.12.13" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.8.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz#174254d0f2424d8aefb4dd48057511247b0a9eeb" - integrity sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" + integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== -"@babel/helper-replace-supers@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz#00ec4fb6862546bd3d0aff9aac56074277173121" - integrity sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg== +"@babel/helper-replace-supers@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" + integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== dependencies: - "@babel/helper-member-expression-to-functions" "^7.12.13" + "@babel/helper-member-expression-to-functions" "^7.13.12" "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.12" -"@babel/helper-simple-access@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz#8478bcc5cacf6aa1672b251c1d2dde5ccd61a6c4" - integrity sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA== +"@babel/helper-simple-access@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" + integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== dependencies: - "@babel/types" "^7.12.13" + "@babel/types" "^7.13.12" "@babel/helper-split-export-declaration@^7.12.13": version "7.12.13" @@ -132,28 +146,33 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== -"@babel/helpers@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.13.tgz#3c75e993632e4dadc0274eae219c73eb7645ba47" - integrity sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ== +"@babel/helper-validator-option@^7.12.17": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" + integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== + +"@babel/helpers@^7.13.10": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.10.tgz#fd8e2ba7488533cdeac45cc158e9ebca5e3c7df8" + integrity sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ== dependencies: "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" "@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c" - integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww== + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" + integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== dependencies: "@babel/helper-validator-identifier" "^7.12.11" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.12.16": - version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.16.tgz#cc31257419d2c3189d394081635703f549fc1ed4" - integrity sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw== +"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.13.13": + version "7.13.13" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df" + integrity sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -240,9 +259,9 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/runtime@^7.8.7": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.13.tgz#0a21452352b02542db0ffb928ac2d3ca7cb6d66d" - integrity sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw== + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" + integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== dependencies: regenerator-runtime "^0.13.4" @@ -255,25 +274,24 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.13.tgz#689f0e4b4c08587ad26622832632735fb8c4e0c0" - integrity sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13": + version "7.13.13" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d" + integrity sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg== dependencies: "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.12.13" + "@babel/generator" "^7.13.9" "@babel/helper-function-name" "^7.12.13" "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/parser" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/parser" "^7.13.13" + "@babel/types" "^7.13.13" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.12.13", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.13.tgz#8be1aa8f2c876da11a9cf650c0ecf656913ad611" - integrity sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ== +"@babel/types@^7.0.0", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.13", "@babel/types@^7.13.14", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.13.14" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.14.tgz#c35a4abb15c7cd45a2746d78ab328e362cbace0d" + integrity sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ== dependencies: "@babel/helper-validator-identifier" "^7.12.11" lodash "^4.17.19" @@ -292,10 +310,10 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@eslint/eslintrc@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318" - integrity sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg== +"@eslint/eslintrc@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.0.tgz#99cc0a0584d72f1df38b900fb062ba995f395547" + integrity sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog== dependencies: ajv "^6.12.4" debug "^4.1.1" @@ -304,7 +322,6 @@ ignore "^4.0.6" import-fresh "^3.2.1" js-yaml "^3.13.1" - lodash "^4.17.20" minimatch "^3.0.4" strip-json-comments "^3.1.1" @@ -548,9 +565,9 @@ defer-to-connect "^1.0.1" "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": - version "7.1.12" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.12.tgz#4d8e9e51eb265552a7e4f1ff2219ab6133bdfb2d" - integrity sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ== + version "7.1.14" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402" + integrity sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -574,9 +591,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.0.tgz#b9a1efa635201ba9bc850323a8793ee2d36c04a0" - integrity sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg== + version "7.11.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" + integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== dependencies: "@babel/types" "^7.3.0" @@ -632,9 +649,9 @@ integrity sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog== "@types/express-serve-static-core@^4.17.18": - version "4.17.18" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz#8371e260f40e0e1ca0c116a9afcd9426fa094c40" - integrity sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA== + version "4.17.19" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz#00acfc1632e729acac4f1530e9e16f6dd1508a1d" + integrity sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA== dependencies: "@types/node" "*" "@types/qs" "*" @@ -658,9 +675,9 @@ "@types/serve-static" "*" "@types/formidable@^1.0.31": - version "1.0.32" - resolved "https://registry.yarnpkg.com/@types/formidable/-/formidable-1.0.32.tgz#d9a7eefbaa995a4486ec4e3960e9552e68b3f33c" - integrity sha512-jOAB5+GFW+C+2xdvUcpd/CnYg2rD5xCyagJLBJU+9PB4a/DKmsAqS9yZI3j/Q9zwvM7ztPHaAIH1ijzp4cezdQ== + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/formidable/-/formidable-1.2.1.tgz#d17006b48acd314df9bcfa04236b3e32de0cc817" + integrity sha512-4sVIjd51AADf4YnpsdqNQh7n3ZRLo16w+w6F7zzKjK6dBsQc9Vrq8GQLpHOOWq0V8Fe2bbp2EpihHx57iVgm5Q== dependencies: "@types/node" "*" @@ -695,10 +712,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@26.x", "@types/jest@^26.0.4": - version "26.0.20" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.20.tgz#cd2f2702ecf69e86b586e1f5223a60e454056307" - integrity sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA== +"@types/jest@^26.0.4": + version "26.0.22" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.22.tgz#8308a1debdf1b807aa47be2838acdcd91e88fbe6" + integrity sha512-eeWwWjlqxvBxc4oQdkueW5OF/gtfSceKk4OnOAGlUSwS/liBRtZppbJuz1YkgbrbfGOoeBHun9fOvXnjNwrSOw== dependencies: jest-diff "^26.0.0" pretty-format "^26.0.0" @@ -726,9 +743,9 @@ "@types/mjml-core" "*" "@types/mysql@^2.15.10": - version "2.15.17" - resolved "https://registry.yarnpkg.com/@types/mysql/-/mysql-2.15.17.tgz#18b9a64b3c83916e768cf0c1bd7469f7ecbb7484" - integrity sha512-5vlnAFgdjFGqu3fHbd+pp+qL9mMty6c/N65TjsT5H+kfet50Qq4tXWMrD5lm/ftXeiEQwbAndZepB/eaLGaTew== + version "2.15.18" + resolved "https://registry.yarnpkg.com/@types/mysql/-/mysql-2.15.18.tgz#eea3f2845e619db0073d63d821aa99bf2079c95c" + integrity sha512-JW74Nh3P/RDAnaP8uXe1qmRpoFBO84SiWvWoSju/F5+2S1kVBi1FbbDoqK/sTZrCCxySaOJnRATvWD+bLcJjAg== dependencies: "@types/node" "*" @@ -748,14 +765,14 @@ form-data "^3.0.0" "@types/node@*": - version "14.14.28" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.28.tgz#cade4b64f8438f588951a6b35843ce536853f25b" - integrity sha512-lg55ArB+ZiHHbBBttLpzD07akz0QPrZgUODNakeC09i62dnrywr9mFErHuaPlB6I7z+sEbK+IYmplahvplCj2g== + version "14.14.37" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" + integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== "@types/nodemailer@^6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.0.tgz#d8c039be3ed685c4719a026455555be82c124b74" - integrity sha512-KY7bFWB0MahRZvVW4CuW83qcCDny59pJJ0MQ5ifvfcjNwPlIT0vW4uARO4u1gtkYnWdhSvURegecY/tzcukJcA== + version "6.4.1" + resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.1.tgz#31f96f4410632f781d3613bd1f4293649e423f75" + integrity sha512-8081UY/0XTTDpuGqCnDc8IY+Q3DSg604wB3dBH0CaZlj4nZWHWuxtZ3NRZ9c9WUrz1Vfm6wioAUnqL3bsh49uQ== dependencies: "@types/node" "*" @@ -777,14 +794,14 @@ "@types/node" "*" "@types/prettier@^2.0.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.1.tgz#374e31645d58cb18a07b3ecd8e9dede4deb2cccd" - integrity sha512-DxZZbyMAM9GWEzXL+BMZROWz9oo6A9EilwwOMET2UVu2uZTqMWS5S69KVtuVKaRjCUpcrOXRalet86/OpG4kqw== + version "2.2.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.3.tgz#ef65165aea2924c9359205bf748865b8881753c0" + integrity sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA== "@types/qs@*": - version "6.9.5" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.5.tgz#434711bdd49eb5ee69d90c1d67c354a9a8ecb18b" - integrity sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ== + version "6.9.6" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.6.tgz#df9c3c8b31a247ec315e6996566be3171df4b3b1" + integrity sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA== "@types/range-parser@*": version "1.2.3" @@ -851,12 +868,12 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^4.2.0": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.15.1.tgz#835f64aa0a403e5e9e64c10ceaf8d05c3f015180" - integrity sha512-yW2epMYZSpNJXZy22Biu+fLdTG8Mn6b22kR3TqblVk50HGNV8Zya15WAXuQCr8tKw4Qf1BL4QtI6kv6PCkLoJw== + version "4.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.20.0.tgz#9d8794bd99aad9153092ad13c96164e3082e9a92" + integrity sha512-sw+3HO5aehYqn5w177z2D82ZQlqHCwcKSMboueo7oE4KU9QiC0SAgfS/D4z9xXvpTc8Bt41Raa9fBR8T2tIhoQ== dependencies: - "@typescript-eslint/experimental-utils" "4.15.1" - "@typescript-eslint/scope-manager" "4.15.1" + "@typescript-eslint/experimental-utils" "4.20.0" + "@typescript-eslint/scope-manager" "4.20.0" debug "^4.1.1" functional-red-black-tree "^1.0.1" lodash "^4.17.15" @@ -864,60 +881,60 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@4.15.1": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.15.1.tgz#d744d1ac40570a84b447f7aa1b526368afd17eec" - integrity sha512-9LQRmOzBRI1iOdJorr4jEnQhadxK4c9R2aEAsm7WE/7dq8wkKD1suaV0S/JucTL8QlYUPU1y2yjqg+aGC0IQBQ== +"@typescript-eslint/experimental-utils@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.20.0.tgz#a8ab2d7b61924f99042b7d77372996d5f41dc44b" + integrity sha512-sQNlf6rjLq2yB5lELl3gOE7OuoA/6IVXJUJ+Vs7emrQMva14CkOwyQwD7CW+TkmOJ4Q/YGmoDLmbfFrpGmbKng== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.15.1" - "@typescript-eslint/types" "4.15.1" - "@typescript-eslint/typescript-estree" "4.15.1" + "@typescript-eslint/scope-manager" "4.20.0" + "@typescript-eslint/types" "4.20.0" + "@typescript-eslint/typescript-estree" "4.20.0" eslint-scope "^5.0.0" eslint-utils "^2.0.0" "@typescript-eslint/parser@^4.2.0": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.15.1.tgz#4c91a0602733db63507e1dbf13187d6c71a153c4" - integrity sha512-V8eXYxNJ9QmXi5ETDguB7O9diAXlIyS+e3xzLoP/oVE4WCAjssxLIa0mqCLsCGXulYJUfT+GV70Jv1vHsdKwtA== + version "4.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.20.0.tgz#8dd403c8b4258b99194972d9799e201b8d083bdd" + integrity sha512-m6vDtgL9EABdjMtKVw5rr6DdeMCH3OA1vFb0dAyuZSa3e5yw1YRzlwFnm9knma9Lz6b2GPvoNSa8vOXrqsaglA== dependencies: - "@typescript-eslint/scope-manager" "4.15.1" - "@typescript-eslint/types" "4.15.1" - "@typescript-eslint/typescript-estree" "4.15.1" + "@typescript-eslint/scope-manager" "4.20.0" + "@typescript-eslint/types" "4.20.0" + "@typescript-eslint/typescript-estree" "4.20.0" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.15.1": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.15.1.tgz#f6511eb38def2a8a6be600c530c243bbb56ac135" - integrity sha512-ibQrTFcAm7yG4C1iwpIYK7vDnFg+fKaZVfvyOm3sNsGAerKfwPVFtYft5EbjzByDJ4dj1WD8/34REJfw/9wdVA== +"@typescript-eslint/scope-manager@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.20.0.tgz#953ecbf3b00845ece7be66246608be9d126d05ca" + integrity sha512-/zm6WR6iclD5HhGpcwl/GOYDTzrTHmvf8LLLkwKqqPKG6+KZt/CfSgPCiybshmck66M2L5fWSF/MKNuCwtKQSQ== dependencies: - "@typescript-eslint/types" "4.15.1" - "@typescript-eslint/visitor-keys" "4.15.1" + "@typescript-eslint/types" "4.20.0" + "@typescript-eslint/visitor-keys" "4.20.0" -"@typescript-eslint/types@4.15.1": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.15.1.tgz#da702f544ef1afae4bc98da699eaecd49cf31c8c" - integrity sha512-iGsaUyWFyLz0mHfXhX4zO6P7O3sExQpBJ2dgXB0G5g/8PRVfBBsmQIc3r83ranEQTALLR3Vko/fnCIVqmH+mPw== +"@typescript-eslint/types@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.20.0.tgz#c6cf5ef3c9b1c8f699a9bbdafb7a1da1ca781225" + integrity sha512-cYY+1PIjei1nk49JAPnH1VEnu7OYdWRdJhYI5wiKOUMhLTG1qsx5cQxCUTuwWCmQoyriadz3Ni8HZmGSofeC+w== -"@typescript-eslint/typescript-estree@4.15.1": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.1.tgz#fa9a9ff88b4a04d901ddbe5b248bc0a00cd610be" - integrity sha512-z8MN3CicTEumrWAEB2e2CcoZa3KP9+SMYLIA2aM49XW3cWIaiVSOAGq30ffR5XHxRirqE90fgLw3e6WmNx5uNw== +"@typescript-eslint/typescript-estree@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.20.0.tgz#8b3b08f85f18a8da5d88f65cb400f013e88ab7be" + integrity sha512-Knpp0reOd4ZsyoEJdW8i/sK3mtZ47Ls7ZHvD8WVABNx5Xnn7KhenMTRGegoyMTx6TiXlOVgMz9r0pDgXTEEIHA== dependencies: - "@typescript-eslint/types" "4.15.1" - "@typescript-eslint/visitor-keys" "4.15.1" + "@typescript-eslint/types" "4.20.0" + "@typescript-eslint/visitor-keys" "4.20.0" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/visitor-keys@4.15.1": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.1.tgz#c76abbf2a3be8a70ed760f0e5756bf62de5865dd" - integrity sha512-tYzaTP9plooRJY8eNlpAewTOqtWW/4ff/5wBjNVaJ0S0wC4Gpq/zDVRTJa5bq2v1pCNQ08xxMCndcvR+h7lMww== +"@typescript-eslint/visitor-keys@4.20.0": + version "4.20.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.20.0.tgz#1e84db034da13f208325e6bfc995c3b75f7dbd62" + integrity sha512-NXKRM3oOVQL8yNFDNCZuieRIwZ5UtjNLYtmMx2PacEAGmbaEYtGgVHUHVyZvU/0rYZcizdrWjDo+WBtRPSgq+A== dependencies: - "@typescript-eslint/types" "4.15.1" + "@typescript-eslint/types" "4.20.0" eslint-visitor-keys "^2.0.0" a-sync-waterfall@^1.0.0: @@ -925,7 +942,7 @@ a-sync-waterfall@^1.0.0: resolved "https://registry.yarnpkg.com/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz#75b6b6aa72598b497a125e7a2770f14f4c8a1fa7" integrity sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA== -abab@^2.0.3: +abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== @@ -966,6 +983,11 @@ acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe" + integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA== + addressparser@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/addressparser/-/addressparser-1.0.1.tgz#47afbe1a2a9262191db6838e4fd1d39b40821746" @@ -986,10 +1008,10 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^7.0.2: - version "7.1.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-7.1.1.tgz#1e6b37a454021fa9941713f38b952fc1c8d32a84" - integrity sha512-ga/aqDYnUy/o7vbsRTFhhTsNeXiYb5JWDIcRIeZfwRNCefwjNTVYCGdGSUrEmiu3yDK3vFvNbgJxvrQW4JXrYQ== +ajv@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.0.1.tgz#dac101898a87f8ebb57fea69617e8096523c628c" + integrity sha512-46ZA4TalFcLLqX1dEU3dhdY38wAtDydJ4e7QQTVekLUTzXkb1LfqU6VOBXC/a9wiv4T094WURqJH6ZitF92Kqw== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -1009,11 +1031,11 @@ ansi-colors@^4.1.1: integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-escapes@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: - type-fest "^0.11.0" + type-fest "^0.21.3" ansi-regex@^2.0.0: version "2.1.1" @@ -1035,7 +1057,7 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -1398,6 +1420,17 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== +browserslist@^4.14.5: + version "4.16.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" + integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== + dependencies: + caniuse-lite "^1.0.30001181" + colorette "^1.2.1" + electron-to-chromium "^1.3.649" + escalade "^3.1.1" + node-releases "^1.1.70" + bs-logger@0.x: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -1460,6 +1493,14 @@ cacheable-request@^6.0.0: normalize-url "^4.1.0" responselike "^1.0.2" +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + callsite@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" @@ -1488,6 +1529,11 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== +caniuse-lite@^1.0.30001181: + version "1.0.30001204" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz#256c85709a348ec4d175e847a3b515c66e79f2aa" + integrity sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -1500,7 +1546,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@^2.0.0, chalk@^2.4.2: +chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1517,7 +1563,7 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== @@ -1618,15 +1664,6 @@ cli-boxes@^2.2.0: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - cliui@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" @@ -1699,6 +1736,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colorette@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + colors@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -1766,20 +1808,20 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concurrently@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-5.3.0.tgz#7500de6410d043c912b2da27de3202cb489b1e7b" - integrity sha512-8MhqOB6PWlBfA2vJ8a0bSFKATOdWlHiQlk11IfmQBPaHVP8oP2gsh2MObE6UR3hqDHqvaIvLTyceNW6obVuFHQ== +concurrently@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.0.0.tgz#c1a876dd99390979c71f8c6fe6796882f3a13199" + integrity sha512-Ik9Igqnef2ONLjN2o/OVx1Ow5tymVvvEwQeYCQdD/oV+CN9oWhxLk7ibcBdOtv0UzBqHCEKRwbKceYoTK8t3fQ== dependencies: - chalk "^2.4.2" - date-fns "^2.0.1" - lodash "^4.17.15" - read-pkg "^4.0.1" - rxjs "^6.5.2" + chalk "^4.1.0" + date-fns "^2.16.1" + lodash "^4.17.20" + read-pkg "^5.2.0" + rxjs "^6.6.3" spawn-command "^0.0.2-1" - supports-color "^6.1.0" + supports-color "^8.1.0" tree-kill "^1.2.2" - yargs "^13.3.0" + yargs "^16.2.0" config-chain@^1.1.12: version "1.1.12" @@ -1790,9 +1832,9 @@ config-chain@^1.1.12: proto-list "~1.2.1" config@^3.3.1: - version "3.3.3" - resolved "https://registry.yarnpkg.com/config/-/config-3.3.3.tgz#d3c110fce543022c2fde28712e4f1b8440dee101" - integrity sha512-T3RmZQEAji5KYqUQpziWtyGJFli6Khz7h0rpxDwYNjSkr5ynyTWwO7WpfjHzTXclNCDfSWQRcwMb+NwxJesCKw== + version "3.3.6" + resolved "https://registry.yarnpkg.com/config/-/config-3.3.6.tgz#b87799db7399cc34988f55379b5f43465b1b065c" + integrity sha512-Hj5916C5HFawjYJat1epbyY2PlAgLpBtDUlr0MxGLgo3p5+7kylyvnRY18PqJHgnNWXcdd0eWDemT7eYWuFgwg== dependencies: json5 "^2.1.1" @@ -1959,7 +2001,7 @@ cssom@~0.3.6: resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^2.2.0: +cssstyle@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== @@ -1982,10 +2024,10 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -date-fns@^2.0.1: - version "2.17.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.17.0.tgz#afa55daea539239db0a64e236ce716ef3d681ba1" - integrity sha512-ZEhqxUtEZeGgg9eHNSOAJ8O9xqSgiJdrL0lzSSfMF54x6KXWJiOH/xntSJ9YomJPrYH/p08t6gWjGWq1SDJlSA== +date-fns@^2.16.1: + version "2.19.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1" + integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg== debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" @@ -2027,7 +2069,7 @@ decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= -decimal.js@^10.2.0: +decimal.js@^10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== @@ -2235,9 +2277,9 @@ domutils@^1.5.1: domelementtype "1" domutils@^2.0.0, domutils@^2.4.3, domutils@^2.4.4: - version "2.4.4" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.4.tgz#282739c4b150d022d34699797369aad8d19bbbd3" - integrity sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA== + version "2.5.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.5.0.tgz#42f49cffdabb92ad243278b331fd761c1c2d3039" + integrity sha512-Ho16rzNMOFk2fPwChGh3D2D9OEHAfG19HgmRR2l+WLSsIstNsAYBzePH412bL0y5T44ejABIVfTHQ8nqi/tBCg== dependencies: dom-serializer "^1.0.1" domelementtype "^2.0.1" @@ -2278,6 +2320,11 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +electron-to-chromium@^1.3.649: + version "1.3.702" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.702.tgz#39b8b6860b22806482ad07a8eaf35f861d4f3ce0" + integrity sha512-qJVUKFWQnF6wP7MmTngDkmm8/KPzaiTXNFOAg5j7DSa6J7kPou7mTBqC8jpUOxauQWwHR3pn4dMRdV8IE1xdtA== + emittery@^0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" @@ -2404,13 +2451,13 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== -escodegen@^1.14.1: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== dependencies: esprima "^4.0.1" - estraverse "^4.2.0" + estraverse "^5.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: @@ -2442,12 +2489,12 @@ eslint-visitor-keys@^2.0.0: integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== eslint@^7.9.0: - version "7.20.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.20.0.tgz#db07c4ca4eda2e2316e7aa57ac7fc91ec550bdc7" - integrity sha512-qGi0CTcOGP2OtCQBgWZlQjcTuP0XkIpYFj25XtRTQSHC+umNnp7UMshr2G8SLsRFYDdAPFeHOsiteadmMH02Yw== + version "7.23.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.23.0.tgz#8d029d252f6e8cf45894b4bee08f5493f8e94325" + integrity sha512-kqvNVbdkjzpFy0XOszNwjkKzZ+6TcwCQ/h+ozlcIWwaimBBuhlQ4nN6kbiM2L+OjDcznkTJxzYfRFH92sx4a0Q== dependencies: "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.3.0" + "@eslint/eslintrc" "^0.4.0" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -2460,10 +2507,10 @@ eslint@^7.9.0: espree "^7.3.1" esquery "^1.4.0" esutils "^2.0.2" - file-entry-cache "^6.0.0" + file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" - globals "^12.1.0" + globals "^13.6.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" @@ -2471,7 +2518,7 @@ eslint@^7.9.0: js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" - lodash "^4.17.20" + lodash "^4.17.21" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" @@ -2512,7 +2559,7 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -2533,9 +2580,9 @@ etag@~1.8.1: integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= exec-sh@^0.3.2: - version "0.3.4" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" - integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== + version "0.3.6" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" + integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== execa@^1.0.0: version "1.0.0" @@ -2722,9 +2769,9 @@ fast-safe-stringify@^2.0.7: integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== fastq@^1.6.0: - version "1.10.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.10.1.tgz#8b8f2ac8bf3632d67afcd65dac248d5fdc45385e" - integrity sha512-AWuv6Ery3pM+dY7LYS8YIaCiQvUaos9OB1RyNgaOWnaX+Tik7Onvcsf8x8c+YtDeT0maYLniBip2hox5KtEXXA== + version "1.11.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" + integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== dependencies: reusify "^1.0.4" @@ -2742,10 +2789,10 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -file-entry-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.0.tgz#7921a89c391c6d93efec2169ac6bf300c527ea0a" - integrity sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA== +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: flat-cache "^3.0.4" @@ -2779,13 +2826,6 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -2898,7 +2938,7 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -gensync@^1.0.0-beta.1: +gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== @@ -2921,6 +2961,15 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -2953,9 +3002,9 @@ getpass@^0.1.1: assert-plus "^1.0.0" glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + 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" @@ -2990,10 +3039,17 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" +globals@^13.6.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.7.0.tgz#aed3bcefd80ad3ec0f0be2cf0c895110c0591795" + integrity sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA== + dependencies: + type-fest "^0.20.2" + globby@^11.0.1: - version "11.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.2.tgz#1af538b766a3b540ebfb58a32b2e2d5897321d83" - integrity sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og== + version "11.0.3" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" + integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" @@ -3064,6 +3120,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-symbols@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -3170,9 +3231,9 @@ htmlparser2@^4.0.0, htmlparser2@^4.1.0: entities "^2.0.0" htmlparser2@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.0.0.tgz#c2da005030390908ca4c91e5629e418e0665ac01" - integrity sha512-numTQtDZMoh78zJpaNdJ9MXb2cv5G3jwUoe3dMQODubZvLoGvTE/Ofp6sHvH8OGKcN/8A47pGLi/k58xHP/Tfw== + version "6.0.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.0.1.tgz#422521231ef6d42e56bd411da8ba40aa36e91446" + integrity sha512-GDKPd+vk4jvSuvCbyuzx/unmXkk090Azec7LovXP8as1Hn8q9p3hbjmDGbUqqhknw0ajwit6LiiWqfiTUPMK7w== dependencies: domelementtype "^2.0.1" domhandler "^4.0.0" @@ -3317,11 +3378,6 @@ ip-address@^5.8.9: lodash "^4.17.15" sprintf-js "1.1.2" -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -3358,6 +3414,13 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-boolean-object@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" + integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== + dependencies: + call-bind "^1.0.0" + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -3473,6 +3536,11 @@ is-npm@^4.0.0: resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== +is-number-object@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" + integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -3491,9 +3559,9 @@ is-obj@^2.0.0: integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== is-path-inside@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" - integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== + 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" @@ -3517,6 +3585,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -4025,35 +4098,35 @@ jsbn@~0.1.0: integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= jsdom@^16.4.0: - version "16.4.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.4.0.tgz#36005bde2d136f73eee1a830c6d45e55408edddb" - integrity sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w== + version "16.5.2" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.2.tgz#583fac89a0aea31dbf6237e7e4bedccd9beab472" + integrity sha512-JxNtPt9C1ut85boCbJmffaQ06NBnzkQY/MWO3YxPW8IWS38A26z+B1oBvA9LwKrytewdfymnhi4UNH3/RAgZrg== dependencies: - abab "^2.0.3" - acorn "^7.1.1" + abab "^2.0.5" + acorn "^8.1.0" acorn-globals "^6.0.0" cssom "^0.4.4" - cssstyle "^2.2.0" + cssstyle "^2.3.0" data-urls "^2.0.0" - decimal.js "^10.2.0" + decimal.js "^10.2.1" domexception "^2.0.1" - escodegen "^1.14.1" + escodegen "^2.0.0" html-encoding-sniffer "^2.0.1" is-potential-custom-element-name "^1.0.0" nwsapi "^2.2.0" - parse5 "5.1.1" + parse5 "6.0.1" request "^2.88.2" - request-promise-native "^1.0.8" - saxes "^5.0.0" + request-promise-native "^1.0.9" + saxes "^5.0.1" symbol-tree "^3.2.4" - tough-cookie "^3.0.1" + tough-cookie "^4.0.0" w3c-hr-time "^1.0.2" w3c-xmlserializer "^2.0.0" webidl-conversions "^6.1.0" whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - ws "^7.2.3" + whatwg-url "^8.5.0" + ws "^7.4.4" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -4066,11 +4139,6 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -4203,14 +4271,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -4218,15 +4278,25 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= -lodash@4.x, lodash@^4.15.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +lodash.flatten@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= + +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@4.x, lodash@^4.15.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== lower-case@^1.1.1: version "1.1.4" @@ -4440,46 +4510,46 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mjml-accordion@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-accordion/-/mjml-accordion-4.8.1.tgz#8917b263336acca062665d9f37eb9fb2b77eaf3e" - integrity sha512-VviMSaWlHkiTt0bVSdaIeDQjkApAjJR2whEhVvQmEjpu5gJdUS2Po6dQHrd/0ub8gCVMzVq62UKJdPM0fTBlMw== +mjml-accordion@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-accordion/-/mjml-accordion-4.9.0.tgz#013b7b3d1d52b059fdcbd83cdd67d6414a463e19" + integrity sha512-wj8Z2Nm8brZQzVHE6Uds7dMjBq/cjyC6UhPbaG2QpkfvTTZ7fxEIVS2LJgeAkuqHjnzQJNvQU8cFWRiB2Uw5zQ== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-body@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-body/-/mjml-body-4.8.1.tgz#6bca36a037410f8c11cd23e4b210bbbd424c59b2" - integrity sha512-L8DjOveb1GsxSAOye7CyeTsqBQ13DBQCuRVz9dXF1pjycawgK3eBvMHhlXAkCcuNlRUuH0/jI04f2whkYTYOZg== +mjml-body@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-body/-/mjml-body-4.9.0.tgz#b66c44937e1f92c2ee1256135be125591175f4a0" + integrity sha512-1CvOpMchVwauVH0PEqd2yfPQAxXJ2E1OEPFItQfs2M1rFl0RHdN1TvkJmSig05WKGirTn/5AMZlKZSnl3cWTZw== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-button@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-button/-/mjml-button-4.8.1.tgz#c0677d128e28acf74b65a34237a12248442cf48f" - integrity sha512-qiPtRQkC1/4QjHPTA8NvpVgK8jRIevEo2pgxw8gDsstkWSnV/TxrzQxQ6iWaWI7gGD3ZOQUMvVTpUeuPAJGssw== +mjml-button@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-button/-/mjml-button-4.9.0.tgz#6d4b0cbaa176acb695e07acc6ec15842287cafaf" + integrity sha512-7kNE77NF3qKsE5a+ZSvpNaE8mrariokISwFsfxDTL3+GNuPas3dGIFCOYkMYXRu8wCWoNNh4eTd4GmnLieKGaA== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-carousel@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-carousel/-/mjml-carousel-4.8.1.tgz#ecad8db5c3a251978fb2d9ec92f15e4acae1e8a5" - integrity sha512-YlYy6sQuhi1Q889WW9OwQp9qZvb0mR7M/9rnCgRzI5SFd9dICwafEz5hKHTfy4o/d1CWnKF5Gp/ovg/Ci6pm4A== +mjml-carousel@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-carousel/-/mjml-carousel-4.9.0.tgz#95ade8d0bee7354cdfd006a478c713472a1ac612" + integrity sha512-Xgo5is2dpSdfeaPZ91mJ34jBTDCS4hLvc6X6VGcV9oUUvpO7ttDuKw6hMKevS123L9Xyl7NYn6e+5ZtR/JElIQ== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-cli@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-cli/-/mjml-cli-4.8.1.tgz#04ef02f7cbec9de1744d69a856319d70b071607d" - integrity sha512-Yb/Ykwin4XLpX9uonFW1GK7aMc3CBUDtcbPsVMC/p9g3U1rXi/Bp4MFpya8WoHT9D4N97gGJPEQ7ndCrzMrgNQ== +mjml-cli@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-cli/-/mjml-cli-4.9.0.tgz#63d0214dd6423e7e9b40d41847b2b3492ee0cfe1" + integrity sha512-FOkmYvFYMn17wON3i3Sm86SjcLwqXFEfZR2lOc/5zvyEN3JpUna/8v2Tt9EeP+S38sWyDarVlKtilJnKKm/7Lg== dependencies: "@babel/runtime" "^7.8.7" chokidar "^3.0.0" @@ -4487,25 +4557,25 @@ mjml-cli@4.8.1: html-minifier "^4.0.0" js-beautify "^1.6.14" lodash "^4.17.15" - mjml-core "4.8.1" - mjml-migrate "4.8.1" - mjml-parser-xml "4.8.1" - mjml-validator "4.8.1" + mjml-core "4.9.0" + mjml-migrate "4.9.0" + mjml-parser-xml "4.9.0" + mjml-validator "4.9.0" yargs "^16.1.0" -mjml-column@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-column/-/mjml-column-4.8.1.tgz#f6b0a65a9b611c6f6feddfd88d3dd5453c1be42c" - integrity sha512-8UlYNtBgcEylnFAA+il+LEeuP8sf91ml7v9yV9GWVZpdS9o2eQI1LHtmlEZ6+PDVG9CYpmTm1XZ0YWqBsVVtBg== +mjml-column@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-column/-/mjml-column-4.9.0.tgz#821579a5e51359258b45b521d2051d0d9585147c" + integrity sha512-lFkYgxx8aRPChEV8hBpgOXAtQFw6YT9WuwbMfvNnUz0R9aIE7rvWLxMaHXsslla4YZz+LB3amPJgeqlDZ9HNjg== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-core@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-core/-/mjml-core-4.8.1.tgz#96dd54760411423fb579816da68adfa97530f66f" - integrity sha512-CXKzgu3BjgtSfNKDeihK75fLOhhimEZK4eU5ZCgVgtD5S3txfyA+IbRPKikcj5V/vF1Zxfipr3P4SMnVAIi1vA== +mjml-core@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-core/-/mjml-core-4.9.0.tgz#aa6d40881c4062e9ccf0d6a0c12b55c38943f0a4" + integrity sha512-89mMFH2+CwMXhEMgy1PT/KrqjOBcl4yezdZk/I3JezIYhv39kaa2Q0yt2uOmdDwxGIVkLAtA32Kug/a1K+zbQQ== dependencies: "@babel/runtime" "^7.8.7" cheerio "1.0.0-rc.3" @@ -4514,255 +4584,263 @@ mjml-core@4.8.1: js-beautify "^1.6.14" juice "^7.0.0" lodash "^4.17.15" - mjml-migrate "4.8.1" - mjml-parser-xml "4.8.1" - mjml-validator "4.8.1" + mjml-migrate "4.9.0" + mjml-parser-xml "4.9.0" + mjml-validator "4.9.0" -mjml-divider@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-divider/-/mjml-divider-4.8.1.tgz#ca352e9de33cd9aba6fef76b791dcd75caa5ef33" - integrity sha512-kaDHd++6qfOp79dm9k/3o4uMLvhSMy01HjWO5+HCYGv9V4ZLHRHmz8MJVz9plpRByRsOV0gw88vXDNiGVqX6Eg== +mjml-divider@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-divider/-/mjml-divider-4.9.0.tgz#e384c9f5a72cc438db97e67ceecdb26103a3908c" + integrity sha512-DYsFunfmhtlUQ9Fkf2ZZGkMdWALStcZZcFJBLQMpz07UzpVeWgvlH1o2MPn81rfyDpwMBW6PgwoGlZ7tcpAP8Q== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-group@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-group/-/mjml-group-4.8.1.tgz#949c1f8580c1edf86dd33d5773c54799c0bb876a" - integrity sha512-839DbzEg9GzXgwjXSJZFcx3k18DiklAHCnhpy/fbH5C1IbFU0W5I3V105p2a9jeXVIvrRiDw4pCjoPSJsNu5lQ== +mjml-group@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-group/-/mjml-group-4.9.0.tgz#58058aa19d94e51315f5f64c0ecd2c56d81a2f7b" + integrity sha512-/CH6gQ1qzaG/3P5pKttSGRZaY3FB8pEsyiUNDIV8yEqgu0AYYLT7LOFyIEqC3+BYYLavecnyelyEKbiM0+qZaA== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-head-attributes@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-head-attributes/-/mjml-head-attributes-4.8.1.tgz#ba64ec9183e578c3758a4fbcc3e10563a9a819f2" - integrity sha512-PthSJB+znbNfOZ5DHFiuoY9hG97rgmcKzq0Htn6YQuzVFEtvrKXf7cj57M23RkFq2Gcyvn/8VJ98F6kG1Pfq7A== +mjml-head-attributes@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-head-attributes/-/mjml-head-attributes-4.9.0.tgz#34facdbdd85dc9708f6ba960529142972474d79a" + integrity sha512-QCCkcYIGDxdfBeI4Oy5jPHvmUCPmhTA6Fy4o3kLLpv+MoG9aDdJIH7SGrQoy2BoQp/MYoMPxau3miY10P/Ozwg== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-head-breakpoint@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-head-breakpoint/-/mjml-head-breakpoint-4.8.1.tgz#4f3ccf56e7ae3469bc47ace220cc0ac255802abb" - integrity sha512-ABL6L5GKRE3wWY5YOZEHDp5MQN1oV9srTR13Ohe/IC3MHaLv78T98E8iEBYr51RnVlfMkhfGNJF8vn6C8EXIFQ== +mjml-head-breakpoint@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-head-breakpoint/-/mjml-head-breakpoint-4.9.0.tgz#4986c47a0efc44bf71449f9232a35ebb571135d8" + integrity sha512-GXyIe2QBNll1DX1dPPOrww+wW/GqaV8GkBmzfyL3OCN2k5N1eYTx6FP9VPkJi43EDvRALgQJK7sy8CeWWAnVvA== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-head-font@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-head-font/-/mjml-head-font-4.8.1.tgz#ca326e2d73054bc837add59cbf07eca42cfaecbb" - integrity sha512-Gm4QOKQOE87D6pCor1IqBT76PPd0fhtSXWpceacf9oS8QtZtI1VjNuP7TiEk+T5DZo5mM+0zKuhrW7EUPfku3w== +mjml-head-font@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-head-font/-/mjml-head-font-4.9.0.tgz#89e3e05e75ee18ae90db76ca469496411a4914a5" + integrity sha512-pqJcG0jpCYxsV8FjLrtbgCzU23z0kalwcxaOpulCXonSsfUNRtp68TVE2L1rNkcLrwhjIdlLoGHBAPLo47uQdg== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-head-html-attributes@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-head-html-attributes/-/mjml-head-html-attributes-4.8.1.tgz#28bee85179554c0d93de47e5ab7b604da592514f" - integrity sha512-WNZnF0+2Q3aBAYXvthiOHg4URPxUKdTSNmCsrTajqDrP/1A0lin5uLrKc/BGf2MiiBtSvz2kUYbkEBPn7qvSBA== +mjml-head-html-attributes@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-head-html-attributes/-/mjml-head-html-attributes-4.9.0.tgz#543dda655f30e1f9d642a9747b9478d2a9c6b936" + integrity sha512-NSLEiq8cs+8AYdZrbIxsNTWqUEkRMxtAD294YsGvM5NsuzAJOGqJ/BT+aZbm3qiMKeWhaj9OPiph6VV/k+IUzw== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-head-preview@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-head-preview/-/mjml-head-preview-4.8.1.tgz#0757a5ba4ef91a72b0e1b4c093fe356539d49d98" - integrity sha512-7u9Y7p9DpmGedKMAzvRPl5u3vazi7AWj1iNV/cHyt6couWlszrLGiG2L9dxr58zSfsxvAyGLH+dVcx/qRsQwZA== +mjml-head-preview@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-head-preview/-/mjml-head-preview-4.9.0.tgz#76606e867b9ad00d526387f176a003213453f8c1" + integrity sha512-ZiNJFyuMWbvUHJVszPa9EkadeapeWoQdTYjqBio+QOQYcwIGmrsIu0P2ffaLqRUYZLubudF5+1eGGGKRy0cOAw== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-head-style@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-head-style/-/mjml-head-style-4.8.1.tgz#e0e4c74b2df54d45343a4474fffaf481786e82f4" - integrity sha512-QeYHhSPzv3fV5vM1huFiERmLZ/UzJAxqSz/BJiqwZ0qawWLxVG6ku8VTwNQdiWKD4Wnsiijre41rwPttv4OiJQ== +mjml-head-style@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-head-style/-/mjml-head-style-4.9.0.tgz#c1bcb242795aac33d8637ba85fe788c6b79afeb2" + integrity sha512-t/aVMReqYMyXwzedMMCM/TLGboqkpRlbuHixOjG9AnNug1QuDnuAj0mE5sFVbbxz1bcuE+rGJ0Q69ynkNTW2rQ== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-head-title@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-head-title/-/mjml-head-title-4.8.1.tgz#ee9c5035d1fcc2663e569b349e1ca05543b1b4a3" - integrity sha512-Nc49MlGxML4orDL9XKMnaZDHFSivGZnOTls/TH4nkZG+TLMzLf/6+f//Im1x8XiLKhWgETuGff7eFc1PadxVKg== +mjml-head-title@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-head-title/-/mjml-head-title-4.9.0.tgz#3e612d6f397e86b825c5a6ef7464d7607118114d" + integrity sha512-+QxEtIWvgqOjbQNEvS3/IYTrVORpIVffpsEsoPlcgO7K0i6Q+Q7i/O2u3ViFfUW5y7p/tjO0P1TP6nQX+H5lQw== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-head@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-head/-/mjml-head-4.8.1.tgz#d2e24096ca49f450937f7ccf4b33a3dc9e61c53a" - integrity sha512-6UeXCXFN/+8ehwE20weE68Kx1kaWySdffqPm2zjvDdOWQPEAO9tx3FnJk3MuR0kZ6vcvuM0KXYLXlC5rJS02Dg== +mjml-head@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-head/-/mjml-head-4.9.0.tgz#645d1a9047ff7483dcb234a7ca7a0e027a795b39" + integrity sha512-CA8iJBp8DjI20j2quJbvB55h2tM+rVaYcB2rPykLq/kQuNEdgxEtIEuHWr1QMteBf0smXfSK/UDw4/vp2Ja0Cw== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-hero@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-hero/-/mjml-hero-4.8.1.tgz#8524d9c66541afa506c645d1f3614cf801e5c408" - integrity sha512-LYe1mzNySN0M/ZHx8IMB5+v5MzKVHElujzywEFKnAFycWXPjRTvFUDp+PzWP55rbg5GILu4+pgD8ePZH02DHOQ== +mjml-hero@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-hero/-/mjml-hero-4.9.0.tgz#4952c40b860b3be1abb1345c5eae5518aa720250" + integrity sha512-yPpfn5uHL86oWlG0utcJ5SxHEmnsBK8n+SILhDSUbi8cLHWkloCrsuwGOYM9ebD1lcw09if9jPvXUZi0wNYHag== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-image@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-image/-/mjml-image-4.8.1.tgz#11884e8358764a06261c16605f8d5b2ea09c538f" - integrity sha512-3xHmUhdfoOVFzXkFV0bpq84ZGQgQrJbCVeArpz7DdwjjaEER7cYoleAMPtlgOlEyx1TwAJzClpIRO887MkV/qg== +mjml-image@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-image/-/mjml-image-4.9.0.tgz#d7d1d78c5e735e4568ca7cb4f0ae7f5184a0c692" + integrity sha512-hKjW07e+K5pZBPGkC5EXYVEalrWA91+ut+X8guMZOie89XlT/pDDotXXZnocB2hmo75c2lEoMW/ygTbc+Xmv0g== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-migrate@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-migrate/-/mjml-migrate-4.8.1.tgz#e74f42e5b7baaa475ce1e784cc90e535f45309d0" - integrity sha512-U8s9uzgjsOt9so+oqq9Dd9x/bZfkPva8euzF2RiN09wfUIKfglMblZyarsbaVTyFT3BOFKbJ091YcVBobsCJiQ== +mjml-migrate@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-migrate/-/mjml-migrate-4.9.0.tgz#6dcc2fa611115afaf2a559494bf4f11411ca059e" + integrity sha512-rKqy9isx73tD85zcghuj1krIUHky0o/MuQEDOaStcaln6LlR9019tLTbgMefjBflcHNDL0BgMFzp/jdP35u13w== dependencies: "@babel/runtime" "^7.8.7" js-beautify "^1.6.14" lodash "^4.17.15" - mjml-core "4.8.1" - mjml-parser-xml "4.8.1" + mjml-core "4.9.0" + mjml-parser-xml "4.9.0" yargs "^16.1.0" -mjml-navbar@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-navbar/-/mjml-navbar-4.8.1.tgz#365f2b55980e9b247a67646b85922c6a29566ebd" - integrity sha512-6Y3ITpDYz9HytT69A59hk50/y1r7iOkGQL7PP2qltWAjj2eHxUpu0dsPfPvV0a2X6HB9DXOSPJSWdHNHowI/dQ== +mjml-navbar@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-navbar/-/mjml-navbar-4.9.0.tgz#1fe1be1ae8bde965d6e598fc186ef960c6c9ebeb" + integrity sha512-hH+xo6rVfFVT+M/1nhnIyE6lmHHLoZrrdrfJwTx6xPV2mw05fbDFNNnfK2T+8PU9koYpU2RYo2ZahVa1LxYU0A== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-parser-xml@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-parser-xml/-/mjml-parser-xml-4.8.1.tgz#0eddf3d6c070e01ba73e366865b9f3ff6f8ff016" - integrity sha512-kU9IpBVWfeDad/vuDpBt0okz9yRyvy+H6JRZqrUm+qDkzNQHEChnLl3U47FYj81SMuh0CVTGatCIi05pFC396g== +mjml-parser-xml@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-parser-xml/-/mjml-parser-xml-4.9.0.tgz#895015481cfbdaa6fe5d4e16b15671dbf4a451ee" + integrity sha512-YD9BMjr7l5B49czSj2OtLW5+1i53GgMnroIt84F+QUWUz9f6pyeK4cyUO/L5wKW+WiTVM3O0q142Bmq45PZvyA== dependencies: "@babel/runtime" "^7.8.7" detect-node "2.0.4" htmlparser2 "^4.1.0" lodash "^4.17.15" -mjml-raw@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-raw/-/mjml-raw-4.8.1.tgz#c2c1ac30677bce3ed57f63138194ff2dc7a37921" - integrity sha512-NIwHVcFDCOuFHB9dY1fLyRSRTuq//FcYPyorJrEt9TTEY16KznjRyJvJohPbF7bcLoYiqBUDFSRtI7qJFTFapg== +mjml-preset-core@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-preset-core/-/mjml-preset-core-4.9.0.tgz#6a6e2aec7402060b42a93737400c5aefe4d06945" + integrity sha512-sNWt6sffvzgvBgrZA1LclxAV/YuWy2UZIBuGbTjKVhYil1EfrH8SeZClyIBcVW42vx7qDRVnPYrV7w88CBRzOQ== + dependencies: + "@babel/runtime" "^7.8.7" + mjml-accordion "4.9.0" + mjml-body "4.9.0" + mjml-button "4.9.0" + mjml-carousel "4.9.0" + mjml-column "4.9.0" + mjml-divider "4.9.0" + mjml-group "4.9.0" + mjml-head "4.9.0" + mjml-head-attributes "4.9.0" + mjml-head-breakpoint "4.9.0" + mjml-head-font "4.9.0" + mjml-head-html-attributes "4.9.0" + mjml-head-preview "4.9.0" + mjml-head-style "4.9.0" + mjml-head-title "4.9.0" + mjml-hero "4.9.0" + mjml-image "4.9.0" + mjml-navbar "4.9.0" + mjml-raw "4.9.0" + mjml-section "4.9.0" + mjml-social "4.9.0" + mjml-spacer "4.9.0" + mjml-table "4.9.0" + mjml-text "4.9.0" + mjml-wrapper "4.9.0" + +mjml-raw@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-raw/-/mjml-raw-4.9.0.tgz#f00894cf2cd5570d19b243cd243fbf0d432abde0" + integrity sha512-gKNEqpPDPYPdSoHy+/JdUeclnuHEsF8SWVgMkthc3581T2qefYZAORU7Kj1BZWTIsxObcGYfWJu6kQWKVpj8PA== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-section@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-section/-/mjml-section-4.8.1.tgz#f8341cbd8acceee609234b2fea619207cccb48f1" - integrity sha512-cksu5rVBioDjNZyyWBwV2oW+HdUGrESMQSACrJCgeQFTbkJ7GdiCqsGOGTZN4OoM8DvHAizXzOXHZY9GPC4M8g== +mjml-section@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-section/-/mjml-section-4.9.0.tgz#934f14bb547c383794b4492e50165472f335a7a3" + integrity sha512-9SdCf+Jf2ezhA6y/zEjvPvAyyccyRwpqusI2M83guM40tFzevknjMqzM1MnHAebQiXwS4+3xfoTHas5GgJhFqA== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-social@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-social/-/mjml-social-4.8.1.tgz#ffb72c2db75a346b43267df87bca29192054623c" - integrity sha512-YU0eJg0BnqfV1JzHONWabnZ8c1xJATezVXe1z0xMhXpe/lPPWRjqv97Sf06h2NoK8z9F6PvifHBVv6/kU0HU6g== +mjml-social@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-social/-/mjml-social-4.9.0.tgz#05a6328f2e03844cd1e8b1adbdd81b69b47a64d1" + integrity sha512-CxbUP5Kv7Mzag5wf1js31RaZCPeQMV7JgeYaFAFMNp8f3PF6p33nS4FMFQpyGsoYKUSTkRCaSDFnjHR4MMfibw== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-spacer@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-spacer/-/mjml-spacer-4.8.1.tgz#be24302a29fb2083bfd74ab31d00ec08e142920e" - integrity sha512-pMvL2YK0Phb7m78cwipWb+OmvP1TT1spsYDtC1qFuK46vkdOpesGS9dhPMG5iApbaKOcdmoIENtsD01agIzjjw== +mjml-spacer@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-spacer/-/mjml-spacer-4.9.0.tgz#515010491530654ea8344b0639ccfbb54bfddc61" + integrity sha512-UXZEnvxjqajXXRkYrV6a2TN1PBKKkhb8DM4zvlgwZrllh/fEimiu1GWZm2AfCvp1Yax+uuDG3dXr37xVk0B+Hg== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-table@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-table/-/mjml-table-4.8.1.tgz#a50479e51aeb28d31492b57924ad355a3e746525" - integrity sha512-aXOThuC9d3wcnuigefqPcUTticSKul9+ElFKDiX5SEGmXbr3g5Mp3TaM9218GaXfyGJNFEe4eWfiwqjeRv8Fmw== +mjml-table@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-table/-/mjml-table-4.9.0.tgz#0edc74b7e34d19368177f62d2fb3e6bb1048d41d" + integrity sha512-cFKO5tQGxpJCzK1W5aDjkY0BVXfFEVG7akNp3bVeHO0hjdR2Gdvd/hVJPOqhG1aL4PmqJuTZhrMchTTTbifezA== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-text@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-text/-/mjml-text-4.8.1.tgz#01dd3579f1fa5c3a1379d5965ee61450af0c8ad5" - integrity sha512-wA+/pMEmJqDnSR45w6jon/f2HGnLddcc19DNo77EfW8yw6KVyjvDdRs5y6L0S7Ri265AsgzvG7hNbJ31AwjtJw== +mjml-text@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-text/-/mjml-text-4.9.0.tgz#34a00e2e69478efff3313e9152e82699a20b9f6b" + integrity sha512-734JDf1uDiEn0q9fAkW09FHGFBteLYyBGCd8xK5vqenbO0dtEp/j1vjKaw9yMUd6K4MZp4+r7e1N3DsZto4uSQ== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" + mjml-core "4.9.0" -mjml-validator@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-validator/-/mjml-validator-4.8.1.tgz#936ffc0c8f98803ffac1028bbcdb718d614ad538" - integrity sha512-5qykc1kLILqj89Zqij6SsuKHG/jp5mjJfZWFpC8sEKIPVxBKBduz3BNSp5KABue1wW17swaXyMFhCjiFD+QRrg== +mjml-validator@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-validator/-/mjml-validator-4.9.0.tgz#3874d6f17610eeafac16f549c6ca5402e21063f4" + integrity sha512-ta6ipn9QiIFzsLq6yT+CIsadB/GHVTbRYQ7AIBowlrHSREmip4pxPDk6WdaQtjFfG9XD4GQwbJoUbKCERFDg6w== dependencies: "@babel/runtime" "^7.8.7" -mjml-wrapper@4.8.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml-wrapper/-/mjml-wrapper-4.8.1.tgz#93b94624bb789986d911922c4bac18b550f22843" - integrity sha512-PgOg6sEW/bXOnvMt5L2KuJCdlsOclw+GqH9Cf3gVHgw2P+7OfLIp6p+gByYTwjc4JAoUz0mfcCWdZ9HRMSCcYQ== +mjml-wrapper@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml-wrapper/-/mjml-wrapper-4.9.0.tgz#b598140493856268e320fc76a6a035e45e8b0de6" + integrity sha512-fhaa/KIJKEc/SLeYCKF6D8/iQAEM8OFGbna1CdflxbS6Sn3N9wWprWypZN5kbc9zXRR0+G+yI7b19mTYs4Iv0g== dependencies: "@babel/runtime" "^7.8.7" lodash "^4.17.15" - mjml-core "4.8.1" - mjml-section "4.8.1" + mjml-core "4.9.0" + mjml-section "4.9.0" mjml@^4.6.2: - version "4.8.1" - resolved "https://registry.yarnpkg.com/mjml/-/mjml-4.8.1.tgz#32b65a98c4bab7a5a1f51b784fae92c768b35b5b" - integrity sha512-jdKABiLBA1IJ0qTA5QVVsi/NN5GFtdvC1lxwdxrYV6J7dcJW7Z07j3r/GmJyOc2cznCFpJFKzfYV4Z6OZS4iyw== + version "4.9.0" + resolved "https://registry.yarnpkg.com/mjml/-/mjml-4.9.0.tgz#36862201c7d00c908f3859b063ac9667c2274d90" + integrity sha512-34oQtWxbNEwGBCAESAYRtmKdgicIYBWjfB4NY2OzufQ4JxK5BdpvWWVAoG5moty/cxKuhgSh7Q9DSaSWrdmvRA== dependencies: "@babel/runtime" "^7.8.7" - mjml-accordion "4.8.1" - mjml-body "4.8.1" - mjml-button "4.8.1" - mjml-carousel "4.8.1" - mjml-cli "4.8.1" - mjml-column "4.8.1" - mjml-core "4.8.1" - mjml-divider "4.8.1" - mjml-group "4.8.1" - mjml-head "4.8.1" - mjml-head-attributes "4.8.1" - mjml-head-breakpoint "4.8.1" - mjml-head-font "4.8.1" - mjml-head-html-attributes "4.8.1" - mjml-head-preview "4.8.1" - mjml-head-style "4.8.1" - mjml-head-title "4.8.1" - mjml-hero "4.8.1" - mjml-image "4.8.1" - mjml-migrate "4.8.1" - mjml-navbar "4.8.1" - mjml-raw "4.8.1" - mjml-section "4.8.1" - mjml-social "4.8.1" - mjml-spacer "4.8.1" - mjml-table "4.8.1" - mjml-text "4.8.1" - mjml-validator "4.8.1" - mjml-wrapper "4.8.1" + mjml-cli "4.9.0" + mjml-core "4.9.0" + mjml-migrate "4.9.0" + mjml-preset-core "4.9.0" + mjml-validator "4.9.0" mkdirp@1.x, mkdirp@^1.0.4: version "1.0.4" @@ -4807,9 +4885,9 @@ mysql@^2.18.1: sqlstring "2.3.1" nanoid@^3.1.20: - version "3.1.20" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" - integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== + version "3.1.22" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" + integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== nanomatch@^1.2.9: version "1.2.13" @@ -4880,9 +4958,9 @@ node-modules-regexp@^1.0.0: integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= node-notifier@^8.0.0: - version "8.0.1" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.1.tgz#f86e89bbc925f2b068784b31f382afdc6ca56be1" - integrity sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA== + version "8.0.2" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5" + integrity sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg== dependencies: growly "^1.3.0" is-wsl "^2.2.0" @@ -4907,6 +4985,11 @@ node-pre-gyp@^0.17.0: semver "^5.7.1" tar "^4.4.13" +node-releases@^1.1.70: + version "1.1.71" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" + integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== + nodemailer@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-5.0.0.tgz#bcb409eca613114e85de42646d0ce7f1fa70b716" @@ -4918,9 +5001,9 @@ nodemailer@^3.1.1: integrity sha1-/r+sy0vSc2eEc6MJxstLSi88SOM= nodemailer@^6.4.6: - version "6.4.18" - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.18.tgz#2788c85792844fc17befda019031609017f4b9a1" - integrity sha512-ht9cXxQ+lTC+t00vkSIpKHIyM4aXIsQ1tcbQCn5IOnxYHi81W2XOaU66EQBFFpbtzLEBTC94gmkbD4mGZQzVpA== + version "6.5.0" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.5.0.tgz#d12c28d8d48778918e25f1999d97910231b175d9" + integrity sha512-Tm4RPrrIZbnqDKAvX+/4M+zovEReiKlEXWDzG4iwtpL9X34MJY+D5LnQPH/+eghe8DLlAVshHAJZAZWBGhkguw== nodemon@^2.0.6: version "2.0.7" @@ -4960,7 +5043,7 @@ nopt@~1.0.10: dependencies: abbrev "1" -normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: +normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -5089,6 +5172,11 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-inspect@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" + integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== + object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -5198,20 +5286,13 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-limit@^2.0.0, p-limit@^2.2.0: +p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -5248,14 +5329,6 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - parse-json@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -5273,10 +5346,10 @@ parse5-htmlparser2-tree-adapter@^6.0.0: dependencies: parse5 "^6.0.1" -parse5@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== +parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== parse5@^3.0.1: version "3.0.3" @@ -5285,11 +5358,6 @@ parse5@^3.0.1: dependencies: "@types/node" "*" -parse5@^6.0.0, parse5@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - parseqs@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" @@ -5314,11 +5382,6 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -5369,11 +5432,6 @@ picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -5454,7 +5512,7 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= -psl@^1.1.28: +psl@^1.1.28, psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -5490,9 +5548,11 @@ qs@6.7.0: integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== qs@^6.9.4: - version "6.9.6" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" - integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== + version "6.10.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" + integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== + dependencies: + side-channel "^1.0.4" qs@~6.5.2: version "6.5.2" @@ -5500,9 +5560,9 @@ qs@~6.5.2: integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== queue-microtask@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.2.tgz#abf64491e6ecf0f38a6502403d4cda04f372dfd3" - integrity sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg== + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== random-bytes@~1.0.0: version "1.0.0" @@ -5535,9 +5595,9 @@ rc@^1.2.8: strip-json-comments "~2.0.1" react-is@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" - integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== read-pkg-up@^7.0.1: version "7.0.1" @@ -5548,15 +5608,6 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" -read-pkg@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" - integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= - dependencies: - normalize-package-data "^2.3.2" - parse-json "^4.0.0" - pify "^3.0.0" - read-pkg@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" @@ -5682,7 +5733,7 @@ request-promise-core@1.1.4: dependencies: lodash "^4.17.19" -request-promise-native@^1.0.8: +request-promise-native@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== @@ -5805,10 +5856,10 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^6.5.2: - version "6.6.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" - integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== +rxjs@^6.6.3: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" @@ -5859,7 +5910,7 @@ sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^5.0.0: +saxes@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== @@ -5873,15 +5924,15 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: +"semver@2 || 3 || 4 || 5", 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" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@7.x, semver@^7.2.1, semver@^7.3.2: - version "7.3.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" - integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: lru-cache "^6.0.0" @@ -5968,6 +6019,15 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + sigmund@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" @@ -6227,9 +6287,9 @@ stealthy-require@^1.1.1: integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= string-length@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1" - integrity sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw== + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: char-regex "^1.0.2" strip-ansi "^6.0.0" @@ -6251,7 +6311,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^3.0.0, string-width@^3.1.0: +string-width@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== @@ -6261,9 +6321,9 @@ string-width@^3.0.0, string-width@^3.1.0: strip-ansi "^5.1.0" string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" @@ -6297,7 +6357,7 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: +strip-ansi@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== @@ -6368,13 +6428,6 @@ supports-color@^5.3.0, supports-color@^5.5.0: dependencies: has-flag "^3.0.0" -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -6382,6 +6435,13 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-hyperlinks@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47" @@ -6396,12 +6456,17 @@ symbol-tree@^3.2.4: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^6.0.4: - version "6.0.7" - resolved "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34" - integrity sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g== + version "6.0.9" + resolved "https://registry.yarnpkg.com/table/-/table-6.0.9.tgz#790a12bf1e09b87b30e60419bafd6a1fd85536fb" + integrity sha512-F3cLs9a3hL1Z7N4+EkSscsel3z55XT950AvB05bwayrNg5T1/gykXtigioTAjbltvbMSJvvhFCbnf6mX+ntnJQ== dependencies: - ajv "^7.0.2" - lodash "^4.17.20" + ajv "^8.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + lodash.clonedeep "^4.5.0" + lodash.flatten "^4.4.0" + lodash.truncate "^4.4.2" slice-ansi "^4.0.0" string-width "^4.2.0" @@ -6522,14 +6587,14 @@ tough-cookie@^2.3.3, tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" - integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== dependencies: - ip-regex "^2.1.0" - psl "^1.1.28" + psl "^1.1.33" punycode "^2.1.1" + universalify "^0.1.2" tr46@^2.0.2: version "2.0.2" @@ -6544,11 +6609,10 @@ tree-kill@^1.2.2: integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== ts-jest@^26.1.1: - version "26.5.1" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.1.tgz#4d53ee4481552f57c1624f0bd3425c8b17996150" - integrity sha512-G7Rmo3OJMvlqE79amJX8VJKDiRcd7/r61wh9fnvvG8cAjhA9edklGw/dCxRSQmfZ/z8NDums5srSVgwZos1qfg== + version "26.5.4" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.4.tgz#207f4c114812a9c6d5746dd4d1cdf899eafc9686" + integrity sha512-I5Qsddo+VTm94SukBJ4cPimOoFZsYTeElR2xy6H2TOVs+NsvgYglW8KuQgKoApOKuaU/Ix/vrF9ebFZlb5D2Pg== dependencies: - "@types/jest" "26.x" bs-logger "0.x" buffer-from "1.x" fast-json-stable-stringify "2.x" @@ -6578,16 +6642,16 @@ tslib@^1.8.1, tslib@^1.9.0: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslog@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/tslog/-/tslog-3.1.1.tgz#e5b87cc1fa4d6d9c45c03f0b3643e80b9af30dcf" - integrity sha512-DRsPRK/O+D8aumIMPEK+92slz5NvsJY/0evZisCxv5TQOBuBTGI20p/LYNY0Opur+wYahoXkzqW+Ugvs7ynjcQ== + version "3.1.2" + resolved "https://registry.yarnpkg.com/tslog/-/tslog-3.1.2.tgz#fff4a821214a4bef64d5622e80389c94b8bea000" + integrity sha512-sKhNPUMjf+POPxcWuGxinjilEjIzPCdehF/zIdp33ttv9ohIBWHMV9gpdGvJjWbZn09a5IqP1dmaYq56IPXZAg== dependencies: source-map-support "^0.5.19" tsutils@^3.17.1: - version "3.20.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.20.0.tgz#ea03ea45462e146b53d70ce0893de453ff24f698" - integrity sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg== + 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" @@ -6622,10 +6686,15 @@ type-detect@4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" - integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== +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.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-fest@^0.6.0: version "0.6.0" @@ -6653,14 +6722,14 @@ typedarray-to-buffer@^3.1.5: is-typedarray "^1.0.0" typescript@^4.0.2: - version "4.1.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.5.tgz#123a3b214aaff3be32926f0d8f1f6e704eb89a72" - integrity sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA== + version "4.2.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" + integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== uglify-js@^3.5.1: - version "3.12.8" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.12.8.tgz#a82e6e53c9be14f7382de3d068ef1e26e7d4aaf8" - integrity sha512-fvBeuXOsvqjecUtF/l1dwsrrf5y2BCUk9AOJGzGcm6tE7vegku5u/YvqjyDaAGr422PLoLnrxg3EnRvTqsdC1w== + version "3.13.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.3.tgz#ce72a1ad154348ea2af61f50933c76cc8802276e" + integrity sha512-otIc7O9LyxpUcQoXzj2hL4LPWKklO6LJWoJUzNa8A17Xgi4fOeDC8FBDOLHnC/Slo1CQgsZMcM6as0M76BZaig== uid-safe@~2.1.5: version "2.1.5" @@ -6693,6 +6762,11 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -6783,14 +6857,14 @@ uuid@^8.0.0, uuid@^8.3.0: integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== v8-compile-cache@^2.0.3: - version "2.2.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" - integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== v8-to-istanbul@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz#5b95cef45c0f83217ec79f8fc7ee1c8b486aee07" - integrity sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g== + version "7.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.1.tgz#04bfd1026ba4577de5472df4f5e89af49de5edda" + integrity sha512-p0BB09E5FRjx0ELN6RgusIPsSPhtgexSRcKETybEs6IGOTXJSZqfwxp7r//55nnu0f1AxltY5VvdVqy2vZf9AA== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -6878,12 +6952,12 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^8.0.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.4.0.tgz#50fb9615b05469591d2b2bd6dfaed2942ed72837" - integrity sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw== +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" + integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== dependencies: - lodash.sortby "^4.7.0" + lodash "^4.7.0" tr46 "^2.0.2" webidl-conversions "^6.1.0" @@ -6930,15 +7004,6 @@ word-wrap@^1.2.3, word-wrap@~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== -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -6972,10 +7037,10 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -ws@^7.2.3: - version "7.4.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.3.tgz#1f9643de34a543b8edb124bdcbc457ae55a6e5cd" - integrity sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA== +ws@^7.2.3, ws@^7.4.4: + version "7.4.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" + integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== ws@~6.1.0: version "6.1.4" @@ -7030,17 +7095,9 @@ yallist@^4.0.0: integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yargs-parser@20.x, yargs-parser@^20.2.2: - version "20.2.5" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.5.tgz#5d37729146d3f894f39fc94b6796f5b239513186" - integrity sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg== - -yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" + version "20.2.7" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" + integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== yargs-parser@^18.1.2: version "18.1.3" @@ -7050,22 +7107,6 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs@^13.3.0: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - yargs@^15.4.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" @@ -7083,7 +7124,7 @@ yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^16.1.0: +yargs@^16.1.0, yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== From dbf9347ec66049aa7bb9ce5eea63dbb8713d43f0 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Tue, 30 Mar 2021 12:10:58 +0200 Subject: [PATCH 13/13] Version 0.23.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 228d134..9b728eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "swaf", - "version": "0.23.6", + "version": "0.23.7", "description": "Structure Web Application Framework.", "repository": "https://eternae.ink/ashpie/swaf", "author": "Alice Gaudon ",