From 38de2876e2e6095bf8aed0a535c44c2a650d4d4c Mon Sep 17 00:00:00 2001 From: Alexis Hushbeck Date: Sat, 5 Feb 2022 17:02:30 -0800 Subject: [PATCH 01/10] :palms_up_together: Base & Noop Command Classes This is the beginning of the new command style strcture. Commands will be added as self managing classes that know how to generate and send the actual command text as well as process parsed responses. The base class implements a common strategy of sending a tagged command and listening for a tagged response, capturing everything in between. The no-op is the most simple implementation of this command system. --- src/commands/base.ts | 154 +++++++++++++++++++++++++++++++++++++++++++ src/commands/noop.ts | 11 ++++ 2 files changed, 165 insertions(+) create mode 100644 src/commands/base.ts create mode 100644 src/commands/noop.ts diff --git a/src/commands/base.ts b/src/commands/base.ts new file mode 100644 index 00000000..50ebc568 --- /dev/null +++ b/src/commands/base.ts @@ -0,0 +1,154 @@ +import { EventEmitter } from "events"; + +import { IMAPError, NotImplementedError } from "../errors"; + +import type Connection from "../connection"; +import { ContinueResponse, TaggedResponse, UntaggedResponse } from "../parser"; + +// General commands +type GeneralCommandTypes = "CAPABILITY" | "ID" | "IDLE" | "NOOP"; + +// Login/Auth commands +type LoginOrAuthCommandTypes = "AUTHENTICATE" | "LOGIN" | "LOGOUT" | "STARTTLS"; + +// Mailbox commands +type MailboxCommandTypes = + | "APPEND" + | "CREATE" + | "DELETE" + | "EXAMINE" + | "LIST" + | "LSUB" + | "RENAME" + | "SELECT" + | "STATUS" + | "SUBSCRIBE" + | "UNSUBSCRIBE"; + +// Message commands +type MessageCommandTypes = + | "CHECK" + | "CLOSE" + | "COPY" + | "EXPUNGE" + | "FETCH" + | "SEARCH" + | "STORE" + | "UID"; + +export type CommandType = + | GeneralCommandTypes + | LoginOrAuthCommandTypes + | MailboxCommandTypes + | MessageCommandTypes; + +export type StandardResponseTypes = + | ContinueResponse + | TaggedResponse + | UntaggedResponse; + +let NEXT_COMMAND_ID = 1; + +export abstract class Command extends EventEmitter { + public readonly id: number; + + protected readonly commandPromise: Promise; + + constructor(public readonly type: CommandType) { + super(); + this.id = NEXT_COMMAND_ID++; + // Reset our ID count if we go over max safe integer + if (NEXT_COMMAND_ID === Number.MAX_SAFE_INTEGER) { + NEXT_COMMAND_ID = 1; + } + + this.commandPromise = new Promise(this.executor); + } + + protected executor( + resolve: (result: T) => void, + reject: (reason: any) => any, + ): void { + const cleanUpHandlers = () => { + this.off("results", successHandler); + this.off("error", errorHandler); + this.off("cancel", cancelHandler); + }; + const successHandler = (results) => { + try { + resolve(results); + } catch (err) { + reject(err); + } + cleanUpHandlers(); + }; + const errorHandler = (err: any) => { + reject(err); + cleanUpHandlers(); + }; + const cancelHandler = () => { + reject("Command canceled"); + cleanUpHandlers(); + }; + + this.once("results", successHandler); + this.once("error", errorHandler); + this.once("cancel", cancelHandler); + } + + protected getCommand(): string { + return this.type; + } + + public run(connection: Connection): Promise { + const cmdText = this.getFullAnnotatedCommand(); + let responses: StandardResponseTypes[] = []; + connection.send(cmdText); + + const responseHandler = (response: StandardResponseTypes) => { + responses.push(response); + if (response instanceof TaggedResponse) { + if (response.tag.id === this.id) { + if (response.status.status === "OK") { + this.emit("results", this.parseResponse(responses)); + } else { + this.emit("error", this.parseNonOKResponse(responses)); + } + connection.off("response", responseHandler); + } else { + // If that was data for another command, clear it + responses = []; + } + } + }; + + connection.on("response", responseHandler); + return this.commandPromise; + } + + protected parseNonOKResponse(responses: StandardResponseTypes[]): any { + const taggedResponse = responses[responses.length - 1]; + + if (taggedResponse && taggedResponse instanceof TaggedResponse) { + let msg = `Got non-OK status "${taggedResponse.status.status}" from command`; + if (taggedResponse.status.text) { + msg += `\r\n${taggedResponse.status.text.content}`; + } + return new IMAPError(msg); + } + } + + protected parseResponse(responses: StandardResponseTypes[]): T { + throw new NotImplementedError( + "Response parsing has not be implemented for this command", + ); + } + + public get results(): Promise { + return this.commandPromise; + } + + public getFullAnnotatedCommand() { + return `A${this.id.toString().padStart(5, "0")} ${this.getCommand()}`; + } +} diff --git a/src/commands/noop.ts b/src/commands/noop.ts new file mode 100644 index 00000000..1cb5bf86 --- /dev/null +++ b/src/commands/noop.ts @@ -0,0 +1,11 @@ +import { Command } from "./base"; + +export class NoopCommand extends Command { + constructor() { + super("NOOP"); + } + + protected parseResponse(): null { + return null; + } +} From 25c0d0e51a6650212c7b1878c4c75fb2066f2599 Mon Sep 17 00:00:00 2001 From: Alexis Hushbeck Date: Thu, 10 Feb 2022 12:59:44 -0800 Subject: [PATCH 02/10] :name_badge: Add ID & Capability Commands Adding command classes for the ID and Capability commands, which will be common to run on intiating the connection. Also included is the first command encoding function for creating IMAP safe strings. --- src/commands/capability.ts | 35 +++++++++++++++++++ src/commands/encoding.ts | 19 +++++++++++ src/commands/id.ts | 69 ++++++++++++++++++++++++++++++++++++++ src/commands/index.ts | 4 +++ 4 files changed, 127 insertions(+) create mode 100644 src/commands/capability.ts create mode 100644 src/commands/encoding.ts create mode 100644 src/commands/id.ts create mode 100644 src/commands/index.ts diff --git a/src/commands/capability.ts b/src/commands/capability.ts new file mode 100644 index 00000000..13789d57 --- /dev/null +++ b/src/commands/capability.ts @@ -0,0 +1,35 @@ +import { + CapabilityList, + CapabilityTextCode, + TaggedResponse, + UntaggedResponse, +} from "../parser"; +import { Command, StandardResponseTypes } from "./base"; + +export class CapabilityCommand extends Command { + constructor() { + super("CAPABILITY"); + } + + protected parseResponse( + responses: StandardResponseTypes[], + ): CapabilityList { + for (const resp of responses) { + if ( + resp instanceof UntaggedResponse && + resp.content instanceof CapabilityList + ) { + return resp.content; + } + + // It's also possible the server will just return it as a part + // of the tag response text, which is technically valid + if ( + resp instanceof TaggedResponse && + resp.status.text?.code instanceof CapabilityTextCode + ) { + return resp.status.text.code.capabilities; + } + } + } +} diff --git a/src/commands/encoding.ts b/src/commands/encoding.ts new file mode 100644 index 00000000..5546bd1d --- /dev/null +++ b/src/commands/encoding.ts @@ -0,0 +1,19 @@ +import { IMAPError } from "../errors"; + +export function createIMAPSafeString(value: string | null, allowNull = false) { + if (value === null) { + if (!allowNull) { + throw new IMAPError( + "Cannot create IMAP safe string from null value", + ); + } + return "NIL"; + } + + if (value.match(/\r|\n|[^\\]\\|"/)) { + // We have potentially unsafe characters, use a literal + return `${value.length}\r\n${value}`; + } + // Else just use DQUOTE + return `"${value}"`; +} diff --git a/src/commands/id.ts b/src/commands/id.ts new file mode 100644 index 00000000..e5c875ef --- /dev/null +++ b/src/commands/id.ts @@ -0,0 +1,69 @@ +import { IDResponse, UntaggedResponse } from "../parser"; +import { Command, StandardResponseTypes } from "./base"; +import { createIMAPSafeString } from "./encoding"; + +const pkg = require("../../package.json"); + +enum IdCommandKeys { + "address" = "address", + "arguments" = "arguments", + "command" = "command", + "environment" = "environment", + "date" = "date", + "name" = "name", + "os" = "os", + "os-version" = "os-version", + "support-url" = "support-url", + "vendor" = "vendor", + "version" = "version", +} +export type IdCommandValues = Partial< + { + [key in IdCommandKeys]: string | null; + } +>; + +export type IdResponseMap = Map; + +const DEFAULT_ID_OPTS: IdCommandValues = { + name: "node-imap", + "support-url": `${pkg.bugs ? pkg.bugs.url || pkg.bugs : pkg.homepage}`, + vendor: "lovely-inbox", + version: pkg.version, +}; + +export class IdCommand extends Command { + constructor( + protected readonly valuesToSend: IdCommandValues = DEFAULT_ID_OPTS, + ) { + super("ID"); + } + + protected getCommand(): string { + if (!this.valuesToSend || !Object.keys(this.valuesToSend).length) { + return this.type; + } + + const keyValPairs = []; + for (const [key, val] of Object.entries(this.valuesToSend)) { + if (key in IdCommandKeys) { + keyValPairs.push(createIMAPSafeString(key)); + keyValPairs.push(createIMAPSafeString(val, true)); + } + } + + return `${this.type} (${keyValPairs.join(" ")})`; + } + + protected parseResponse(responses: StandardResponseTypes[]): IdResponseMap { + for (const resp of responses) { + if ( + resp instanceof UntaggedResponse && + resp.content instanceof IDResponse + ) { + return resp.content.details; + } + } + return new Map(); + } +} diff --git a/src/commands/index.ts b/src/commands/index.ts new file mode 100644 index 00000000..7486caf4 --- /dev/null +++ b/src/commands/index.ts @@ -0,0 +1,4 @@ +export * from "./base"; +export * from "./capability"; +export * from "./id"; +export * from "./noop"; From 55708f3a5c18baa5a098f26da22822bf5bf443c1 Mon Sep 17 00:00:00 2001 From: Alexis Hushbeck Date: Thu, 10 Feb 2022 13:24:37 -0800 Subject: [PATCH 03/10] :runner: Create basic IMAPSession Class This class will eventually serve as the base class that is exposed and that other systems would interface with. This will contain the public- facing API for the library and will be both a mirror and an update of existing functionality. Note that this commit does not expose this class nor remove or change the original `Connection` class which currently acts as the public interface. Eventually the `Connection` class will be cleaned up and it will serve purely as the connection for the session without any logic for actual commands. --- src/connection/types.ts | 14 +++++++ src/imap.ts | 83 +++++++++++++++++++++++++++++++++++++++++ src/types.ts | 19 ++++++++++ 3 files changed, 116 insertions(+) create mode 100644 src/imap.ts create mode 100644 src/types.ts diff --git a/src/connection/types.ts b/src/connection/types.ts index d986c4a7..91afca01 100644 --- a/src/connection/types.ts +++ b/src/connection/types.ts @@ -4,6 +4,20 @@ import * as tls from "tls"; import type { FlagList } from "../parser"; +export enum TLSSetting { + "DEFAULT" = "on", + "STARTTLS" = "starttls", + "FORCE_OFF" = "off", +} + +export type IMAPConnectionConfiguration = { + host: string; + port?: number; + tls?: TLSSetting; + tlsOptions?: tls.ConnectionOptions; + timeout?: number; +}; + export interface IConfig { authTimeout?: number; autotls?: "never" | "always" | "required"; diff --git a/src/imap.ts b/src/imap.ts new file mode 100644 index 00000000..6489f8cf --- /dev/null +++ b/src/imap.ts @@ -0,0 +1,83 @@ +import {CapabilityCommand, IdCommand, IdResponseMap} from "./commands"; +import Connection from "./connection"; +import { IMAPError } from "./errors"; +import { type CapabilityList } from "./parser"; +import { IMAPLogMessage, type IMAPConfiguration } from "./types"; + +class IMAPSession { + protected authed: boolean; + protected capabilityList: CapabilityList; + protected connection: Connection; + protected logger: (info: IMAPLogMessage) => void; + protected options: IMAPConfiguration; + protected serverInfo: IdResponseMap; + protected started: boolean; + + constructor(options: IMAPConfiguration) { + this.connection = new Connection(options); + this.logger = options.logger || (() => {}); + this.options = options; + + this.authed = false; + this.started = false; + } + + public get active() { + return this.started; + } + + public get authenticated() { + return this.authed; + } + + public get capabilities() { + return this.capabilityList; + } + + public async start() { + if (this.started) { + return true; + } + this.started = true; + + try { + await this.connection.connect(); + + // Get server information and capabilities to start with since + // that information will really always be helpful. Surround in + // a try/catch because if the server doesn't support this, it + // is unlikely to have support for other things we need. + const capsCmd = new CapabilityCommand(); + this.capabilityList = await this.connection.runCommand(capsCmd); + + const idCmd = new IdCommand(this.options.id); + this.serverInfo = await this.connection.runCommand(idCmd); + } catch(error) { + // Try and destroy the connection + try{ + this.connection.destroy(); + } catch (_) {} + // Log the error + this.logger({ + level: "error", + message: "Unable to connect to the server", + error, + }); + // And set us back to not started + this.started = false; + return false; + } + + return true; + } + + public async end() { + if (!this.started) { + return; + } + this.started = false; + this.authed = false; + this.capabilityList = null; + this.connection.end(); + } +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 00000000..f35106bf --- /dev/null +++ b/src/types.ts @@ -0,0 +1,19 @@ +import { type IMAPConnectionConfiguration } from "./connection/types"; +import { type IdCommandValues } from "./commands"; + +export type IMAPLogMessage = + | { + level: "warn" | "info" | "verbose" | "debug" | "silly"; + message: string; + detail?: any; + } + | { + level: "error" | "warn"; + message: string; + error?: any; + }; + +export type IMAPConfiguration = IMAPConnectionConfiguration & { + id?: IdCommandValues; + logger?: (info: IMAPLogMessage) => void; +}; From 37407bec7be553da7556e6a76a62ee4fb2055dcf Mon Sep 17 00:00:00 2001 From: Alexis Hushbeck Date: Sun, 3 Jul 2022 10:25:31 -0700 Subject: [PATCH 04/10] =?UTF-8?q?=F0=9F=98=8C=20Rewrite=20Connection=20Cla?= =?UTF-8?q?ss?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pulled everything out of the connection class that is not actually related to the connection. This means almost all IMAP related commands and controls will be in a new class. The code went from almost 2k lines to around 300, which should be a lot easier to understand. From a practical perspective, I chose to write a brand new class and just remove the old copy completely. The old code was inter-weaved with a lot of implicit assumptions and untangling that would have been a nightmare. This does, however, mean this is all (or almost all) new code. Which is extra terrifying. But that's a future me problem. --- package.json | 1 + src/commands/base.ts | 5 +- src/commands/index.ts | 1 + src/commands/starttls.ts | 45 + src/connection/connection.ts | 2225 +++------------------------- src/connection/errors.ts | 12 + src/connection/index.ts | 2 +- src/connection/queue.ts | 188 +++ src/connection/types.ts | 86 +- src/newline.transform.ts | 10 +- src/parser/structure/capability.ts | 5 + yarn.lock | 5 + 12 files changed, 523 insertions(+), 2062 deletions(-) create mode 100644 src/commands/starttls.ts create mode 100644 src/connection/errors.ts create mode 100644 src/connection/queue.ts diff --git a/package.json b/package.json index c18abe07..4a2844ca 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "main": "./dist/index.js", "types": "./dist/index.d.ts", "dependencies": { + "tiny-typed-emitter": "2.1.0", "utf7": "git+https://github.com/LoveAndCoding/utf7.git" }, "scripts": { diff --git a/src/commands/base.ts b/src/commands/base.ts index 50ebc568..e52bf869 100644 --- a/src/commands/base.ts +++ b/src/commands/base.ts @@ -54,7 +54,10 @@ export abstract class Command extends EventEmitter { protected readonly commandPromise: Promise; - constructor(public readonly type: CommandType) { + constructor( + public readonly type: CommandType, + public readonly requiresOwnContext: boolean = false, + ) { super(); this.id = NEXT_COMMAND_ID++; // Reset our ID count if we go over max safe integer diff --git a/src/commands/index.ts b/src/commands/index.ts index 7486caf4..6bf78925 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -2,3 +2,4 @@ export * from "./base"; export * from "./capability"; export * from "./id"; export * from "./noop"; +export * from "./starttls"; diff --git a/src/commands/starttls.ts b/src/commands/starttls.ts new file mode 100644 index 00000000..10c6c1e2 --- /dev/null +++ b/src/commands/starttls.ts @@ -0,0 +1,45 @@ +import { TLSSocketError } from "../connection/errors"; +import { IMAPError } from "../errors"; +import { TaggedResponse } from "../parser"; +import { Command, StandardResponseTypes } from "./base"; + +export class StartTLSCommand extends Command { + constructor() { + super("STARTTLS", true); + } + + protected parseNonOKResponse( + responses: StandardResponseTypes[], + ): TLSSocketError { + const taggedResponse: TaggedResponse = responses.find( + (r) => r instanceof TaggedResponse, + ) as TaggedResponse; + + if (!taggedResponse) { + return new IMAPError(`Unknown error trying to run STARTTLS`); + } + + let msg: string; + switch (taggedResponse.status.status) { + case "NO": + msg = + "TLS negotiation can't be initiated, due to server configuration error"; + break; + case "BAD": + msg = + "STARTTLS received after a successful TLS negotiation or arguments invalid"; + break; + default: + msg = "Cannot initiate TLS connection"; + } + + if (taggedResponse.status.text) { + msg += `\r\n${taggedResponse.status.text.content}`; + } + return new TLSSocketError(msg); + } + + protected parseResponse(): boolean { + return true; + } +} diff --git a/src/connection/connection.ts b/src/connection/connection.ts index 59edfd12..f2d1d486 100644 --- a/src/connection/connection.ts +++ b/src/connection/connection.ts @@ -1,2097 +1,326 @@ -import { Buffer } from "buffer"; -import { EventEmitter } from "events"; import { Socket } from "net"; import { clearTimeout, setTimeout } from "timers"; import * as tls from "tls"; -import { imap as utf7 } from "utf7"; -import { inspect, types } from "util"; +import { TypedEmitter } from 'tiny-typed-emitter'; +import { CapabilityCommand, StartTLSCommand, type Command } from "../commands"; import { IMAPError } from "../errors"; import NewlineTranform from "../newline.transform"; import Lexer from "../lexer"; import Parser, { - AppendUIDTextCode, CapabilityList, + CapabilityTextCode, ContinueResponse, - CopyUIDTextCode, - ExistsCount, - Expunge, - ExtendedSearchResponse, - Fetch, - FlagList, - IDResponse, - MailboxListing, - MailboxStatus, - NamespaceResponse, - NumberTextCode, - PermentantFlagsTextCode, - QuotaResponse, - RecentCount, - SearchResponse, - SortResponse, StatusResponse, TaggedResponse, - ThreadResponse, UnknownResponse, UntaggedResponse, } from "../parser"; import { - MAX_INT, - KEEPALIVE_INTERVAL, - MAX_IDLE_WAIT, - MONTHS, - FETCH_ATTR_MAP, - SPECIAL_USE_ATTRIBUTES, CRLF, - RE_BODYPART, - RE_CMD, - RE_ESCAPE, - RE_IDLENOOPRES, - RE_INVALID_KW_CHARS, - RE_OPENBOX, - RE_UIDCMD_HASRESULTS, } from "./constants"; -import { buildSearchQuery } from "./search"; -import { IBox, ICommand, IConfig, INamespaces } from "./types"; -import { deepEqual, escape, validateUIDList } from "./utils"; +import CommandQueue from "./queue"; +import { IConnectionEvents, IMAPConnectionConfiguration, TLSSetting } from "./types"; +import { ConnectionTimeout, TLSSocketError } from "./errors"; -export default class Connection extends EventEmitter { - // END Extension methods ======================================================= +const DEFAULT_TIMEOUT = 10000; - // Namespace for seqno-based commands - get seq() { - return { - addKeywords: (seqnos, keywords, cb) => { - this.store("", seqnos, { mode: "+", keywords }, cb); - }, - delKeywords: (seqnos, keywords, cb) => { - this.store("", seqnos, { mode: "-", keywords }, cb); - }, - setKeywords: (seqnos, keywords, cb) => { - this.store("", seqnos, { mode: "", keywords }, cb); - }, +export default class Connection extends TypedEmitter { + public socket: undefined | Socket; - addFlags: (seqnos, flags, cb) => { - this.store("", seqnos, { mode: "+", flags }, cb); - }, - delFlags: (seqnos, flags, cb) => { - this.store("", seqnos, { mode: "-", flags }, cb); - }, - setFlags: (seqnos, flags, cb) => { - this.store("", seqnos, { mode: "", flags }, cb); - }, + protected lexer: Lexer; + protected parser: Parser; + protected processingPipeline: NewlineTranform; - copy: (seqnos, boxTo, cb) => { - this._copy("", seqnos, boxTo, cb); - }, - fetch: (seqnos, options) => { - return this._fetch("", seqnos, options); - }, - move: (seqnos, boxTo, cb) => { - this._move("", seqnos, boxTo, cb); - }, - search: (options, cb) => { - this._search("", options, cb); - }, + private options: IMAPConnectionConfiguration; + private commandQueue: CommandQueue; + private connected: boolean; + private secure?: boolean; - // Extensions ============================================================== - addLabels: (seqnos, labels, cb) => { - this.storeLabels("", seqnos, labels, "+", cb); - }, - delLabels: (seqnos, labels, cb) => { - this.storeLabels("", seqnos, labels, "-", cb); - }, - setLabels: (seqnos, labels, cb) => { - this.storeLabels("", seqnos, labels, "", cb); - }, - - esearch: (criteria, options, cb) => { - this._esearch("", criteria, options, cb); - }, + constructor(options: IMAPConnectionConfiguration) { + super(); + // Shallow copy options so we're not modifying the original object + this.options = Object.assign({}, options); - sort: (sorts, options, cb) => { - this._sort("", sorts, options, cb); - }, - thread: (algorithm, criteria, cb) => { - this._thread("", algorithm, criteria, cb); - }, + // Set TLS setting to default if it is unset or invalid + let {tls} = this.options; + if(!tls || !(tls === TLSSetting.DEFAULT || tls === TLSSetting.STARTTLS || tls === TLSSetting.STARTTLS_OPTIONAL || tls === TLSSetting.FORCE_OFF)) { + this.options.tls = tls = TLSSetting.DEFAULT; + } - addKeywordsSince: (seqnos, keywords, modseq, cb) => { - this.store("", seqnos, { mode: "+", keywords, modseq }, cb); - }, - delKeywordsSince: (seqnos, keywords, modseq, cb) => { - this.store("", seqnos, { mode: "-", keywords, modseq }, cb); - }, - setKeywordsSince: (seqnos, keywords, modseq, cb) => { - this.store("", seqnos, { mode: "", keywords, modseq }, cb); - }, + this.connected = false; - addFlagsSince: (seqnos, flags, modseq, cb) => { - this.store("", seqnos, { mode: "+", flags, modseq }, cb); - }, - delFlagsSince: (seqnos, flags, modseq, cb) => { - this.store("", seqnos, { mode: "-", flags, modseq }, cb); - }, - setFlagsSince: (seqnos, flags, modseq, cb) => { - this.store("", seqnos, { mode: "", flags, modseq }, cb); - }, - }; + this.init(); } - private static getDefaultBox(): IBox { - return { - flags: new FlagList([]), - keywords: [], - messages: { - new: 0, - total: 0, - }, - name: "", - newKeywords: false, - nomodseq: false, - permFlags: new FlagList([]), - persistentUIDs: true, - readOnly: false, - uidnext: 0, - uidvalidity: 0, - }; + get isActive(): boolean { + return this.connected; } - public delimiter: void | string; - public namespaces: void | NamespaceResponse; - public state: "disconnected" | "connected" | "authenticated"; - public lexer: Lexer; - public parser: Parser; - - private debug: (msg: string) => void; - private box: undefined | IBox; - private caps: undefined | CapabilityList; - private config: IConfig; - private curReq: undefined | ICommand; - private idle: { started: undefined | number; enabled: boolean }; - private queue: ICommand[]; - private newlineTransform: NewlineTranform; - private sock: undefined | Socket; - private tagcount: number; - private tmrAuth: undefined | NodeJS.Timeout; - private tmrConn: undefined | NodeJS.Timeout; - private tmrKeepalive: undefined | NodeJS.Timeout; - - private onError: (err: Error) => void; - private onSocketTimeout: () => void; - - constructor(config: Partial) { - super(); - config = config || {}; - - this.config = { - authTimeout: config.authTimeout || 5000, - autotls: config.autotls, - connTimeout: config.connTimeout || 10000, - host: config.host || "localhost", - keepalive: - config.keepalive === undefined || config.keepalive === null - ? true - : config.keepalive, - localAddress: config.localAddress, - password: config.password, - port: config.port || 143, - socket: config.socket, - socketTimeout: config.socketTimeout || 0, - tls: config.tls, - tlsOptions: config.tlsOptions, - user: config.user, - xoauth: config.xoauth, - xoauth2: config.xoauth2, - }; - - this.sock = config.socket || undefined; - this.tagcount = 0; - this.tmrConn = undefined; - this.tmrKeepalive = undefined; - this.tmrAuth = undefined; - this.queue = []; - this.box = undefined; - this.idle = { started: undefined, enabled: false }; - this.parser = undefined; - this.curReq = undefined; - this.delimiter = undefined; - this.namespaces = undefined; - this.state = "disconnected"; - // Fallback to no-op - // tslint:disable-next-line:no-empty - this.debug = config.debug || (() => {}); + get isSecure(): boolean { + return this.connected && this.secure; } - public connect() { - const config = this.config; + public async connect(): Promise { + if(this.connected) { + throw new IMAPError('Must end previous IMAP connection before starting a new one') + } else if (this.socket) { + throw new IMAPError('Existing IMAP connection or connection attempt must be fully closed before a new one can be made') + } + + const config = this.options; let socket: Socket; let tlsOptions: tls.ConnectionOptions; - socket = config.socket || new Socket(); + socket = new Socket(); socket.setKeepAlive(true); - this.sock = undefined; - this.tagcount = 0; - this.tmrConn = undefined; - this.tmrKeepalive = undefined; - this.tmrAuth = undefined; - this.queue = []; - this.box = undefined; - this.idle = { started: undefined, enabled: false }; - this.parser = undefined; - this.curReq = undefined; - this.delimiter = undefined; - this.namespaces = undefined; - this.state = "disconnected"; - - if (config.tls) { - tlsOptions = {}; - tlsOptions.host = config.host; - // Host name may be overridden the tlsOptions + this.socket = undefined; + + if (config.tls === TLSSetting.DEFAULT) { + tlsOptions = { + // Host name may be overridden by the tlsOptions + host: config.host, + // Explicitly reject unauthorized connections by default + rejectUnauthorized: true, + }; Object.assign(tlsOptions, config.tlsOptions); + // Socket cannot be overridden tlsOptions.socket = socket; } - const onconnect = () => { - if (typeof this.tmrConn !== "undefined") { - clearTimeout(this.tmrConn); - } - this.state = "connected"; - this.debug("[connection] Connected to host"); - this.tmrAuth = setTimeout(function () { - const err = new IMAPError( - "Timed out while authenticating with server", - ); - err.source = "timeout-auth"; - this.emit("error", err); - socket.destroy(); - }, config.authTimeout); - }; - - if (config.tls) { - this.sock = tls.connect(tlsOptions, onconnect); - } else { - socket.once("connect", onconnect); - this.sock = socket; - } - - this.onError = (err) => { - const wrpd = new IMAPError(err); - - if (typeof this.tmrConn !== "undefined") { - clearTimeout(this.tmrConn); - } - if (typeof this.tmrAuth !== "undefined") { - clearTimeout(this.tmrAuth); - } - this.debug("[connection] Error: " + wrpd); - wrpd.source = "socket"; - this.emit("error", wrpd); - }; - this.sock.on("error", this.onError); - - this.onSocketTimeout = () => { - if (typeof this.tmrConn !== "undefined") { - clearTimeout(this.tmrConn); - } - if (typeof this.tmrAuth !== "undefined") { - clearTimeout(this.tmrAuth); - } - if (typeof this.tmrKeepalive !== "undefined") { - clearTimeout(this.tmrKeepalive); - } - this.state = "disconnected"; - this.debug("[connection] Socket timeout"); - - const err = new IMAPError( - "Socket timed out while talking to server", - ); - err.source = "socket-timeout"; - this.emit("error", err); - socket.destroy(); - }; - this.sock.on("timeout", this.onSocketTimeout); - socket.setTimeout(config.socketTimeout); - - socket.once("close", (hadErr) => { - if (typeof this.tmrConn !== "undefined") { - clearTimeout(this.tmrConn); - } - if (typeof this.tmrAuth !== "undefined") { - clearTimeout(this.tmrAuth); - } - if (typeof this.tmrKeepalive !== "undefined") { - clearTimeout(this.tmrKeepalive); - } - this.state = "disconnected"; - this.debug("[connection] Closed"); - this.emit("close", hadErr); - }); - - socket.once("end", () => { - if (typeof this.tmrConn !== "undefined") { - clearTimeout(this.tmrConn); - } - if (typeof this.tmrAuth !== "undefined") { - clearTimeout(this.tmrAuth); - } - if (typeof this.tmrKeepalive !== "undefined") { - clearTimeout(this.tmrKeepalive); - } - this.state = "disconnected"; - this.debug("[connection] Ended"); - this.emit("end"); - }); - - const newlineTransform = new NewlineTranform(); - this.newlineTransform = newlineTransform; - const lexer = new Lexer(); - this.lexer = lexer; - const parser = new Parser(); - this.parser = parser; - - socket.pipe(newlineTransform).pipe(lexer).pipe(parser); - - parser.on("untagged", (resp: UntaggedResponse) => { - this.resUntagged(resp); - }); - parser.on("tagged", (resp: TaggedResponse) => { - this.resTagged(resp); - }); - parser.on("continue", (resp: ContinueResponse) => { - if (!this.curReq) { - throw new IMAPError( - "Unable to find current request during parsing", - ); - } else if (!this.sock) { - throw new IMAPError( - "No socket available when parsing continue", - ); - } - - const type = this.curReq.type; - if (type === "IDLE") { - if ( - this.queue.length && - this.idle.started === 0 && - this.curReq && - this.curReq.type === "IDLE" && - this.sock && - this.sock.writable && - !this.idle.enabled - ) { - this.debug("=> DONE"); - this.sock.write("DONE" + CRLF); - return; - } - // now idling - this.idle.started = Date.now(); - } else if (/^AUTHENTICATE XOAUTH/.test(this.curReq.fullcmd)) { - this.curReq.oauthError = Buffer.from( - resp.text.content, - "base64", - ).toString("utf8"); - this.debug("=> " + inspect(CRLF)); - this.sock.write(CRLF); - } else if (type === "APPEND") { - this.sockWriteAppendData(this.curReq.appendData); - } else if (this.curReq.lines && this.curReq.lines.length) { - const line = this.curReq.lines.shift() + "\r\n"; - this.debug("=> " + inspect(line)); - this.sock.write(line, "binary"); - } - }); - parser.on("unknown", (resp: UnknownResponse) => { - const m = RE_IDLENOOPRES.exec(resp.text); - if (m) { - // no longer idling - this.idle.enabled = false; - this.idle.started = undefined; - if (typeof this.tmrKeepalive !== "undefined") { - clearTimeout(this.tmrKeepalive); - } - - this.curReq = undefined; - - if ( - this.queue.length === 0 && - this.config.keepalive && - this.state === "authenticated" && - !this.idle.enabled - ) { - this.idle.enabled = true; - if (m[1] === "NOOP") { - this.doKeepaliveTimer(); - } else { - this.doKeepaliveTimer(true); - } - } - - this.processQueue(); - } - }); - - this.tmrConn = setTimeout(() => { - const err = new IMAPError("Timed out while connecting to server"); - err.source = "timeout"; - this.emit("error", err); - socket.destroy(); - }, config.connTimeout); - - socket.connect({ - host: config.host, - localAddress: config.localAddress, - port: config.port, - }); - } - - public serverSupports(cap: string): boolean { - return this.caps.has(cap); - } - - public destroy() { - this.queue = []; - this.curReq = undefined; - if (this.sock) { - this.sock.unpipe(this.newlineTransform); - this.sock.end(); - } - } - - public end() { - this.enqueue("LOGOUT", () => { - this.queue = []; - this.curReq = undefined; - this.sock?.end(); - }); - } - - public append(data: string | Buffer, cb: Function); - public append( - data: string | Buffer, - options: Record, - cb: Function, - ); - public append( - data: string | Buffer, - optionsOrCb: Record | Function, - cb?: Function, - ) { - const literal = this.serverSupports("LITERAL+"); - let options: Record; - if (typeof optionsOrCb === "function") { - cb = optionsOrCb; - options = {}; - } else { - options = optionsOrCb; - } - if (!options.mailbox) { - if (!this.box) { - throw new IMAPError( - "No mailbox specified or currently selected", - ); - } else { - options.mailbox = this.box.name; - } - } - let cmd = 'APPEND "' + escape(utf7.encode("" + options.mailbox)) + '"'; - if (options.flags) { - if (!Array.isArray(options.flags)) { - options.flags = [options.flags]; - } - if (options.flags.length > 0) { - for (let i = 0, len = options.flags.length; i < len; ++i) { - if ( - options.flags[i][0] !== "$" && - options.flags[i][0] !== "\\" - ) { - options.flags[i] = "\\" + options.flags[i]; + let connected = await new Promise((resolve, reject) => { + // Setup a simple timeout + const timeoutWait = config.timeout || DEFAULT_TIMEOUT + let timeout = setTimeout(() => { + // Check to make sure we didn't already close the connection + if(socket.destroyed) { return; } + + timeout = undefined; + const tmrErr = new ConnectionTimeout(timeoutWait, 'Socket') + socket.destroy(tmrErr); + reject(tmrErr); + }, timeoutWait); + const clearTimer = (connected) => { + return () => { + if(timeout) { + clearTimeout(timeout); + timeout = undefined; + resolve(connected); } + this.socket.off('close', clearTimerBad); } - cmd += " (" + options.flags.join(" ") + ")"; - } - } - if (options.date) { - if (!types.isDate(options.date)) { - throw new IMAPError("`date` is not a Date object"); - } - cmd += ' "'; - cmd += options.date.getDate(); - cmd += "-"; - cmd += MONTHS[options.date.getMonth()]; - cmd += "-"; - cmd += options.date.getFullYear(); - cmd += " "; - cmd += ("0" + options.date.getHours()).slice(-2); - cmd += ":"; - cmd += ("0" + options.date.getMinutes()).slice(-2); - cmd += ":"; - cmd += ("0" + options.date.getSeconds()).slice(-2); - cmd += options.date.getTimezoneOffset() > 0 ? " -" : " +"; - cmd += ("0" + -options.date.getTimezoneOffset() / 60).slice(-2); - cmd += ("0" + (-options.date.getTimezoneOffset() % 60)).slice(-2); - cmd += '"'; - } - cmd += " {"; - cmd += Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data); - cmd += (literal ? "+" : "") + "}"; - - this.enqueue(cmd, cb); - - if (literal) { - this.queue[this.queue.length - 1].literalAppendData = data; - } else { - this.queue[this.queue.length - 1].appendData = data; - } - } - - public getSpecialUseBoxes(cb: Function) { - this.enqueue('XLIST "" "*"', cb); - } - - public getBoxes(cb: Function); - public getBoxes(namespace: string, cb: Function); - public getBoxes(namespace: string | Function, cb?: Function) { - if (typeof namespace === "function") { - cb = namespace; - namespace = ""; - } - - namespace = escape(utf7.encode("" + namespace)); - - this.enqueue('LIST "' + namespace + '" "*"', cb); - } - - public id(identification: null | Record, cb: Function) { - if (!this.serverSupports("ID")) { - throw new IMAPError("Server does not support ID"); - } - let cmd = "ID"; - if ( - identification === null || - Object.keys(identification).length === 0 - ) { - cmd += " NIL"; - } else { - if (Object.keys(identification).length > 30) { - throw new IMAPError("Max allowed number of keys is 30"); } - const kv = []; - Object.keys(identification).forEach((k) => { - if (Buffer.byteLength(k) > 30) { - throw new IMAPError("Max allowed key length is 30"); - } - if (Buffer.byteLength(identification[k]) > 1024) { - throw new IMAPError("Max allowed value length is 1024"); - } - kv.push('"' + escape(k) + '"'); - kv.push('"' + escape(identification[k]) + '"'); - }); - cmd += " (" + kv.join(" ") + ")"; - } - this.enqueue(cmd, cb); - } - - public openBox( - name: string, - cb: (err: undefined | Error, box?: IBox) => void, - ); - public openBox( - name: string, - readonly: boolean, - cb: (err: undefined | Error, box?: IBox) => void, - ); - public openBox( - name: string, - readOnly: boolean | ((err: undefined | Error, box: IBox) => void), - cb?: (err: undefined | Error, box?: IBox) => void, - ) { - if (this.state !== "authenticated") { - throw new IMAPError("Not authenticated"); - } - - if (typeof readOnly === "function") { - cb = readOnly; - readOnly = false; - } - - name = "" + name; - const encname = escape(utf7.encode(name)); - let cmd = readOnly ? "EXAMINE" : "SELECT"; - - cmd += ' "' + encname + '"'; - - if (this.serverSupports("CONDSTORE")) { - cmd += " (CONDSTORE)"; - } - - this.enqueue(cmd, (err) => { - if (err) { - this.box = undefined; - cb(err); - } else if (!this.box) { - cb(new IMAPError("Did not successfully open box")); + const clearTimerGood = clearTimer(true); + const clearTimerBad = clearTimer(false); + if (tlsOptions) { + // Use a local reference here in case this.socket changes + const tlsSock = tls.connect(tlsOptions, clearTimerGood); + this.socket = tlsSock; + this.secure = true; } else { - this.box.name = name; - cb(err, this.box); - } + socket.connect({ + host: config.host, + port: config.port, + }, clearTimerGood); + this.socket = socket; + this.secure = false; + } + this.socket.once('close', clearTimerBad); }); - } - public closeBox(cb: (err?: Error) => void); - public closeBox(shouldExpunge: boolean, cb: (err?: Error) => void); - public closeBox( - shouldExpunge: boolean | ((err?: Error) => void), - cb?: (err?: Error) => void, - ) { - if (this.box === undefined) { - throw new IMAPError("No mailbox is currently selected"); + if(!connected) { + return false; } - if (typeof shouldExpunge === "function") { - cb = shouldExpunge; - shouldExpunge = true; - } - - if (shouldExpunge) { - this.enqueue("CLOSE", (err) => { - if (!err) { - this.box = undefined; - } - - cb(err); - }); - } else { - if (this.serverSupports("UNSELECT")) { - // use UNSELECT if available, as it claims to be "cleaner" than the - // alternative "hack" - this.enqueue("UNSELECT", (err) => { - if (!err) { - this.box = undefined; - } + this.socket.pipe(this.processingPipeline); - cb(err); - }); - } else { - // "HACK": close the box without expunging by attempting to SELECT a - // non-existent mailbox - const badbox = "NODEJSIMAPCLOSINGBOX" + Date.now(); - this.enqueue('SELECT "' + badbox + '"', (err) => { - this.box = undefined; - cb(); - }); + if(!this.isSecure && (config.tls === TLSSetting.STARTTLS || config.tls === TLSSetting.STARTTLS_OPTIONAL)) { + connected = await this.starttls(); + if(!this.isSecure && config.tls === TLSSetting.STARTTLS) { + this.socket.destroy(); + this.socket = undefined; + throw new TLSSocketError('Could not establish a secure connection'); } } - } - - public addBox(name: string, cb: Function) { - this.enqueue('CREATE "' + escape(utf7.encode("" + name)) + '"', cb); - } - - public delBox(name: string, cb: Function) { - this.enqueue('DELETE "' + escape(utf7.encode("" + name)) + '"', cb); - } - - public renameBox( - oldname: string, - newname: string, - cb: (err?: Error, box?: IBox) => void, - ) { - const encoldname = escape(utf7.encode("" + oldname)); - const encnewname = escape(utf7.encode("" + newname)); - - this.enqueue( - 'RENAME "' + encoldname + '" "' + encnewname + '"', - (err) => { - if (err) { - return cb(err); - } - - if ( - this.box && - this.box.name === oldname && - oldname.toUpperCase() !== "INBOX" - ) { - this.box.name = newname; - cb(err, this.box); - } else { - cb(); - } - }, - ); - } - - public subscribeBox(name: string, cb: Function) { - this.enqueue('SUBSCRIBE "' + escape(utf7.encode("" + name)) + '"', cb); - } - - public unsubscribeBox(name: string, cb: Function) { - this.enqueue( - 'UNSUBSCRIBE "' + escape(utf7.encode("" + name)) + '"', - cb, - ); - } - - public getSubscribedBoxes(cb: Function); - public getSubscribedBoxes(namespace: string, cb: Function); - public getSubscribedBoxes(namespace: string | Function, cb?: Function) { - if (typeof namespace === "function") { - cb = namespace; - namespace = ""; - } - - namespace = escape(utf7.encode("" + namespace)); - - this.enqueue('LSUB "' + namespace + '" "*"', cb); - } - - public status(boxName: string, cb: Function) { - if (this.box && this.box.name === boxName) { - throw new IMAPError( - "Cannot call status on currently selected mailbox", - ); - } - - boxName = escape(utf7.encode("" + boxName)); - - let info = ["MESSAGES", "RECENT", "UNSEEN", "UIDVALIDITY", "UIDNEXT"]; - - if (this.serverSupports("CONDSTORE")) { - info.push("HIGHESTMODSEQ"); - } - - const attrs = info.join(" "); - - this.enqueue('STATUS "' + boxName + '" (' + attrs + ")", cb); - } - - public expunge(cb: Function); - public expunge(uids: string | number | (string | number)[], cb: Function); - public expunge( - uidsOrCb: string | number | (string | number)[] | Function, - cb?: Function, - ) { - let uids: (string | number)[]; - if (typeof uidsOrCb === "function") { - cb = uidsOrCb; - uids = undefined; - } else if (!Array.isArray(uidsOrCb)) { - uids = [uidsOrCb]; - } else { - uids = uidsOrCb; - } - - if (uids !== undefined) { - validateUIDList(uids); - - if (uids.length === 0) { - throw new IMAPError("Empty uid list"); - } - - const uidsList = uids.join(","); - if (!this.serverSupports("UIDPLUS")) { - throw new IMAPError( - "Server does not support this feature (UIDPLUS)", - ); - } - - this.enqueue("UID EXPUNGE " + uidsList, cb); - } else { - this.enqueue("EXPUNGE", cb); + this.connected = connected; + if(!connected) { + this.socket.destroy(); + this.socket = undefined; + return false; } - } - public search(criteria: string | string[], cb: Function) { - this._search("UID ", criteria, cb); - } + this.socket.on('error', this.onSocketError); + this.socket.once('end', this.onSocketEnd); + this.socket.once('close', this.onSocketClose); - public addFlags( - uids: string | string[], - flags: string | string[], - cb: Function, - ) { - this.store("UID ", uids, { mode: "+", flags }, cb); + // Manually call because the ready event will likely have passed + this.onSocketReady(); + this.emit('ready', this.isSecure); + return this.connected; } - public delFlags( - uids: string | string[], - flags: string | string[], - cb: Function, - ) { - this.store("UID ", uids, { mode: "-", flags }, cb); + // Socket event handlers + protected onSocketReady = () => { + this.connected = true; + this.commandQueue.start(); } - - public setFlags( - uids: string | string[], - flags: string | string[], - cb: Function, - ) { - this.store("UID ", uids, { mode: "", flags }, cb); + protected onSocketError = (err) => { + this.emit('connectionError', new IMAPError(err)); } - - public addKeywords( - uids: string | string[], - keywords: string | string[], - cb: Function, - ) { - this.store("UID ", uids, { mode: "+", keywords }, cb); + protected onSocketClose = (hadErr: boolean) => { + this.commandQueue.stop(); + this.connected = false; + this.socket.unpipe(this.processingPipeline) + this.processingPipeline.forceNewLine(false); + this.socket.removeAllListeners(); + this.socket = undefined; + this.secure = undefined; + this.emit('disconnected', !hadErr) } - - public delKeywords( - uids: string | string[], - keywords: string | string[], - cb: Function, - ) { - this.store("UID ", uids, { mode: "-", keywords }, cb); - } - - public setKeywords( - uids: string | string[], - keywords: string | string[], - cb: Function, - ) { - this.store("UID ", uids, { mode: "", keywords }, cb); - } - - public copy(uids: string | string[], boxTo: string, cb: Function) { - this._copy("UID ", uids, boxTo, cb); - } - - public move(uids: string | string[], boxTo: string, cb: Function) { - this._move("UID ", uids, boxTo, cb); + protected onSocketEnd = () => { + this.commandQueue.stop(); + this.connected = false; + this.socket.end(); } - public fetch(uids: string | string[], options) { - return this._fetch("UID ", uids, options); - } + public async disconnect(error?: Error) { + if(!this.socket) { + return; + } - // Extension methods =========================================================== - public setLabels( - uids: string | string[], - labels: string | string[], - cb: Function, - ) { - this.storeLabels("UID ", uids, labels, "", cb); + // Socket closing event handles cleanup + this.socket.destroy(error); } - public addLabels(uids, labels, cb: Function) { - this.storeLabels("UID ", uids, labels, "+", cb); + public async runCommand, T>(command: K): Promise { + this.commandQueue.add(command); + return command.results; } - - public delLabels(uids, labels, cb: Function) { - this.storeLabels("UID ", uids, labels, "-", cb); + + public send(toSend: string) { + this.socket.write(toSend + CRLF, "utf8"); } - public sort(sorts, criteria: string[], cb: Function) { - this._sort("UID ", sorts, criteria, cb); - } + protected init() { + this.commandQueue = new CommandQueue(this, false); - public esearch(criteria: string[], options, cb: Function) { - this._esearch("UID ", criteria, options, cb); - } + // Setup our Lexing/Parsing + this.processingPipeline = new NewlineTranform({ allowHalfOpen: true, }); + this.lexer = new Lexer(); + this.parser = new Parser(); - public setQuota(quotaRoot: string, limits, cb: Function) { - if (typeof limits === "function") { - cb = limits; - limits = {}; - } - - let triplets = ""; - Object.keys(limits).forEach((l) => { - if (triplets) { - triplets += " "; + // Pipe from our newline splitter to lexer to parser + this.processingPipeline.pipe(this.lexer).pipe(this.parser); + // Once we hit the parser, we want to (mostly) bubble events + this.parser.on("untagged", (resp: UntaggedResponse) => { + if(resp.content instanceof StatusResponse) { + this.emit('serverStatus', resp); + } else { + this.emit("untaggedResponse", resp); + this.emit("response", resp); } - triplets += l + " " + limits[l]; }); - - quotaRoot = escape(utf7.encode("" + quotaRoot)); - - this.enqueue( - 'SETQUOTA "' + quotaRoot + '" (' + triplets + ")", - (err, quotalist) => { - if (err) { - return cb(err); - } - - cb(err, quotalist ? quotalist[0] : limits); - }, - ); - } - - public getQuota(quotaRoot: string, cb: Function) { - quotaRoot = escape(utf7.encode("" + quotaRoot)); - - this.enqueue('GETQUOTA "' + quotaRoot + '"', (err, quotalist) => { - if (err) { - return cb(err); - } - - cb(err, quotalist[0]); + this.parser.on("tagged", (resp: TaggedResponse) => { + this.emit("taggedResponse", resp); + this.emit("response", resp); }); - } - - public getQuotaRoot(boxName: string, cb: Function) { - boxName = escape(utf7.encode("" + boxName)); - - this.enqueue('GETQUOTAROOT "' + boxName + '"', (err, quotalist) => { - if (err) { - return cb(err); - } - - const quotas = {}; - if (quotalist) { - for (let i = 0, len = quotalist.length; i < len; ++i) { - quotas[quotalist[i].root] = quotalist[i].resources; - } - } - - cb(err, quotas); + this.parser.on("continue", (resp: ContinueResponse) => { + this.emit("continueResponse", resp); + this.emit("response", resp); }); - } - - public thread(algorithm: string, criteria: string[], cb: Function) { - this._thread("UID ", algorithm, criteria, cb); - } - - public addFlagsSince( - uids: string | string[], - flags: string | string[], - modseq: number, - cb: Function, - ) { - this.store("UID ", uids, { mode: "+", flags, modseq }, cb); - } - - public delFlagsSince( - uids: string | string[], - flags: string | string[], - modseq: number, - cb: Function, - ) { - this.store("UID ", uids, { mode: "-", flags, modseq }, cb); - } - - public setFlagsSince( - uids: string | string[], - flags: string | string[], - modseq: number, - cb: Function, - ) { - this.store("UID ", uids, { mode: "", flags, modseq }, cb); - } - - public addKeywordsSince( - uids: string | string[], - keywords: string | string[], - modseq: number, - cb: Function, - ) { - this.store("UID ", uids, { mode: "+", keywords, modseq }, cb); - } - - public delKeywordsSince( - uids: string | string[], - keywords: string | string[], - modseq: number, - cb: Function, - ) { - this.store("UID ", uids, { mode: "-", keywords, modseq }, cb); - } - - public setKeywordsSince( - uids: string | string[], - keywords: string | string[], - modseq: number, - cb: Function, - ) { - this.store("UID ", uids, { mode: "", keywords, modseq }, cb); - } - - private _search(which, criteria, cb: Function) { - if (this.box === undefined) { - throw new IMAPError("No mailbox is currently selected"); - } else if (!Array.isArray(criteria)) { - throw new IMAPError("Expected array for search criteria"); - } - - let cmd = which + "SEARCH"; - const info = { hasUTF8: false /*output*/ }; - let query = buildSearchQuery(criteria, this.caps, info); - let lines; - if (info.hasUTF8) { - cmd += " CHARSET UTF-8"; - lines = query.split(CRLF); - query = lines.shift(); - } - cmd += query; - this.enqueue(cmd, cb); - if (info.hasUTF8) { - const req = this.queue[this.queue.length - 1]; - req.lines = lines; - } - } - - private store( - which: string, - uids: string[] | string, - cfg: - | { mode: string; flags: string | string[]; modseq?: number } - | { mode: string; keywords: string | string[]; modseq?: number }, - cb: Function, - ) { - const mode = cfg.mode; - const isFlags = "flags" in cfg; - let items = "flags" in cfg ? cfg.flags : cfg.keywords; - if (this.box === undefined) { - throw new IMAPError("No mailbox is currently selected"); - } else if (uids === undefined) { - throw new IMAPError("No messages specified"); - } - - if (!Array.isArray(uids)) { - uids = [uids]; - } - validateUIDList(uids); - - if (uids.length === 0) { - throw new IMAPError( - "Empty " + (which === "" ? "sequence number" : "uid") + "list", - ); - } - - if ( - (!Array.isArray(items) && typeof items !== "string") || - (Array.isArray(items) && items.length === 0) - ) { - throw new IMAPError( - (isFlags ? "Flags" : "Keywords") + - " argument must be a string or a non-empty Array", - ); - } - if (!Array.isArray(items)) { - items = [items]; - } - for (let i = 0, len = items.length; i < len; ++i) { - if (isFlags) { - if (items[i][0] !== "\\") { - items[i] = "\\" + items[i]; - } - } else { - // keyword contains any char except control characters (%x00-1F and %x7F) - // and: '(', ')', '{', ' ', '%', '*', '\', '"', ']' - if (RE_INVALID_KW_CHARS.test(items[i])) { - throw new IMAPError( - 'The keyword "' + - items[i] + - '" contains invalid characters', - ); - } - } - } - - items = items.join(" "); - uids = uids.join(","); - - let modifiers = ""; - if (cfg.modseq !== undefined && !this.box?.nomodseq) { - modifiers += "UNCHANGEDSINCE " + cfg.modseq + " "; - } - - this.enqueue( - which + - "STORE " + - uids + - " " + - modifiers + - mode + - "FLAGS.SILENT (" + - items + - ")", - cb, - ); - } - - private _copy(which, uids, boxTo, cb: Function) { - if (this.box === undefined) { - throw new IMAPError("No mailbox is currently selected"); - } - - if (!Array.isArray(uids)) { - uids = [uids]; - } - validateUIDList(uids); - - if (uids.length === 0) { - throw new IMAPError( - "Empty " + (which === "" ? "sequence number" : "uid") + "list", - ); - } - - boxTo = escape(utf7.encode("" + boxTo)); - - this.enqueue(which + "COPY " + uids.join(",") + ' "' + boxTo + '"', cb); - } - - private _move(which, uids, boxTo, cb: Function) { - if (this.box === undefined) { - throw new IMAPError("No mailbox is currently selected"); - } - - if (this.serverSupports("MOVE")) { - if (!Array.isArray(uids)) { - uids = [uids]; - } - validateUIDList(uids); - - if (uids.length === 0) { - throw new IMAPError( - "Empty " + - (which === "" ? "sequence number" : "uid") + - "list", - ); - } - - uids = uids.join(","); - boxTo = escape(utf7.encode("" + boxTo)); - - this.enqueue(which + "MOVE " + uids + ' "' + boxTo + '"', cb); - } else if ( - !this.box.permFlags.has("\\Deleted") && - !this.box.flags.has("\\Deleted") - ) { - throw new IMAPError( - "Cannot move message: " + - "server does not allow deletion of messages", - ); - } else { - let deletedUIDs; - let task = 0; - const ccb = (err, info) => { - if (err) { - return cb(err, info); - } - - if (task === 0 && which && this.serverSupports("UIDPLUS")) { - // UIDPLUS gives us a 'UID EXPUNGE n' command to expunge a subset of - // messages with the \Deleted flag set. This allows us to skip some - // actions. - task = 2; - } - // Make sure we don't expunge any messages marked as Deleted except the - // one we are moving - if (task === 0) { - this.search(["DELETED"], (e, result) => { - ++task; - deletedUIDs = result; - ccb(e, info); - }); - } else if (task === 1) { - if (deletedUIDs.length) { - this.delFlags(deletedUIDs, "\\Deleted", (e) => { - ++task; - ccb(e, info); - }); - } else { - ++task; - ccb(err, info); - } - } else if (task === 2) { - const cbMarkDel = (e) => { - ++task; - ccb(e, info); - }; - if (which) { - this.addFlags(uids, "\\Deleted", cbMarkDel); - } else { - this.seq.addFlags(uids, "\\Deleted", cbMarkDel); - } - } else if (task === 3) { - if (which && this.serverSupports("UIDPLUS")) { - this.expunge(uids, (e) => { - cb(e, info); - }); - } else { - this.expunge((e) => { - ++task; - ccb(e, info); - }); - } - } else if (task === 4) { - if (deletedUIDs.length) { - this.addFlags(deletedUIDs, "\\Deleted", (e) => { - cb(e, info); - }); - } else { - cb(err, info); - } - } - }; - this._copy(which, uids, boxTo, ccb); - } - } - - private _fetch(which, uids, options) { - if ( - uids === undefined || - uids === null || - (Array.isArray(uids) && uids.length === 0) - ) { - throw new IMAPError("Nothing to fetch"); - } - - if (!Array.isArray(uids)) { - uids = [uids]; - } - validateUIDList(uids); - - if (uids.length === 0) { - throw new IMAPError( - "Empty " + (which === "" ? "sequence number" : "uid") + " list", - ); - } - - uids = uids.join(","); - - let cmd = which + "FETCH " + uids + " ("; - const fetching = []; - let i; - let len; - let key; - - if (this.serverSupports("X-GM-EXT-1")) { - fetching.push("X-GM-THRID"); - fetching.push("X-GM-MSGID"); - fetching.push("X-GM-LABELS"); - } - if (this.serverSupports("CONDSTORE") && !this.box.nomodseq) { - fetching.push("MODSEQ"); - } - - fetching.push("UID"); - fetching.push("FLAGS"); - fetching.push("INTERNALDATE"); - - let modifiers; - - if (options) { - modifiers = options.modifiers; - if (options.envelope) { - fetching.push("ENVELOPE"); - } - if (options.struct) { - fetching.push("BODYSTRUCTURE"); - } - if (options.size) { - fetching.push("RFC822.SIZE"); - } - if (Array.isArray(options.extensions)) { - options.extensions.forEach((extension) => { - fetching.push(extension.toUpperCase()); - }); - } - cmd += fetching.join(" "); - if (options.bodies !== undefined) { - let bodies = options.bodies; - const prefix = options.markSeen ? "" : ".PEEK"; - if (!Array.isArray(bodies)) { - bodies = [bodies]; - } - for (i = 0, len = bodies.length; i < len; ++i) { - fetching.push(bodies[i]); - cmd += " BODY" + prefix + "[" + bodies[i] + "]"; - } - } - } else { - cmd += fetching.join(" "); - } - - cmd += ")"; - - const modkeys = - typeof modifiers === "object" ? Object.keys(modifiers) : []; - let modstr = " ("; - for (i = 0, len = modkeys.length, key; i < len; ++i) { - key = modkeys[i].toUpperCase(); - if ( - key === "CHANGEDSINCE" && - this.serverSupports("CONDSTORE") && - !this.box.nomodseq - ) { - modstr += key + " " + modifiers[modkeys[i]] + " "; - } - } - if (modstr.length > 2) { - cmd += modstr.substring(0, modstr.length - 1); - cmd += ")"; - } - - this.enqueue(cmd); - const req = this.queue[this.queue.length - 1]; - req.fetchCache = {}; - req.fetching = fetching; - return (req.bodyEmitter = new EventEmitter()); - } - - private storeLabels(which, uids, labels, mode, cb: Function) { - if (!this.serverSupports("X-GM-EXT-1")) { - throw new IMAPError("Server must support X-GM-EXT-1 capability"); - } else if (this.box === undefined) { - throw new IMAPError("No mailbox is currently selected"); - } else if (uids === undefined) { - throw new IMAPError("No messages specified"); - } - - if (!Array.isArray(uids)) { - uids = [uids]; - } - validateUIDList(uids); - - if (uids.length === 0) { - throw new IMAPError( - "Empty " + (which === "" ? "sequence number" : "uid") + "list", - ); - } - - if ( - (!Array.isArray(labels) && typeof labels !== "string") || - (Array.isArray(labels) && labels.length === 0) - ) { - throw new IMAPError( - "labels argument must be a string or a non-empty Array", - ); - } - - if (!Array.isArray(labels)) { - labels = [labels]; - } - labels = labels - .map((v) => { - return '"' + escape(utf7.encode("" + v)) + '"'; - }) - .join(" "); - - uids = uids.join(","); - - this.enqueue( - which + - "STORE " + - uids + - " " + - mode + - "X-GM-LABELS.SILENT (" + - labels + - ")", - cb, - ); - } - - private _sort(which, sorts, criteria, cb: Function) { - if (this.box === undefined) { - throw new IMAPError("No mailbox is currently selected"); - } else if (!Array.isArray(sorts) || !sorts.length) { - throw new IMAPError( - "Expected array with at least one sort criteria", - ); - } else if (!Array.isArray(criteria)) { - throw new IMAPError("Expected array for search criteria"); - } else if (!this.serverSupports("SORT")) { - throw new IMAPError("Sort is not supported on the server"); - } - - sorts = sorts.map((c) => { - if (typeof c !== "string") { - throw new IMAPError( - "Unexpected sort criteria data type. " + - "Expected string. Got: " + - typeof criteria, - ); - } - - let modifier = ""; - if (c[0] === "-") { - modifier = "REVERSE "; - c = c.substring(1); - } - switch (c.toUpperCase()) { - case "ARRIVAL": - case "CC": - case "DATE": - case "FROM": - case "SIZE": - case "SUBJECT": - case "TO": - break; - default: - throw new IMAPError("Unexpected sort criteria: " + c); - } - - return modifier + c; + this.parser.on("unknown", (resp: UnknownResponse) => { + this.emit("unknownResponse", resp); + this.emit("response", resp); }); - - sorts = sorts.join(" "); - - const info = { hasUTF8: false /*output*/ }; - let query = buildSearchQuery(criteria, this.caps, info); - let charset = "US-ASCII"; - let lines; - if (info.hasUTF8) { - charset = "UTF-8"; - lines = query.split(CRLF); - query = lines.shift(); - } - - this.enqueue(which + "SORT (" + sorts + ") " + charset + query, cb); - if (info.hasUTF8) { - const req = this.queue[this.queue.length - 1]; - req.lines = lines; - } - } - - private _esearch(which, criteria, options, cb: Function) { - if (this.box === undefined) { - throw new IMAPError("No mailbox is currently selected"); - } else if (!Array.isArray(criteria)) { - throw new IMAPError("Expected array for search options"); - } - - const info = { hasUTF8: false /*output*/ }; - let query = buildSearchQuery(criteria, this.caps, info); - let charset = ""; - let lines; - if (info.hasUTF8) { - charset = " CHARSET UTF-8"; - lines = query.split(CRLF); - query = lines.shift(); - } - - if (typeof options === "function") { - cb = options; - options = ""; - } else if (!options) { - options = ""; - } - - if (Array.isArray(options)) { - options = options.join(" "); - } - - this.enqueue( - which + "SEARCH RETURN (" + options + ")" + charset + query, - cb, - ); - if (info.hasUTF8) { - const req = this.queue[this.queue.length - 1]; - req.lines = lines; - } - } - - private _thread(which, algorithm, criteria, cb: Function) { - algorithm = algorithm.toUpperCase(); - - if (!this.serverSupports("THREAD=" + algorithm)) { - throw new IMAPError( - "Server does not support that threading algorithm", - ); - } - - const info = { hasUTF8: false /*output*/ }; - let query = buildSearchQuery(criteria, this.caps, info); - let charset = "US-ASCII"; - let lines; - if (info.hasUTF8) { - charset = "UTF-8"; - lines = query.split(CRLF); - query = lines.shift(); - } - - this.enqueue(which + "THREAD " + algorithm + " " + charset + query, cb); - if (info.hasUTF8) { - const req = this.queue[this.queue.length - 1]; - req.lines = lines; - } - } - - private resUntagged(resp: UntaggedResponse) { - const { content, type } = resp; - let i; - let len; - let box; - if (content instanceof StatusResponse && content.status === "BYE") { - if (this.sock) { - this.sock.end(); - } - } else if ( - type === "NAMESPACE" && - content instanceof NamespaceResponse - ) { - this.namespaces = content; - } else if (type === "ID" && content instanceof IDResponse) { - this.curReq?.cbargs.push(content.details); - } else if (type === "CAPABILITY" && content instanceof CapabilityList) { - this.caps = content; - } else if ( - content instanceof StatusResponse && - content.status === "PREAUTH" - ) { - this.state = "authenticated"; - } else if (content instanceof SortResponse) { - this.curReq.cbargs.push(content.ids); - } else if (content instanceof ExtendedSearchResponse) { - this.curReq.cbargs.push(content); - } else if (content instanceof ThreadResponse) { - this.curReq.cbargs.push(content.threads); - } else if (content instanceof SearchResponse) { - // CONDSTORE-modified search results - this.curReq.cbargs.push(content.results); - this.curReq.cbargs.push(content.modseq); - } else if (content instanceof QuotaResponse) { - this.curReq.cbargs.push(content.quotas); - this.curReq.cbargs.push(content.rootName); - } else if (content instanceof RecentCount) { - if (!this.box && RE_OPENBOX.test(this.curReq.type)) { - this.box = Connection.getDefaultBox(); - } - if (this.box) { - this.box.messages.new = content.count; - } - } else if (content instanceof FlagList) { - if (!this.box && RE_OPENBOX.test(this.curReq.type)) { - this.box = Connection.getDefaultBox(); - } - if (this.box) { - this.box.flags = content; - } - } else if ( - content instanceof StatusResponse && - (content.status === "BAD" || content.status === "NO") - ) { - if (this.state === "connected" && !this.curReq) { - if (typeof this.tmrConn !== "undefined") { - clearTimeout(this.tmrConn); - } - if (typeof this.tmrAuth !== "undefined") { - clearTimeout(this.tmrAuth); - } - const err = new IMAPError( - "Received negative welcome: " + content.text, - ); - err.source = "protocol"; - this.emit("error", err); - if (this.sock) { - this.sock.end(); - } - } - } else if (content instanceof ExistsCount) { - if (!this.box && RE_OPENBOX.test(this.curReq.type)) { - this.box = Connection.getDefaultBox(); - } - if (this.box) { - const prev = this.box.messages.total; - const now = content.count; - this.box.messages.total = now; - if (now > prev && this.state === "authenticated") { - this.box.messages.new = now - prev; - this.emit("mail", this.box.messages.new); - } - } - } else if (content instanceof Expunge) { - if (this.box) { - if (this.box.messages.total > 0) { - --this.box.messages.total; - } - this.emit("expunge", content.sequenceNumber); - } - } else if ( - content instanceof StatusResponse && - content.status === "OK" - ) { - if (this.state === "connected" && !this.curReq) { - this.login(); - } else if ( - content.text && - content.text.code && - content.text.code.kind === "ALERT" - ) { - this.emit("alert", content.text.content); - } else if ( - this.curReq && - content.text && - content.text.code && - RE_OPENBOX.test(this.curReq.type) - ) { - // we're opening a mailbox - - if (!this.box) { - this.box = Connection.getDefaultBox(); - } - const code = content.text.code; - const kind = code.kind; - - if ( - kind === "UIDVALIDITY" && - code instanceof NumberTextCode && - typeof code.value === "number" - ) { - this.box.uidvalidity = code.value; - } else if ( - kind === "UIDNEXT" && - code instanceof NumberTextCode && - typeof code.value === "number" - ) { - this.box.uidnext = code.value; - } else if ( - kind === "HIGHESTMODSEQ" && - code instanceof NumberTextCode - ) { - this.box.highestmodseq = "" + code.value; - } else if (code instanceof PermentantFlagsTextCode) { - let permFlags: FlagList; - let keywords; - this.box.permFlags = permFlags = code.flags; - this.box.newKeywords = permFlags.includesWildcard; - this.box.keywords = keywords = permFlags.flags - .filter((f) => { - return f.name[0] !== "\\" && !f.isWildcard; - }) - .map((f) => f.name); - } else if (kind === "UIDNOTSTICKY") { - this.box.persistentUIDs = false; - } else if (kind === "NOMODSEQ") { - this.box.nomodseq = true; - } - } else if ( - content.text && - content.text.code && - content.text.code.kind === "UIDVALIDITY" && - content.text.code instanceof NumberTextCode - ) { - this.emit("uidvalidity", content.text.code.value); - } - } else if (content instanceof MailboxListing) { - if (this.delimiter === undefined) { - this.delimiter = content.separator; - } else { - if (this.curReq.cbargs.length === 0) { - this.curReq.cbargs.push({}); - } - - box = { - attribs: content.flags, - children: null, - delimiter: content.separator, - parent: null, - }; - - box.special_use_attrib = content.getSpecialUse(); - - let name = content.name; - let curChildren = this.curReq.cbargs[0]; - - if (box.delimiter) { - const path = name.split(box.delimiter); - let parent = null; - name = path.pop(); - for (i = 0, len = path.length; i < len; ++i) { - if (!curChildren[path[i]]) { - curChildren[path[i]] = {}; - } - if (!curChildren[path[i]].children) { - curChildren[path[i]].children = {}; - } - parent = curChildren[path[i]]; - curChildren = curChildren[path[i]].children; - } - box.parent = parent; - } - if (curChildren[name]) { - box.children = curChildren[name].children; - } - curChildren[name] = box; - } - } else if (content instanceof MailboxStatus) { - this.curReq.cbargs.push(content); - } else if (content instanceof Fetch) { - if (/^(?:UID )?FETCH/.test(this.curReq.fullcmd)) { - this.curReq.bodyEmitter.emit( - "message", - content, - content.sequenceNumber, - ); - } else { - // FETCH response sent as result of STORE request or sent unilaterally, - // treat them as the same for now for simplicity - this.emit("update", content.sequenceNumber, content); - } - } } - private resTagged(info: TaggedResponse) { - const req = this.curReq; - let err; - - if (!req) { - return; - } - - this.curReq = undefined; - - const status = info.status.status; - const statusText = info.status.text; - const statusCode = statusText?.code; - if (status === "NO" || status === "BAD") { - if (statusText) { - err = new IMAPError(statusText.content); - err.textCode = statusText.code; - } else { - err = new IMAPError(req.oauthError); - } - err.type = status; - err.source = "protocol"; - } else if (this.box) { - if (req.type === "EXAMINE" || req.type === "SELECT") { - this.box.readOnly = - statusCode && statusCode.kind.toUpperCase() === "READ-ONLY"; - } - - // According to RFC 3501, UID commands do not give errors for - // non-existant user-supplied UIDs, so give the callback empty results - // if we unexpectedly received no untagged responses. - if ( - RE_UIDCMD_HASRESULTS.test(req.fullcmd) && - req.cbargs.length === 0 - ) { - req.cbargs.push([]); - } + protected async starttls(): Promise { + if(!this.connected || !this.socket || this.isSecure) { + // Don't need to (or can't) do TLS in this case + return this.connected; } - if (req.bodyEmitter) { - const bodyEmitter = req.bodyEmitter; - if (err) { - bodyEmitter.emit("error", err); - } - process.nextTick(() => { - bodyEmitter.emit("end"); + const greeting = await new Promise((resolve, reject) => { + const greetingTimeoutAmount = this.options.timeout || DEFAULT_TIMEOUT; + const greetingTimeout = setTimeout(() => { + reject(new ConnectionTimeout(greetingTimeoutAmount, 'Greeting')) + }, greetingTimeoutAmount) + this.once('serverStatus', (resp) => { + clearTimeout(greetingTimeout); + resolve(resp) }); - } else { - req.cbargs.unshift(err); - if (statusCode) { - if (statusCode instanceof AppendUIDTextCode) { - req.cbargs.push(statusCode.uids); - } else if (statusCode instanceof CopyUIDTextCode) { - req.cbargs.push(statusCode.toUIDs); - } - } - if (req.cb) { - req.cb.apply(this, req.cbargs); - } - } + }); - if ( - this.queue.length === 0 && - this.config.keepalive && - this.state === "authenticated" && - !this.idle.enabled - ) { - this.idle.enabled = true; - this.doKeepaliveTimer(true); + if(!(greeting.content instanceof StatusResponse)) { + throw new IMAPError('Error processing greeting message from server: Invalid content type'); } - this.processQueue(); - } - - private doKeepaliveTimer(immediate = false) { - if (!this.config.keepalive) { - return; + let capabilities: CapabilityList; + if(greeting.content.text?.code instanceof CapabilityTextCode) { + // We have a capability list already! Yay + capabilities = greeting.content.text.code.capabilities + } else { + // We need to retrieve the capabilities + const cmd = new CapabilityCommand(); + capabilities = await cmd.run(this); } - const keepalive = { - interval: KEEPALIVE_INTERVAL, - idleInterval: MAX_IDLE_WAIT, - forceNoop: false, - }; - if (typeof this.config.keepalive === "object") { - Object.assign(keepalive, this.config.keepalive); + if(capabilities.doesntHave('STARTTLS')) { + return this.connected; } - const timerfn = () => { - if (this.idle.enabled) { - // unlike NOOP, IDLE is only a valid command after authenticating - if ( - !this.serverSupports("IDLE") || - this.state !== "authenticated" || - keepalive.forceNoop - ) { - this.enqueue("NOOP", true); - } else { - if (typeof this.idle.started !== "number") { - this.idle.started = 0; - this.enqueue("IDLE", true); - } else if (this.idle.started > 0) { - const timeDiff = Date.now() - this.idle.started; - if (timeDiff >= keepalive.idleInterval) { - this.idle.enabled = false; - this.debug("=> DONE"); - if (this.sock) { - this.sock.write("DONE" + CRLF); - } - return; - } - } - this.tmrKeepalive = setTimeout(timerfn, keepalive.interval); - } - } - }; + const tlsCmd = new StartTLSCommand(); + const startNegotiation: boolean = await tlsCmd.run(this); - if (immediate) { - timerfn(); - } else { - this.tmrKeepalive = setTimeout(timerfn, keepalive.interval); + if(!startNegotiation) { + // In theory we shouldn't be able to hit this as + // the above should throw if we can't negotiate, + // but want to be safe + return false } - } - private login() { - let checkedNS = false; + return new Promise((resolve, reject) => { + const previousSocket = this.socket; + previousSocket.unpipe(this.processingPipeline); - const reentry = (err?: Error) => { - if (this.tmrAuth) { - clearTimeout(this.tmrAuth); - } - if (err) { - this.emit("error", err); - if (this.sock) { - this.sock.end(); - } - return; - } - - // 2. Get the list of available namespaces (RFC2342) - if (!checkedNS && this.serverSupports("NAMESPACE")) { - checkedNS = true; - return this.enqueue("NAMESPACE", reentry); - } - - // 3. Get the top-level mailbox hierarchy delimiter used by the server - this.enqueue('LIST "" ""', () => { - this.state = "authenticated"; - this.emit("ready"); - }); - }; - - // 1. Get the supported capabilities - this.enqueue("CAPABILITY", () => { - // No need to attempt the login sequence if we're on a PREAUTH connection. - if (this.state === "connected") { - let err; - const checkCaps = (error) => { - if (error) { - error.source = "authentication"; - return reentry(error); - } - - if (this.caps === undefined) { - // Fetch server capabilities if they were not automatically - // provided after authentication - return this.enqueue("CAPABILITY", reentry); - } else { - reentry(); + const tlsOptions: tls.ConnectionOptions = { + host: this.options.host, + rejectUnauthorized: true, + }; + // Host name may be overridden the tlsOptions + Object.assign(tlsOptions, this.options.tlsOptions); + tlsOptions.socket = previousSocket; + + const timeoutWait = this.options.timeout || DEFAULT_TIMEOUT + let timeout = setTimeout(() => { + // Check to make sure we didn't already close the connection + if(previousSocket.destroyed) { return; } + + timeout = undefined; + const tmrErr = new ConnectionTimeout(timeoutWait, 'TLS Negotiation') + previousSocket.destroy(tmrErr); + reject(tmrErr); + }, timeoutWait); + let tlsSock: tls.TLSSocket; + const clearTimer = (connected) => { + return () => { + if(timeout) { + clearTimeout(timeout); + timeout = undefined; + resolve(connected); } - }; - - if ( - this.serverSupports("STARTTLS") && - (this.config.autotls === "always" || - (this.config.autotls === "required" && - this.serverSupports("LOGINDISABLED"))) - ) { - this.starttls(); - return; - } - - if (this.serverSupports("LOGINDISABLED")) { - err = new IMAPError( - "Logging in is disabled on this server", - ); - err.source = "authentication"; - return reentry(err); + tlsSock.off('close', clearTimerBad); } - - let cmd; - if (this.serverSupports("AUTH=XOAUTH") && this.config.xoauth) { - this.caps = undefined; - cmd = "AUTHENTICATE XOAUTH"; - // are there any servers that support XOAUTH/XOAUTH2 and not SASL-IR? - // if (this.serverSupports('SASL-IR')) - cmd += " " + escape(this.config.xoauth); - this.enqueue(cmd, checkCaps); - } else if ( - this.serverSupports("AUTH=XOAUTH2") && - this.config.xoauth2 - ) { - this.caps = undefined; - cmd = "AUTHENTICATE XOAUTH2"; - // if (this.serverSupports('SASL-IR')) - cmd += " " + escape(this.config.xoauth2); - this.enqueue(cmd, checkCaps); - } else if (this.config.user && this.config.password) { - this.caps = undefined; - this.enqueue( - 'LOGIN "' + - escape(this.config.user) + - '" "' + - escape(this.config.password) + - '"', - checkCaps, - ); - } else { - err = new IMAPError( - "No supported authentication method(s) available. " + - "Unable to login.", - ); - err.source = "authentication"; - return reentry(err); - } - } else { - reentry(); } - }); - } + const clearTimerGood = clearTimer(true); + const clearTimerBad = clearTimer(false); - private starttls() { - this.enqueue("STARTTLS", (err) => { - if (err) { - this.emit("error", err); - if (this.sock) { - this.sock.end(); - } - return; - } + tlsSock = tls.connect(tlsOptions, clearTimerGood); + this.socket = tlsSock; + this.secure = true; - this.caps = undefined; - if (this.sock) { - this.sock.removeAllListeners("error"); - } - - const tlsOptions: tls.ConnectionOptions = {}; - - tlsOptions.host = this.config.host; - // Host name may be overridden the tlsOptions - Object.assign(tlsOptions, this.config.tlsOptions); - if (this.sock) { - tlsOptions.socket = this.sock; - this.sock.unpipe(this.newlineTransform); - } - - this.sock = tls.connect(tlsOptions, () => { - this.login(); - }); - - this.sock.on("error", this.onError); - this.sock.on("timeout", this.onSocketTimeout); - this.sock.setTimeout(this.config.socketTimeout); - - // The rest of the piping should still be setup, - // so just reattach the socket to the start of - // of the pipeline - this.sock.pipe(this.newlineTransform); + this.socket.pipe(this.processingPipeline); }); } - - private processQueue() { - if ( - this.curReq || - !this.queue.length || - !this.sock || - !this.sock.writable - ) { - return; - } - - this.curReq = this.queue.shift(); - - if (this.tagcount === MAX_INT) { - this.tagcount = 0; - } - - let prefix; - - if (this.curReq.type === "IDLE" || this.curReq.type === "NOOP") { - prefix = this.curReq.type; - } else { - prefix = "A" + this.tagcount++; - } - - const out = prefix + " " + this.curReq.fullcmd; - this.debug("=> " + inspect(out)); - this.sock.write(out + CRLF, "utf8"); - - if (this.curReq.literalAppendData) { - // LITERAL+: we are appending a mesage, and not waiting for a reply - this.sockWriteAppendData(this.curReq.literalAppendData); - } - } - - private sockWriteAppendData(appendData) { - if (!this.sock) { - return; - } - - let val = appendData; - if (Buffer.isBuffer(appendData)) { - val = val.toString("utf8"); - } - - this.debug("=> " + inspect(val)); - this.sock.write(val); - this.sock.write(CRLF); - } - - // TODO: Function is not specific enough, but cb can be a lot of things - private enqueue( - fullcmd: string, - promote: Function | boolean = false, - cb?: Function, - ) { - if (typeof promote === "function") { - cb = promote; - promote = false; - } - - const info: ICommand = { - cb, - cbargs: [], - fullcmd, - type: fullcmd.match(RE_CMD)[1], - }; - - if (promote) { - this.queue.unshift(info); - } else { - this.queue.push(info); - } - - if (!this.curReq && this.state !== "disconnected") { - // defer until next tick for requests like APPEND and FETCH where access to - // the request object is needed immediately after enqueueing - process.nextTick(() => { - this.processQueue(); - }); - } else if ( - this.curReq && - this.curReq.type === "IDLE" && - this.sock && - this.sock.writable && - this.idle.enabled - ) { - this.idle.enabled = false; - if (this.tmrKeepalive) { - clearTimeout(this.tmrKeepalive); - } - if (this.idle.started > 0) { - // we've seen the continuation for our IDLE - this.debug("=> DONE"); - this.sock.write("DONE" + CRLF); - } - } - } } diff --git a/src/connection/errors.ts b/src/connection/errors.ts new file mode 100644 index 00000000..72e6d14d --- /dev/null +++ b/src/connection/errors.ts @@ -0,0 +1,12 @@ +export class ConnectionTimeout extends Error { + constructor( + public readonly timeout: number, + public readonly phase: "Socket" | "Greeting" | "TLS Negotiation", + ) { + super(`IMAP connection timed out`); + } +} + +export class TLSSocketError extends Error {} + +export type ConnectionErrors = ConnectionTimeout | TLSSocketError; diff --git a/src/connection/index.ts b/src/connection/index.ts index aa2a5701..c73586e1 100644 --- a/src/connection/index.ts +++ b/src/connection/index.ts @@ -1,4 +1,4 @@ import Connection from "./connection"; export default Connection; -export { IConfig } from "./types"; +export { IMAPConnectionConfiguration } from "./types"; diff --git a/src/connection/queue.ts b/src/connection/queue.ts new file mode 100644 index 00000000..7c0e90af --- /dev/null +++ b/src/connection/queue.ts @@ -0,0 +1,188 @@ +import { TypedEmitter } from "tiny-typed-emitter"; + +import { Command } from "../commands"; + +import type Connection from "../connection"; + +type AsyncQueueEvents = { + commandStart: (command: Command) => void; + commandDone: (command: Command) => void; + commandCanceled: (command: Command) => void; + + start: () => void; + idle: () => void; +}; + +type CommandQueueEvents = { + idle: () => void; +}; + +export class AsyncQueueContext extends TypedEmitter { + public commands: Set>; + public running: boolean; + + constructor( + public readonly connection: Connection, + immediatelyStart = false, + ) { + super(); + this.commands = new Set(); + this.running = immediatelyStart; + } + + public get isComplete() { + return this.commands.size === 0 && this.running === true; + } + + public get size() { + return this.commands.size; + } + + public add(command: Command) { + this.commands.add(command); + + if (this.running) { + this.startCommand(command); + } + } + + protected remove(command: Command) { + this.commands.delete(command); + command.emit("cancel"); + this.emit("commandCanceled", command); + } + + public run() { + if (this.running) { + return; + } + + this.running = true; + this.emit("start"); + for (const cmd of this.commands) { + this.startCommand(cmd); + } + } + + public stop() { + if (!this.running) { + return; + } + + this.running = false; + for (const cmd of this.commands) { + this.remove(cmd); + } + } + + private startCommand(command: Command) { + if (!this.running) { + return; + } + + this.emit("commandStart", command); + const cmdRun = command.run(this.connection); + cmdRun.finally(() => { + this.emit("commandDone", command); + this.commands.delete(command); + if (this.commands.size === 0) { + this.emit("idle"); + } + }); + } +} + +export default class CommandQueue extends TypedEmitter { + public queueContexts: AsyncQueueContext[]; + + constructor( + public readonly connection: Connection, + private running: boolean = false, + ) { + super(); + this.queueContexts = []; + } + + protected get activeContext(): AsyncQueueContext | void { + return this.queueContexts[0]; + } + + protected get waitingContext(): AsyncQueueContext | void { + return this.queueContexts[this.queueContexts.length - 1]; + } + + add(command: Command) { + if ( + !this.waitingContext || + (command.requiresOwnContext && this.waitingContext.size > 0) + ) { + const q = this.addQueueContext(); + } + + // We just created it if it doesn't exist, so this is a safe add + (this.waitingContext as AsyncQueueContext).add(command); + + if (command.requiresOwnContext) { + // This command needs to be isolated + this.addQueueContext(); + } + } + + cancelAllRunningCommands() { + if (this.activeContext) { + this.activeContext.stop(); + } + } + + start() { + this.running = true; + if (this.activeContext) { + this.activeContext.run(); + } + } + + stop() { + this.running = false; + this.cancelAllRunningCommands(); + } + + private addQueueContext() { + const q = new AsyncQueueContext( + this.connection, + // Auto-start if we're the first in the queue and + // have an active connection + this.running && this.queueContexts.length === 0, + ); + // remove it once the queue is idle + q.once("idle", () => this.removeQueueContext(q)); + return q; + } + + private removeQueueContext( + fromContext: AsyncQueueContext | void = undefined, + ) { + const currActive = this.activeContext; + fromContext = fromContext || currActive; + + if (!fromContext) { + return; + } + + const i = this.queueContexts.findIndex( + (check) => check === fromContext, + ); + if (i > 0) { + this.queueContexts.splice(i, 1); + } + + // We removed the previously running active context, start + // the next one or mark ourselves as idle + if (currActive === fromContext && this.running) { + if (this.activeContext) { + this.activeContext.run(); + } else { + this.emit("idle"); + } + } + } +} diff --git a/src/connection/types.ts b/src/connection/types.ts index 91afca01..9369817f 100644 --- a/src/connection/types.ts +++ b/src/connection/types.ts @@ -1,12 +1,17 @@ -import { EventEmitter } from "events"; -import { Socket } from "net"; import * as tls from "tls"; -import type { FlagList } from "../parser"; +import { + ContinueResponse, + TaggedResponse, + UnknownResponse, + UntaggedResponse, +} from "../parser"; +import { ConnectionErrors } from "./errors"; export enum TLSSetting { "DEFAULT" = "on", "STARTTLS" = "starttls", + "STARTTLS_OPTIONAL" = "opportunistic", "FORCE_OFF" = "off", } @@ -18,62 +23,23 @@ export type IMAPConnectionConfiguration = { timeout?: number; }; -export interface IConfig { - authTimeout?: number; - autotls?: "never" | "always" | "required"; - connTimeout?: number; - debug?: (msg: string) => void; - host: string; - keepalive: - | boolean - | { interval?: number; idleInterval?: number; forceNoop?: boolean }; - localAddress: string; - password: string; - port: number; - socket?: Socket; - socketTimeout?: number; - tls?: boolean; - tlsOptions?: tls.ConnectionOptions; - user: string; - xoauth: string; - xoauth2: string; -} - -export interface ICommand { - appendData?: any; - bodyEmitter?: EventEmitter; - cb: Function; - cbargs: any[]; - data?: any; - fetchCache?: any; - fetching?: string[]; - fullcmd?: string; - lines?: string[]; - literalAppendData?: any; - oauthError?: string; - type: string; -} - -export interface IBox { - name: string; - flags: FlagList; - readOnly: boolean; - uidvalidity: number; - uidnext: number; - permFlags: FlagList; - keywords: string[]; - newKeywords: boolean; - persistentUIDs: boolean; - nomodseq: boolean; - highestmodseq?: string; - messages: { - total: number; - new: number; - }; -} +export interface IConnectionEvents { + // Connection Events + ready: (isSecure: boolean) => void; + connectionError: (error: ConnectionErrors) => void; + disconnected: (wasGraceful: boolean) => void; -export interface INamespaces { - personal: string[]; - other: string[]; - shared: string[]; + // Response Events + serverStatus: (response: UntaggedResponse) => void; + response: ( + response: + | ContinueResponse + | TaggedResponse + | UnknownResponse + | UntaggedResponse, + ) => void; + continueResponse: (response: ContinueResponse) => void; + taggedResponse: (response: TaggedResponse) => void; + unknownResponse: (response: UnknownResponse) => void; + untaggedResponse: (response: UntaggedResponse) => void; } diff --git a/src/newline.transform.ts b/src/newline.transform.ts index 754e56c3..cb6af52b 100644 --- a/src/newline.transform.ts +++ b/src/newline.transform.ts @@ -8,6 +8,7 @@ const DEFUALT_MAX_LINE_LENGTH = 2e6; // 2MB export type NewlineTranformOptions = Partial<{ maxLineLength: number; + allowHalfOpen: boolean; }>; interface INewlineTranformEvents { @@ -62,6 +63,7 @@ class NewlineTranform extends Transform { constructor(options?: NewlineTranformOptions) { super({ + allowHalfOpen: options?.allowHalfOpen, objectMode: true, }); @@ -72,12 +74,16 @@ class NewlineTranform extends Transform { : DEFUALT_MAX_LINE_LENGTH; } - _flush(done: () => void) { - if (this.currentLine && this.currentLine.length) { + public forceNewLine(emitData = true) { + if (emitData && this.currentLine && this.currentLine.length) { this.push(this.currentLine); this.emit("line", this.currentLine); } this.currentLine = undefined; + } + + _flush(done: () => void) { + this.forceNewLine(); done(); } diff --git a/src/parser/structure/capability.ts b/src/parser/structure/capability.ts index 973c4325..78e59801 100644 --- a/src/parser/structure/capability.ts +++ b/src/parser/structure/capability.ts @@ -263,4 +263,9 @@ export class CapabilityList { public has(capability: string) { return this.capabilityMap.has(capability.toUpperCase()); } + + // Some sugar + public doesntHave(capability: string) { + return !this.has(capability); + } } diff --git a/yarn.lock b/yarn.lock index 977a164f..c15d1084 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2915,6 +2915,11 @@ throat@^6.0.1: resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== +tiny-typed-emitter@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz#b3b027fdd389ff81a152c8e847ee2f5be9fad7b5" + integrity sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA== + tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" From 12495630ab0e44bb070e21b1e695b1058e2efa09 Mon Sep 17 00:00:00 2001 From: Alexis Hushbeck Date: Mon, 4 Jul 2022 10:43:36 -0700 Subject: [PATCH 05/10] =?UTF-8?q?=F0=9F=8E=89Hook=20up=20Session/Connectio?= =?UTF-8?q?n=20and=20Clean=20Up?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Actually connects and exposes the Session class so that it functions and can create and manage an IMAP session! This is exciting, and I was able to connect a new session to GMail and get the capabilities and server info 💃 **Test plan:** Connect to GMail using the Session class Celebrate 🙌 --- src/commands/base.ts | 8 +- src/commands/id.ts | 2 +- src/connection/connection.ts | 231 +++++++++++++++++++++-------------- src/connection/queue.ts | 1 + src/index.ts | 10 +- src/{imap.ts => session.ts} | 29 +++-- src/types.ts | 4 +- 7 files changed, 167 insertions(+), 118 deletions(-) rename src/{imap.ts => session.ts} (77%) diff --git a/src/commands/base.ts b/src/commands/base.ts index e52bf869..f2f47e9d 100644 --- a/src/commands/base.ts +++ b/src/commands/base.ts @@ -2,7 +2,7 @@ import { EventEmitter } from "events"; import { IMAPError, NotImplementedError } from "../errors"; -import type Connection from "../connection"; +import Connection from "../connection"; import { ContinueResponse, TaggedResponse, UntaggedResponse } from "../parser"; // General commands @@ -68,10 +68,10 @@ export abstract class Command extends EventEmitter { this.commandPromise = new Promise(this.executor); } - protected executor( + protected executor = ( resolve: (result: T) => void, reject: (reason: any) => any, - ): void { + ): void => { const cleanUpHandlers = () => { this.off("results", successHandler); this.off("error", errorHandler); @@ -97,7 +97,7 @@ export abstract class Command extends EventEmitter { this.once("results", successHandler); this.once("error", errorHandler); this.once("cancel", cancelHandler); - } + }; protected getCommand(): string { return this.type; diff --git a/src/commands/id.ts b/src/commands/id.ts index e5c875ef..2772ef59 100644 --- a/src/commands/id.ts +++ b/src/commands/id.ts @@ -23,7 +23,7 @@ export type IdCommandValues = Partial< } >; -export type IdResponseMap = Map; +export type IdResponseMap = ReadonlyMap; const DEFAULT_ID_OPTS: IdCommandValues = { name: "node-imap", diff --git a/src/connection/connection.ts b/src/connection/connection.ts index f2d1d486..48860ae0 100644 --- a/src/connection/connection.ts +++ b/src/connection/connection.ts @@ -1,9 +1,9 @@ -import { Socket } from "net"; +import * as net from "net"; import { clearTimeout, setTimeout } from "timers"; import * as tls from "tls"; -import { TypedEmitter } from 'tiny-typed-emitter'; +import { TypedEmitter } from "tiny-typed-emitter"; -import { CapabilityCommand, StartTLSCommand, type Command } from "../commands"; +import { CapabilityCommand, StartTLSCommand, Command } from "../commands"; import { IMAPError } from "../errors"; import NewlineTranform from "../newline.transform"; import Lexer from "../lexer"; @@ -16,17 +16,19 @@ import Parser, { UnknownResponse, UntaggedResponse, } from "../parser"; -import { - CRLF, -} from "./constants"; +import { CRLF } from "./constants"; import CommandQueue from "./queue"; -import { IConnectionEvents, IMAPConnectionConfiguration, TLSSetting } from "./types"; +import { + IConnectionEvents, + IMAPConnectionConfiguration, + TLSSetting, +} from "./types"; import { ConnectionTimeout, TLSSocketError } from "./errors"; const DEFAULT_TIMEOUT = 10000; export default class Connection extends TypedEmitter { - public socket: undefined | Socket; + public socket: undefined | net.Socket | tls.TLSSocket; protected lexer: Lexer; protected parser: Parser; @@ -43,8 +45,16 @@ export default class Connection extends TypedEmitter { this.options = Object.assign({}, options); // Set TLS setting to default if it is unset or invalid - let {tls} = this.options; - if(!tls || !(tls === TLSSetting.DEFAULT || tls === TLSSetting.STARTTLS || tls === TLSSetting.STARTTLS_OPTIONAL || tls === TLSSetting.FORCE_OFF)) { + let { tls } = this.options; + if ( + !tls || + !( + tls === TLSSetting.DEFAULT || + tls === TLSSetting.STARTTLS || + tls === TLSSetting.STARTTLS_OPTIONAL || + tls === TLSSetting.FORCE_OFF + ) + ) { this.options.tls = tls = TLSSetting.DEFAULT; } @@ -62,101 +72,121 @@ export default class Connection extends TypedEmitter { } public async connect(): Promise { - if(this.connected) { - throw new IMAPError('Must end previous IMAP connection before starting a new one') + if (this.connected) { + throw new IMAPError( + "Must end previous IMAP connection before starting a new one", + ); } else if (this.socket) { - throw new IMAPError('Existing IMAP connection or connection attempt must be fully closed before a new one can be made') + throw new IMAPError( + "Existing IMAP connection or connection attempt must be fully closed before a new one can be made", + ); } - const config = this.options; - let socket: Socket; - let tlsOptions: tls.ConnectionOptions; - - socket = new Socket(); - socket.setKeepAlive(true); + const { + host, + port, + tls: tlsSetting, + tlsOptions, + timeout, + } = this.options; + let tlsSocketConfig: tls.ConnectionOptions; this.socket = undefined; - if (config.tls === TLSSetting.DEFAULT) { - tlsOptions = { + if (tlsSetting === TLSSetting.DEFAULT) { + tlsSocketConfig = { // Host name may be overridden by the tlsOptions - host: config.host, + host, + port, + servername: host, // Explicitly reject unauthorized connections by default rejectUnauthorized: true, }; - Object.assign(tlsOptions, config.tlsOptions); + Object.assign(tlsSocketConfig, tlsOptions); // Socket cannot be overridden - tlsOptions.socket = socket; + delete tlsSocketConfig.socket; } let connected = await new Promise((resolve, reject) => { // Setup a simple timeout - const timeoutWait = config.timeout || DEFAULT_TIMEOUT - let timeout = setTimeout(() => { + const timeoutWait = timeout || DEFAULT_TIMEOUT; + let connTimeout = setTimeout(() => { // Check to make sure we didn't already close the connection - if(socket.destroyed) { return; } + if (!this.socket) { + return; + } - timeout = undefined; - const tmrErr = new ConnectionTimeout(timeoutWait, 'Socket') - socket.destroy(tmrErr); + connTimeout = undefined; + const tmrErr = new ConnectionTimeout(timeoutWait, "Socket"); + this.socket.destroy(tmrErr); + this.socket = undefined; reject(tmrErr); }, timeoutWait); const clearTimer = (connected) => { return () => { - if(timeout) { - clearTimeout(timeout); - timeout = undefined; + if (connTimeout) { + clearTimeout(connTimeout); + connTimeout = undefined; resolve(connected); } - this.socket.off('close', clearTimerBad); - } - } + this.socket.off("end", clearTimerBad); + this.socket.off("close", clearTimerBad); + }; + }; const clearTimerGood = clearTimer(true); const clearTimerBad = clearTimer(false); - if (tlsOptions) { - // Use a local reference here in case this.socket changes - const tlsSock = tls.connect(tlsOptions, clearTimerGood); - this.socket = tlsSock; + if (tlsSocketConfig) { + this.socket = tls.connect(tlsSocketConfig, clearTimerGood); this.secure = true; } else { - socket.connect({ - host: config.host, - port: config.port, - }, clearTimerGood); - this.socket = socket; + this.socket = net.connect( + { + host, + port, + }, + clearTimerGood, + ); this.secure = false; } - this.socket.once('close', clearTimerBad); + this.socket.once("end", clearTimerBad); + this.socket.once("close", clearTimerBad); }); - if(!connected) { + if (!connected) { + this.socket = undefined; return false; } this.socket.pipe(this.processingPipeline); - if(!this.isSecure && (config.tls === TLSSetting.STARTTLS || config.tls === TLSSetting.STARTTLS_OPTIONAL)) { + if ( + !this.isSecure && + (tlsSetting === TLSSetting.STARTTLS || + tlsSetting === TLSSetting.STARTTLS_OPTIONAL) + ) { connected = await this.starttls(); - if(!this.isSecure && config.tls === TLSSetting.STARTTLS) { + if (!this.isSecure && tlsSetting === TLSSetting.STARTTLS) { this.socket.destroy(); this.socket = undefined; - throw new TLSSocketError('Could not establish a secure connection'); + throw new TLSSocketError( + "Could not establish a secure connection", + ); } } this.connected = connected; - if(!connected) { + if (!connected) { this.socket.destroy(); this.socket = undefined; return false; } - this.socket.on('error', this.onSocketError); - this.socket.once('end', this.onSocketEnd); - this.socket.once('close', this.onSocketClose); + this.socket.on("error", this.onSocketError); + this.socket.once("end", this.onSocketEnd); + this.socket.once("close", this.onSocketClose); // Manually call because the ready event will likely have passed this.onSocketReady(); - this.emit('ready', this.isSecure); + this.emit("ready", this.isSecure); return this.connected; } @@ -164,28 +194,28 @@ export default class Connection extends TypedEmitter { protected onSocketReady = () => { this.connected = true; this.commandQueue.start(); - } + }; protected onSocketError = (err) => { - this.emit('connectionError', new IMAPError(err)); - } + this.emit("connectionError", new IMAPError(err)); + }; protected onSocketClose = (hadErr: boolean) => { this.commandQueue.stop(); this.connected = false; - this.socket.unpipe(this.processingPipeline) + this.socket.unpipe(this.processingPipeline); this.processingPipeline.forceNewLine(false); this.socket.removeAllListeners(); this.socket = undefined; this.secure = undefined; - this.emit('disconnected', !hadErr) - } + this.emit("disconnected", !hadErr); + }; protected onSocketEnd = () => { this.commandQueue.stop(); this.connected = false; this.socket.end(); - } + }; public async disconnect(error?: Error) { - if(!this.socket) { + if (!this.socket) { return; } @@ -197,7 +227,7 @@ export default class Connection extends TypedEmitter { this.commandQueue.add(command); return command.results; } - + public send(toSend: string) { this.socket.write(toSend + CRLF, "utf8"); } @@ -206,7 +236,7 @@ export default class Connection extends TypedEmitter { this.commandQueue = new CommandQueue(this, false); // Setup our Lexing/Parsing - this.processingPipeline = new NewlineTranform({ allowHalfOpen: true, }); + this.processingPipeline = new NewlineTranform({ allowHalfOpen: true }); this.lexer = new Lexer(); this.parser = new Parser(); @@ -214,8 +244,8 @@ export default class Connection extends TypedEmitter { this.processingPipeline.pipe(this.lexer).pipe(this.parser); // Once we hit the parser, we want to (mostly) bubble events this.parser.on("untagged", (resp: UntaggedResponse) => { - if(resp.content instanceof StatusResponse) { - this.emit('serverStatus', resp); + if (resp.content instanceof StatusResponse) { + this.emit("serverStatus", resp); } else { this.emit("untaggedResponse", resp); this.emit("response", resp); @@ -236,48 +266,58 @@ export default class Connection extends TypedEmitter { } protected async starttls(): Promise { - if(!this.connected || !this.socket || this.isSecure) { + if (!this.connected || !this.socket || this.isSecure) { // Don't need to (or can't) do TLS in this case return this.connected; } - const greeting = await new Promise((resolve, reject) => { - const greetingTimeoutAmount = this.options.timeout || DEFAULT_TIMEOUT; - const greetingTimeout = setTimeout(() => { - reject(new ConnectionTimeout(greetingTimeoutAmount, 'Greeting')) - }, greetingTimeoutAmount) - this.once('serverStatus', (resp) => { - clearTimeout(greetingTimeout); - resolve(resp) - }); - }); - - if(!(greeting.content instanceof StatusResponse)) { - throw new IMAPError('Error processing greeting message from server: Invalid content type'); + const greeting = await new Promise( + (resolve, reject) => { + const greetingTimeoutAmount = + this.options.timeout || DEFAULT_TIMEOUT; + const greetingTimeout = setTimeout(() => { + reject( + new ConnectionTimeout( + greetingTimeoutAmount, + "Greeting", + ), + ); + }, greetingTimeoutAmount); + this.once("serverStatus", (resp) => { + clearTimeout(greetingTimeout); + resolve(resp); + }); + }, + ); + + if (!(greeting.content instanceof StatusResponse)) { + throw new IMAPError( + "Error processing greeting message from server: Invalid content type", + ); } let capabilities: CapabilityList; - if(greeting.content.text?.code instanceof CapabilityTextCode) { + if (greeting.content.text?.code instanceof CapabilityTextCode) { // We have a capability list already! Yay - capabilities = greeting.content.text.code.capabilities + capabilities = greeting.content.text.code.capabilities; } else { // We need to retrieve the capabilities const cmd = new CapabilityCommand(); capabilities = await cmd.run(this); } - if(capabilities.doesntHave('STARTTLS')) { + if (capabilities.doesntHave("STARTTLS")) { return this.connected; } const tlsCmd = new StartTLSCommand(); const startNegotiation: boolean = await tlsCmd.run(this); - if(!startNegotiation) { + if (!startNegotiation) { // In theory we shouldn't be able to hit this as // the above should throw if we can't negotiate, // but want to be safe - return false + return false; } return new Promise((resolve, reject) => { @@ -292,27 +332,32 @@ export default class Connection extends TypedEmitter { Object.assign(tlsOptions, this.options.tlsOptions); tlsOptions.socket = previousSocket; - const timeoutWait = this.options.timeout || DEFAULT_TIMEOUT + const timeoutWait = this.options.timeout || DEFAULT_TIMEOUT; let timeout = setTimeout(() => { // Check to make sure we didn't already close the connection - if(previousSocket.destroyed) { return; } + if (previousSocket.destroyed) { + return; + } timeout = undefined; - const tmrErr = new ConnectionTimeout(timeoutWait, 'TLS Negotiation') + const tmrErr = new ConnectionTimeout( + timeoutWait, + "TLS Negotiation", + ); previousSocket.destroy(tmrErr); reject(tmrErr); }, timeoutWait); let tlsSock: tls.TLSSocket; const clearTimer = (connected) => { return () => { - if(timeout) { + if (timeout) { clearTimeout(timeout); timeout = undefined; resolve(connected); } - tlsSock.off('close', clearTimerBad); - } - } + tlsSock.off("close", clearTimerBad); + }; + }; const clearTimerGood = clearTimer(true); const clearTimerBad = clearTimer(false); diff --git a/src/connection/queue.ts b/src/connection/queue.ts index 7c0e90af..f6f6d3d1 100644 --- a/src/connection/queue.ts +++ b/src/connection/queue.ts @@ -155,6 +155,7 @@ export default class CommandQueue extends TypedEmitter { ); // remove it once the queue is idle q.once("idle", () => this.removeQueueContext(q)); + this.queueContexts.push(q); return q; } diff --git a/src/index.ts b/src/index.ts index a8d6504e..e9f9711b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ -import Connection from "./connection"; - -export * from "./connection"; -export default Connection; -export * as Parser from "./parser"; +export { default as Connection } from "./connection"; +export * from "./errors"; +export { default as Parser } from "./parser"; +export { default as Session } from "./session"; +export { IMAPConfiguration } from "./types"; diff --git a/src/imap.ts b/src/session.ts similarity index 77% rename from src/imap.ts rename to src/session.ts index 6489f8cf..f66f6665 100644 --- a/src/imap.ts +++ b/src/session.ts @@ -1,10 +1,9 @@ import {CapabilityCommand, IdCommand, IdResponseMap} from "./commands"; import Connection from "./connection"; -import { IMAPError } from "./errors"; -import { type CapabilityList } from "./parser"; -import { IMAPLogMessage, type IMAPConfiguration } from "./types"; +import { CapabilityList } from "./parser"; +import { IMAPLogMessage, IMAPConfiguration } from "./types"; -class IMAPSession { +export default class Session { protected authed: boolean; protected capabilityList: CapabilityList; protected connection: Connection; @@ -36,13 +35,13 @@ class IMAPSession { public async start() { if (this.started) { - return true; + return this.connection.isActive; } this.started = true; - + try { await this.connection.connect(); - + // Get server information and capabilities to start with since // that information will really always be helpful. Surround in // a try/catch because if the server doesn't support this, it @@ -50,12 +49,16 @@ class IMAPSession { const capsCmd = new CapabilityCommand(); this.capabilityList = await this.connection.runCommand(capsCmd); - const idCmd = new IdCommand(this.options.id); - this.serverInfo = await this.connection.runCommand(idCmd); - } catch(error) { + if (this.capabilityList.has("ID")) { + const idCmd = new IdCommand(this.options.id); + this.serverInfo = await this.connection.runCommand(idCmd); + } else { + this.serverInfo = new Map(); + } + } catch (error) { // Try and destroy the connection - try{ - this.connection.destroy(); + try { + this.connection.disconnect(); } catch (_) {} // Log the error this.logger({ @@ -78,6 +81,6 @@ class IMAPSession { this.started = false; this.authed = false; this.capabilityList = null; - this.connection.end(); + this.connection.disconnect(); } } diff --git a/src/types.ts b/src/types.ts index f35106bf..94fa12ff 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,5 @@ -import { type IMAPConnectionConfiguration } from "./connection/types"; -import { type IdCommandValues } from "./commands"; +import type { IMAPConnectionConfiguration } from "./connection/types"; +import type { IdCommandValues } from "./commands"; export type IMAPLogMessage = | { From 4899bda6e929a742ac4ba83c862df47c0b862c47 Mon Sep 17 00:00:00 2001 From: Alexis Hushbeck Date: Wed, 6 Jul 2022 09:44:59 -0700 Subject: [PATCH 06/10] =?UTF-8?q?=F0=9F=8F=B7=20Make=20Command=20Tag=20Gen?= =?UTF-8?q?eration=20More=20Robust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of just using A0, A1, etc. we want to use A1, B1, etc. This us to send *a lot* more commands before we reuse tags --- src/commands/base.ts | 43 +++++++++++++++++++++++++++------- src/parser/parser.ts | 4 ++-- src/parser/structure/tag.ts | 6 ++--- src/parser/structure/tagged.ts | 2 ++ 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/commands/base.ts b/src/commands/base.ts index f2f47e9d..aa997ba2 100644 --- a/src/commands/base.ts +++ b/src/commands/base.ts @@ -47,10 +47,37 @@ export type StandardResponseTypes = | TaggedResponse | UntaggedResponse; -let NEXT_COMMAND_ID = 1; +const MAX_TAG_ALPHA_LENGTH = 400; + +function* commandIdGenerator(): Generator { + const alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); + let alphaCount = 0; + do { + let lead = ""; + let toAddCount = alphaCount; + while (toAddCount >= 0) { + lead += alpha[toAddCount % alpha.length]; + toAddCount -= alpha.length; + } + + for (let num = 1; num < Number.MAX_SAFE_INTEGER; num++) { + yield `${lead}${num.toString().padStart(5, "0")}`; + } + + if (alphaCount >= MAX_TAG_ALPHA_LENGTH * 26) { + // We've sent more commands than is resonable already, but + // start over just in case. Are we approaching heat-death + // of the universe yet? + alphaCount = 0; + } + } while (++alphaCount < Number.MAX_SAFE_INTEGER); + throw new Error("How did you even get here?!?!"); +} + +const CommandId = commandIdGenerator(); export abstract class Command extends EventEmitter { - public readonly id: number; + public readonly id: string; protected readonly commandPromise: Promise; @@ -59,11 +86,7 @@ export abstract class Command extends EventEmitter { public readonly requiresOwnContext: boolean = false, ) { super(); - this.id = NEXT_COMMAND_ID++; - // Reset our ID count if we go over max safe integer - if (NEXT_COMMAND_ID === Number.MAX_SAFE_INTEGER) { - NEXT_COMMAND_ID = 1; - } + this.id = CommandId.next().value; this.commandPromise = new Promise(this.executor); } @@ -129,7 +152,9 @@ export abstract class Command extends EventEmitter { return this.commandPromise; } - protected parseNonOKResponse(responses: StandardResponseTypes[]): any { + protected parseNonOKResponse( + responses: StandardResponseTypes[], + ): IMAPError { const taggedResponse = responses[responses.length - 1]; if (taggedResponse && taggedResponse instanceof TaggedResponse) { @@ -152,6 +177,6 @@ export abstract class Command extends EventEmitter { } public getFullAnnotatedCommand() { - return `A${this.id.toString().padStart(5, "0")} ${this.getCommand()}`; + return `${this.id} ${this.getCommand()}`; } } diff --git a/src/parser/parser.ts b/src/parser/parser.ts index d44f0dcb..2e9ea4c3 100644 --- a/src/parser/parser.ts +++ b/src/parser/parser.ts @@ -2,7 +2,7 @@ import { Transform } from "stream"; import { LexerTokenList, TokenTypes } from "../lexer/types"; import ContinueResponse from "./structure/continue"; -import TaggedResponse from "./structure/tagged"; +import TaggedResponse, { RE_TAG_MATCH } from "./structure/tagged"; import UnknownResponse from "./structure/unknown"; import UntaggedResponse from "./structure/untagged"; @@ -120,7 +120,7 @@ class Parser extends Transform { return new ContinueResponse(tokens); } else if ( firstToken.isType(TokenTypes.atom) && - firstToken.getTrueValue().match(/^A[0-9]+$/i) + firstToken.getTrueValue().match(RE_TAG_MATCH) ) { return new TaggedResponse(tokens); } else { diff --git a/src/parser/structure/tag.ts b/src/parser/structure/tag.ts index 2b57250c..e9c6fde6 100644 --- a/src/parser/structure/tag.ts +++ b/src/parser/structure/tag.ts @@ -1,9 +1,9 @@ import { ILexerToken, LexerTokenList, TokenTypes } from "../../lexer/types"; -const RE_TAG_MATCH = /^A[0-9]+$/i; +export const RE_TAG_MATCH = /^[A-Z]+[0-9]+$/i; export class Tag { - public readonly id: number; + public readonly id: string; public static match(tokens: LexerTokenList, startingIndex = 0): null | Tag { const token = tokens[startingIndex]; @@ -20,6 +20,6 @@ export class Tag { } constructor(token: ILexerToken) { - this.id = parseInt(token.getTrueValue().substr(1)); + this.id = token.getTrueValue(); } } diff --git a/src/parser/structure/tagged.ts b/src/parser/structure/tagged.ts index 36e9fce8..b4e9d61d 100644 --- a/src/parser/structure/tagged.ts +++ b/src/parser/structure/tagged.ts @@ -3,6 +3,8 @@ import { LexerTokenList } from "../../lexer/types"; import { StatusResponse } from "./status"; import { Tag } from "./tag"; +export { RE_TAG_MATCH } from "./tag"; + // From spec: // response-tagged = tag SP resp-cond-state CRLF export default class TaggedResponse { From a83270b2279d822ed0fcd3900c54704c390b194b Mon Sep 17 00:00:00 2001 From: Alexis Hushbeck Date: Mon, 11 Jul 2022 07:48:20 -0700 Subject: [PATCH 07/10] =?UTF-8?q?=F0=9F=8C=88=20E2E=20Baseline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Creating a baseline E2E suite that can be used to test compatibility against various servers. **Test plan:** yarn test:e2e --- package.json | 2 + src/session.ts | 5 + test/e2e/all.servers.ts | 34 + test/e2e/gmail.test.ts | 8 + test/e2e/icloud.test.ts | 8 + test/e2e/mail.com.test.ts | 8 + test/e2e/outlook.test.ts | 8 + test/e2e/yahoo.test.ts | 8 + yarn.lock | 2121 +++++++++++++++++++------------------ 9 files changed, 1162 insertions(+), 1040 deletions(-) create mode 100644 test/e2e/all.servers.ts create mode 100644 test/e2e/gmail.test.ts create mode 100644 test/e2e/icloud.test.ts create mode 100644 test/e2e/mail.com.test.ts create mode 100644 test/e2e/outlook.test.ts create mode 100644 test/e2e/yahoo.test.ts diff --git a/package.json b/package.json index 4a2844ca..067535b7 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "scripts": { "build": "tsc -d", "test": "jest", + "test:all": "test && test:e2e && test:old", + "test:e2e": "jest --testMatch=\"**/test/e2e/**/*.test.ts\"", "test:old": "node test/test.js" }, "engines": { diff --git a/src/session.ts b/src/session.ts index f66f6665..9c98c184 100644 --- a/src/session.ts +++ b/src/session.ts @@ -33,6 +33,10 @@ export default class Session { return this.capabilityList; } + public get server(): IdResponseMap { + return !this.serverInfo ? null : new Map(this.serverInfo); + } + public async start() { if (this.started) { return this.connection.isActive; @@ -81,6 +85,7 @@ export default class Session { this.started = false; this.authed = false; this.capabilityList = null; + this.serverInfo = null; this.connection.disconnect(); } } diff --git a/test/e2e/all.servers.ts b/test/e2e/all.servers.ts new file mode 100644 index 00000000..0b72f745 --- /dev/null +++ b/test/e2e/all.servers.ts @@ -0,0 +1,34 @@ +import { Session } from "../../src"; + +export const describeAllServers = (host: string, port: number) => { + let session: Session; + describe("Unauthenticated state", () => { + afterEach(async () => { + if (session) { + try { + await session.end(); + } catch (_) {} + session = undefined as any; + } + }); + + it("grabs server info and capabilities on connection and clears them after", async () => { + session = new Session({ + host, + port, + }); + expect(session.active).toBe(false); + expect(session.authenticated).toBe(false); + await session.start(); + expect(session.active).toBe(true); + expect(session.authenticated).toBe(false); + expect(session.capabilities?.capabilities).not.toHaveLength(0); + expect(session.server).toBeInstanceOf(Map); + await session.end(); + expect(session.active).toBe(false); + expect(session.authenticated).toBe(false); + expect(session.capabilities).toBeFalsy(); + expect(session.server).toBeFalsy(); + }); + }); +}; diff --git a/test/e2e/gmail.test.ts b/test/e2e/gmail.test.ts new file mode 100644 index 00000000..fa54c959 --- /dev/null +++ b/test/e2e/gmail.test.ts @@ -0,0 +1,8 @@ +import { describeAllServers } from "./all.servers"; + +const GMAIL_HOST = "imap.gmail.com"; +const PORT = 993; + +describe("Gmail", () => { + describeAllServers(GMAIL_HOST, PORT); +}); diff --git a/test/e2e/icloud.test.ts b/test/e2e/icloud.test.ts new file mode 100644 index 00000000..bd4fbe5e --- /dev/null +++ b/test/e2e/icloud.test.ts @@ -0,0 +1,8 @@ +import { describeAllServers } from "./all.servers"; + +const ICLOUD_HOST = "imap.mail.me.com"; +const PORT = 993; + +describe("iCloud", () => { + describeAllServers(ICLOUD_HOST, PORT); +}); diff --git a/test/e2e/mail.com.test.ts b/test/e2e/mail.com.test.ts new file mode 100644 index 00000000..ed4e2936 --- /dev/null +++ b/test/e2e/mail.com.test.ts @@ -0,0 +1,8 @@ +import { describeAllServers } from "./all.servers"; + +const MAIL_HOST = "imap.mail.com"; +const PORT = 993; + +describe("Mail.com", () => { + describeAllServers(MAIL_HOST, PORT); +}); diff --git a/test/e2e/outlook.test.ts b/test/e2e/outlook.test.ts new file mode 100644 index 00000000..3d5d02ee --- /dev/null +++ b/test/e2e/outlook.test.ts @@ -0,0 +1,8 @@ +import { describeAllServers } from "./all.servers"; + +const OUTLOOK_HOST = "outlook.office365.com"; +const PORT = 993; + +describe("Outlook", () => { + describeAllServers(OUTLOOK_HOST, PORT); +}); diff --git a/test/e2e/yahoo.test.ts b/test/e2e/yahoo.test.ts new file mode 100644 index 00000000..65be6555 --- /dev/null +++ b/test/e2e/yahoo.test.ts @@ -0,0 +1,8 @@ +import { describeAllServers } from "./all.servers"; + +const YAHOO_HOST = "imap.mail.yahoo.com"; +const PORT = 993; + +describe("Yahoo", () => { + describeAllServers(YAHOO_HOST, PORT); +}); diff --git a/yarn.lock b/yarn.lock index c15d1084..fa38690b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,14 @@ # yarn lockfile v1 +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -9,177 +17,150 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" - integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== - dependencies: - "@babel/highlight" "^7.14.5" - -"@babel/compat-data@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.5.tgz#8ef4c18e58e801c5c95d3c1c0f2874a2680fadea" - integrity sha512-kixrYn4JwfAVPa0f2yfzc2AWti6WRRyO3XjWW5PJAvtE11qhSayrrcrEnee05KAtNaPC+EwehE8Qt1UedEVB8w== - -"@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.5.tgz#d281f46a9905f07d1b3bf71ead54d9c7d89cb1e3" - integrity sha512-RN/AwP2DJmQTZSfiDaD+JQQ/J99KsIpOCfBE5pL+5jJSt7nI3nYGoAXZu+ffYSQ029NLs2DstZb+eR81uuARgg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.14.5" - "@babel/helper-compilation-targets" "^7.14.5" - "@babel/helper-module-transforms" "^7.14.5" - "@babel/helpers" "^7.14.5" - "@babel/parser" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/compat-data@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.6.tgz#8b37d24e88e8e21c499d4328db80577d8882fa53" + integrity sha512-tzulrgDT0QD6U7BJ4TKVk2SDDg7wlP39P9yAx1RfLy7vP/7rsDRlWVfbWxElslu56+r7QOhB2NSDsabYYruoZQ== + +"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.6.tgz#54a107a3c298aee3fe5e1947a6464b9b6faca03d" + integrity sha512-cQbWBpxcbbs/IUredIPkHiAGULLV8iwgNRMFzvbhEXISp4f3rUUXE5+TIw6KwUWUR3DwyI6gmBRnmAtYaWehwQ== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.6" + "@babel/helper-compilation-targets" "^7.18.6" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helpers" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.6" + "@babel/types" "^7.18.6" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.1.2" + json5 "^2.2.1" semver "^6.3.0" - source-map "^0.5.0" -"@babel/generator@^7.14.5", "@babel/generator@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785" - integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA== +"@babel/generator@^7.18.6", "@babel/generator@^7.7.2": + version "7.18.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.7.tgz#2aa78da3c05aadfc82dbac16c99552fc802284bd" + integrity sha512-shck+7VLlY72a2w9c3zYWuE1pwOKEiQHV7GTUbSnhyl5eu3i04t30tBY82ZRWrDfo3gkakCFtevExnxbkf2a3A== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.18.7" + "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" - source-map "^0.5.0" -"@babel/helper-compilation-targets@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz#7a99c5d0967911e972fe2c3411f7d5b498498ecf" - integrity sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw== +"@babel/helper-compilation-targets@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.6.tgz#18d35bfb9f83b1293c22c55b3d576c1315b6ed96" + integrity sha512-vFjbfhNCzqdeAtZflUFrG5YIFqGTqsctrtkZ1D/NB0mDW9TwW3GmmUepYY4G9wCET5rY5ugz4OGTcLd614IzQg== dependencies: - "@babel/compat-data" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - browserslist "^4.16.6" + "@babel/compat-data" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.20.2" semver "^6.3.0" -"@babel/helper-function-name@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4" - integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ== - dependencies: - "@babel/helper-get-function-arity" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-get-function-arity@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" - integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-hoist-variables@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" - integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-member-expression-to-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.5.tgz#d5c70e4ad13b402c95156c7a53568f504e2fb7b8" - integrity sha512-UxUeEYPrqH1Q/k0yRku1JE7dyfyehNwT6SVkMHvYvPDv4+uu627VXBckVj891BO8ruKBkiDoGnZf4qPDD8abDQ== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-module-imports@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" - integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-module-transforms@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz#7de42f10d789b423eb902ebd24031ca77cb1e10e" - integrity sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA== - dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" - "@babel/helper-simple-access" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/helper-validator-identifier" "^7.14.5" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-optimise-call-expression@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c" - integrity sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA== - dependencies: - "@babel/types" "^7.14.5" - -"@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.14.5", "@babel/helper-plugin-utils@^7.8.0": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" - integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== - -"@babel/helper-replace-supers@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz#0ecc0b03c41cd567b4024ea016134c28414abb94" - integrity sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.14.5" - "@babel/helper-optimise-call-expression" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/helper-simple-access@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz#66ea85cf53ba0b4e588ba77fc813f53abcaa41c4" - integrity sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-split-export-declaration@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a" - integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA== - dependencies: - "@babel/types" "^7.14.5" - -"@babel/helper-validator-identifier@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" - integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== - -"@babel/helper-validator-option@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" - integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== - -"@babel/helpers@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.5.tgz#4870f8d9a6fdbbd65e5674a3558b4ff7fef0d9b2" - integrity sha512-xtcWOuN9VL6nApgVHtq3PPcQv5qFBJzoSZzJ/2c0QK/IP/gxVcoWSNQwFEGvmbQsuS9rhYqjILDGGXcTkA705Q== - dependencies: - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.5" +"@babel/helper-environment-visitor@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.6.tgz#b7eee2b5b9d70602e59d1a6cad7dd24de7ca6cd7" + integrity sha512-8n6gSfn2baOY+qlp+VSzsosjCVGFqWKmDF0cCWOybh52Dw3SEyoWR1KrhMJASjLwIEkkAufZ0xvr+SxLHSpy2Q== + +"@babel/helper-function-name@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.6.tgz#8334fecb0afba66e6d87a7e8c6bb7fed79926b83" + integrity sha512-0mWMxV1aC97dhjCah5U5Ua7668r5ZmSC2DLfH2EZnf9c3/dHZKiFa5pRLMH5tjSl471tY6496ZWk/kjNONBxhw== + dependencies: + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-transforms@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.6.tgz#57e3ca669e273d55c3cda55e6ebf552f37f483c8" + integrity sha512-L//phhB4al5uucwzlimruukHB3jRd5JGClwRMD/ROrVjXfLqovYnvQrK/JK36WYyVwGGO7OD3kMyVTjx+WVPhw== + dependencies: + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.6" + "@babel/types" "^7.18.6" + +"@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.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.8.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.6.tgz#9448974dd4fb1d80fefe72e8a0af37809cd30d6d" + integrity sha512-gvZnm1YAAxh13eJdkb9EWHBnF3eAub3XTLCZEehHT2kWxiKVRL64+ae5Y6Ivne0mVHmMYKT+xWgZO+gQhuLUBg== + +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helpers@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.6.tgz#4c966140eaa1fcaa3d5a8c09d7db61077d4debfd" + integrity sha512-vzSiiqbQOghPngUYt/zWGvK3LAsPhz55vc9XNN0xAl2gV4ieShI2OQli5duxWHD+72PZPTKAcfcZDE1Cwc5zsQ== + dependencies: + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.5.tgz#4cd2f346261061b2518873ffecdf1612cb032829" - integrity sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.6.tgz#845338edecad65ebffef058d3be851f1d28a63bc" + integrity sha512-uQVSa9jJUe/G/304lXspfWVpKpK4euFLgGiMQFOCpM/bgcAdeoHwi/OQz23O9GK2osz26ZiXRRV9aV+Yl1O8tw== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -266,42 +247,43 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" - integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/template@^7.14.5", "@babel/template@^7.3.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" - integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.14.5" - "@babel/types" "^7.14.5" - -"@babel/traverse@^7.1.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.5.tgz#c111b0f58afab4fea3d3385a406f692748c59870" - integrity sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.14.5" - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-hoist-variables" "^7.14.5" - "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.14.5" - "@babel/types" "^7.14.5" + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" + integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/template@^7.18.6", "@babel/template@^7.3.3": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" + integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/traverse@^7.18.6", "@babel/traverse@^7.7.2": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.6.tgz#a228562d2f46e89258efa4ddd0416942e2fd671d" + integrity sha512-zS/OKyqmD7lslOtFqbscH6gMLFYOfG1YPqCKfAW5KrTeolKqvB8UelR49Fpr6y93kYkW2Ik00mT1LOGiAGvizw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-function-name" "^7.18.6" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/types" "^7.18.6" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.14.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff" - integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg== +"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.18.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.18.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.7.tgz#a4a2c910c15040ea52cdd1ddb1614a65c8041726" + integrity sha512-QG3yxTcTIBoAcQmkCs+wAPYZhu7Dk9rXKacINfNbdJDNERTbLQbHGyVG8q/YGMPeCJRIhSY0+fTc5+xuh6WPSQ== dependencies: - "@babel/helper-validator-identifier" "^7.14.5" + "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -309,10 +291,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@eslint/eslintrc@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179" - integrity sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg== +"@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== dependencies: ajv "^6.12.4" debug "^4.1.1" @@ -324,6 +306,20 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -340,160 +336,160 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.0.2.tgz#b8eeff8f21ac51d224c851e1729d2630c18631e6" - integrity sha512-/zYigssuHLImGeMAACkjI4VLAiiJznHgAl3xnFT19iWyct2LhrH3KXOjHRmxBGTkiPLZKKAJAgaPpiU9EZ9K+w== +"@jest/console@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" + integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.5.1" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^27.0.2" - jest-util "^27.0.2" + jest-message-util "^27.5.1" + jest-util "^27.5.1" slash "^3.0.0" -"@jest/core@^27.0.4": - version "27.0.4" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.4.tgz#679bf9ac07900da2ddbb9667bb1afa8029038f53" - integrity sha512-+dsmV8VUs1h/Szb+rEWk8xBM1fp1I///uFy9nk3wXGvRsF2lBp8EVPmtWc+QFRb3MY2b7u2HbkGF1fzoDzQTLA== +"@jest/core@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" + integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== dependencies: - "@jest/console" "^27.0.2" - "@jest/reporters" "^27.0.4" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/console" "^27.5.1" + "@jest/reporters" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.8.1" exit "^0.1.2" - graceful-fs "^4.2.4" - jest-changed-files "^27.0.2" - jest-config "^27.0.4" - jest-haste-map "^27.0.2" - jest-message-util "^27.0.2" - jest-regex-util "^27.0.1" - jest-resolve "^27.0.4" - jest-resolve-dependencies "^27.0.4" - jest-runner "^27.0.4" - jest-runtime "^27.0.4" - jest-snapshot "^27.0.4" - jest-util "^27.0.2" - jest-validate "^27.0.2" - jest-watcher "^27.0.2" + graceful-fs "^4.2.9" + jest-changed-files "^27.5.1" + jest-config "^27.5.1" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-resolve-dependencies "^27.5.1" + jest-runner "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + jest-watcher "^27.5.1" micromatch "^4.0.4" - p-each-series "^2.1.0" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^27.0.3": - version "27.0.3" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.0.3.tgz#68769b1dfdd213e3456169d64fbe9bd63a5fda92" - integrity sha512-pN9m7fbKsop5vc3FOfH8NF7CKKdRbEZzcxfIo1n2TT6ucKWLFq0P6gCJH0GpnQp036++yY9utHOxpeT1WnkWTA== +"@jest/environment@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== dependencies: - "@jest/fake-timers" "^27.0.3" - "@jest/types" "^27.0.2" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" - jest-mock "^27.0.3" + jest-mock "^27.5.1" -"@jest/fake-timers@^27.0.3": - version "27.0.3" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.0.3.tgz#9899ba6304cc636734c74478df502e18136461dd" - integrity sha512-fQ+UCKRIYKvTCEOyKPnaPnomLATIhMnHC/xPZ7yT1Uldp7yMgMxoYIFidDbpSTgB79+/U+FgfoD30c6wg3IUjA== +"@jest/fake-timers@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== dependencies: - "@jest/types" "^27.0.2" - "@sinonjs/fake-timers" "^7.0.2" + "@jest/types" "^27.5.1" + "@sinonjs/fake-timers" "^8.0.1" "@types/node" "*" - jest-message-util "^27.0.2" - jest-mock "^27.0.3" - jest-util "^27.0.2" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" -"@jest/globals@^27.0.3": - version "27.0.3" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.0.3.tgz#1cf8933b7791bba0b99305cbf39fd4d2e3fe4060" - integrity sha512-OzsIuf7uf+QalqAGbjClyezzEcLQkdZ+7PejUrZgDs+okdAK8GwRCGcYCirHvhMBBQh60Jr3NlIGbn/KBPQLEQ== +"@jest/globals@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== dependencies: - "@jest/environment" "^27.0.3" - "@jest/types" "^27.0.2" - expect "^27.0.2" + "@jest/environment" "^27.5.1" + "@jest/types" "^27.5.1" + expect "^27.5.1" -"@jest/reporters@^27.0.4": - version "27.0.4" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.0.4.tgz#95609b1be97afb80d55d8aa3d7c3179c15810e65" - integrity sha512-Xa90Nm3JnV0xCe4M6A10M9WuN9krb+WFKxV1A98Y4ePCw40n++r7uxFUNU7DT1i9Behj7fjrAIju9oU0t1QtCg== +"@jest/reporters@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" + integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.0.2" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/console" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.2" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^4.0.3" + istanbul-lib-instrument "^5.1.0" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.2" - jest-haste-map "^27.0.2" - jest-resolve "^27.0.4" - jest-util "^27.0.2" - jest-worker "^27.0.2" + istanbul-reports "^3.1.3" + jest-haste-map "^27.5.1" + jest-resolve "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" slash "^3.0.0" source-map "^0.6.0" string-length "^4.0.1" terminal-link "^2.0.0" - v8-to-istanbul "^7.0.0" + v8-to-istanbul "^8.1.0" -"@jest/source-map@^27.0.1": - version "27.0.1" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.1.tgz#2afbf73ddbaddcb920a8e62d0238a0a9e0a8d3e4" - integrity sha512-yMgkF0f+6WJtDMdDYNavmqvbHtiSpwRN2U/W+6uztgfqgkq/PXdKPqjBTUF1RD/feth4rH5N3NW0T5+wIuln1A== +"@jest/source-map@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" + integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== dependencies: callsites "^3.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" source-map "^0.6.0" -"@jest/test-result@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.0.2.tgz#0451049e32ceb609b636004ccc27c8fa22263f10" - integrity sha512-gcdWwL3yP5VaIadzwQtbZyZMgpmes8ryBAJp70tuxghiA8qL4imJyZex+i+USQH2H4jeLVVszhwntgdQ97fccA== +"@jest/test-result@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" + integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== dependencies: - "@jest/console" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/console" "^27.5.1" + "@jest/types" "^27.5.1" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^27.0.4": - version "27.0.4" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.4.tgz#976493b277594d81e589896f0ed21f198308928a" - integrity sha512-6UFEVwdmxYdyNffBxVVZxmXEdBE4riSddXYSnFNH0ELFQFk/bvagizim8WfgJTqF4EKd+j1yFxvhb8BMHfOjSQ== +"@jest/test-sequencer@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" + integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== dependencies: - "@jest/test-result" "^27.0.2" - graceful-fs "^4.2.4" - jest-haste-map "^27.0.2" - jest-runtime "^27.0.4" + "@jest/test-result" "^27.5.1" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-runtime "^27.5.1" -"@jest/transform@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.2.tgz#b073b7c589e3f4b842102468875def2bb722d6b5" - integrity sha512-H8sqKlgtDfVog/s9I4GG2XMbi4Ar7RBxjsKQDUhn2XHAi3NG+GoQwWMER+YfantzExbjNqQvqBHzo/G2pfTiPw== +"@jest/transform@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^27.0.2" - babel-plugin-istanbul "^6.0.0" + "@jest/types" "^27.5.1" + babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^27.0.2" - jest-regex-util "^27.0.1" - jest-util "^27.0.2" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-regex-util "^27.5.1" + jest-util "^27.5.1" micromatch "^4.0.4" - pirates "^4.0.1" + pirates "^4.0.4" slash "^3.0.0" source-map "^0.6.1" write-file-atomic "^3.0.0" @@ -509,10 +505,10 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@jest/types@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.2.tgz#e153d6c46bda0f2589f0702b071f9898c7bbd37e" - integrity sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg== +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" @@ -520,6 +516,46 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -534,9 +570,9 @@ integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": - version "1.2.7" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz#94c23db18ee4653e129abd26fb06f870ac9e1ee2" - integrity sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA== + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" @@ -548,10 +584,10 @@ dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^7.0.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" - integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== dependencies: "@sinonjs/commons" "^1.7.0" @@ -561,9 +597,9 @@ integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.1.14" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402" - integrity sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g== + version "7.1.19" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" + integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -572,24 +608,24 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.2.tgz#f3d71178e187858f7c45e30380f8f1b7415a12d8" - integrity sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ== + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.0.tgz#0c888dd70b3ee9eebb6e4f200e809da0076262be" - integrity sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A== + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" - integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== + version "7.17.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.1.tgz#1a0e73e8c28c7e832656db372b779bfd2ef37314" + integrity sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA== dependencies: "@babel/types" "^7.3.0" @@ -601,9 +637,9 @@ "@types/node" "*" "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" - integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== "@types/istanbul-lib-report@*": version "3.0.0" @@ -620,131 +656,131 @@ "@types/istanbul-lib-report" "*" "@types/jest@^26.0.23": - version "26.0.23" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.23.tgz#a1b7eab3c503b80451d019efb588ec63522ee4e7" - integrity sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA== + version "26.0.24" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" + integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== dependencies: jest-diff "^26.0.0" pretty-format "^26.0.0" "@types/json-schema@^7.0.7": - version "7.0.7" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" - integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== "@types/node@*": - version "15.12.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d" - integrity sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww== + version "18.0.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.3.tgz#463fc47f13ec0688a33aec75d078a0541a447199" + integrity sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ== "@types/node@^12.7.12": - version "12.20.15" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.15.tgz#10ee6a6a3f971966fddfa3f6e89ef7a73ec622df" - integrity sha512-F6S4Chv4JicJmyrwlDkxUdGNSplsQdGwp1A0AJloEVDirWdZOAiRHhovDlsFkKUrquUXhz1imJhXHsf59auyAg== + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== "@types/prettier@^2.1.5": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.0.tgz#2e8332cc7363f887d32ec5496b207d26ba8052bb" - integrity sha512-hkc1DATxFLQo4VxPDpMH1gCkPpBbpOoJ/4nhuXw4n63/0R6bCpQECj4+K226UJ4JO/eJQz+1mC2I7JsWanAdQw== + version "2.6.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.3.tgz#68ada76827b0010d0db071f739314fa429943d0a" + integrity sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg== "@types/stack-utils@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" - integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== "@types/yargs-parser@*": - version "20.2.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" - integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^15.0.0": - version "15.0.13" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" - integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== + version "15.0.14" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" + integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== dependencies: "@types/yargs-parser" "*" "@types/yargs@^16.0.0": - version "16.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.3.tgz#4b6d35bb8e680510a7dc2308518a80ee1ef27e01" - integrity sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ== + version "16.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^4.26.0": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz#b9c7313321cb837e2bf8bebe7acc2220659e67d3" - integrity sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw== + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" + integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg== dependencies: - "@typescript-eslint/experimental-utils" "4.26.1" - "@typescript-eslint/scope-manager" "4.26.1" + "@typescript-eslint/experimental-utils" "4.33.0" + "@typescript-eslint/scope-manager" "4.33.0" debug "^4.3.1" functional-red-black-tree "^1.0.1" - lodash "^4.17.21" + ignore "^5.1.8" regexpp "^3.1.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz#a35980a2390da9232aa206b27f620eab66e94142" - integrity sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ== +"@typescript-eslint/experimental-utils@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" + integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q== dependencies: "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.26.1" - "@typescript-eslint/types" "4.26.1" - "@typescript-eslint/typescript-estree" "4.26.1" + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" "@typescript-eslint/parser@^4.26.0": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.26.1.tgz#cecfdd5eb7a5c13aabce1c1cfd7fbafb5a0f1e8e" - integrity sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ== + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" + integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA== dependencies: - "@typescript-eslint/scope-manager" "4.26.1" - "@typescript-eslint/types" "4.26.1" - "@typescript-eslint/typescript-estree" "4.26.1" + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz#075a74a15ff33ee3a7ed33e5fce16ee86689f662" - integrity sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ== +"@typescript-eslint/scope-manager@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" + integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ== dependencies: - "@typescript-eslint/types" "4.26.1" - "@typescript-eslint/visitor-keys" "4.26.1" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" -"@typescript-eslint/types@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.26.1.tgz#9e7c523f73c34b04a765e4167ca5650436ef1d38" - integrity sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg== +"@typescript-eslint/types@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" + integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== -"@typescript-eslint/typescript-estree@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz#b2ce2e789233d62283fae2c16baabd4f1dbc9633" - integrity sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg== +"@typescript-eslint/typescript-estree@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" + integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA== dependencies: - "@typescript-eslint/types" "4.26.1" - "@typescript-eslint/visitor-keys" "4.26.1" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" debug "^4.3.1" globby "^11.0.3" is-glob "^4.0.1" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz#0d55ea735cb0d8903b198017d6d4f518fdaac546" - integrity sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw== +"@typescript-eslint/visitor-keys@4.33.0": + version "4.33.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" + integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg== dependencies: - "@typescript-eslint/types" "4.26.1" + "@typescript-eslint/types" "4.33.0" eslint-visitor-keys "^2.0.0" 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== + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== acorn-globals@^6.0.0: version "6.0.0" @@ -755,9 +791,9 @@ acorn-globals@^6.0.0: acorn-walk "^7.1.1" acorn-jsx@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^7.1.1: version "7.2.0" @@ -770,9 +806,9 @@ acorn@^7.1.1, acorn@^7.4.0: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.2.4: - version "8.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.0.tgz#af53266e698d7cffa416714b503066a82221be60" - integrity sha512-ULr0LDaEqQrMFGyQ3bhJkLsbtrQ8QibAseGZeaSUiT/6zb9IvIkomWHJIvgvwad+hinRAgsI51JcWk2yvwyL+w== + version "8.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" + integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== agent-base@6: version "6.0.2" @@ -792,9 +828,9 @@ ajv@^6.10.0, ajv@^6.12.4: uri-js "^4.2.2" ajv@^8.0.1: - version "8.6.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.0.tgz#60cc45d9c46a477d80d92c48076d972c342e5720" - integrity sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ== + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -802,9 +838,9 @@ ajv@^8.0.1: uri-js "^4.2.2" ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== ansi-escapes@^4.2.1: version "4.3.2" @@ -813,10 +849,10 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.21.3" -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.0, ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^3.2.1: version "3.2.1" @@ -865,37 +901,37 @@ astral-regex@^2.0.0: asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -babel-jest@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.2.tgz#7dc18adb01322acce62c2af76ea2c7cd186ade37" - integrity sha512-9OThPl3/IQbo4Yul2vMz4FYwILPQak8XelX4YGowygfHaOl5R5gfjm4iVx4d8aUugkW683t8aq0A74E7b5DU1Q== +babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== dependencies: - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^27.0.1" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" slash "^3.0.0" -babel-plugin-istanbul@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" - integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@istanbuljs/load-nyc-config" "^1.0.0" "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^4.0.0" + istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.1.tgz#a6d10e484c93abff0f4e95f437dad26e5736ea11" - integrity sha512-sqBF0owAcCDBVEDtxqfYr2F36eSHdx7lAVGyYuOBRnKdD6gzcy0I0XrAYCZgOA3CRrLhmR+Uae9nogPzmAtOfQ== +babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -920,12 +956,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.1.tgz#7a50c75d16647c23a2cf5158d5bb9eb206b10e20" - integrity sha512-nIBIqCEpuiyhvjQs2mVNwTxQQa2xk70p9Dd/0obQGBf8FBzbnI8QhQKzLsWMN2i6q+5B0OcWDtrboBX5gmOLyA== +babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== dependencies: - babel-plugin-jest-hoist "^27.0.1" + babel-plugin-jest-hoist "^27.5.1" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -941,7 +977,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.1: +braces@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -953,16 +989,15 @@ 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.16.6: - version "4.16.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" - integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== +browserslist@^4.20.2: + version "4.21.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.1.tgz#c9b9b0a54c7607e8dc3e01a0d311727188011a00" + integrity sha512-Nq8MFCSrnJXSc88yliwlzQe3qNe3VntIjhsArW9IJOEPSHNx23FalwApUVbzAWABLhYJJ7y8AynWI/XM8OdfjQ== dependencies: - caniuse-lite "^1.0.30001219" - colorette "^1.2.2" - electron-to-chromium "^1.3.723" - escalade "^3.1.1" - node-releases "^1.1.71" + caniuse-lite "^1.0.30001359" + electron-to-chromium "^1.4.172" + node-releases "^2.0.5" + update-browserslist-db "^1.0.4" bs-logger@0.x: version "0.2.6" @@ -978,10 +1013,10 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-from@1.x, buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== callsites@^3.0.0: version "3.1.0" @@ -994,14 +1029,14 @@ camelcase@^5.3.1: integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== camelcase@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001219: - version "1.0.30001237" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001237.tgz#4b7783661515b8e7151fc6376cfd97f0e427b9e5" - integrity sha512-pDHgRndit6p1NR2GhzMbQ6CkRrp4VKuSsqbcLeOQppYPKOYkKT/6ZvZDvKJUqcmtyWIAHuZq3SVS2vc1egCZzw== +caniuse-lite@^1.0.30001359: + version "1.0.30001363" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001363.tgz#26bec2d606924ba318235944e1193304ea7c4f15" + integrity sha512-HpQhpzTGGPVMnCjIomjt+jvyUu8vNFo3TaDiZ/RcoTrlOq/5+tC8zHdsbgFB6MxmaY+jCpsH09aD80Bb4Ow3Sg== chalk@^2.0.0: version "2.4.2" @@ -1013,9 +1048,9 @@ chalk@^2.0.0: supports-color "^5.3.0" chalk@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" @@ -1025,15 +1060,15 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -ci-info@^3.1.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" - integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A== +ci-info@^3.2.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128" + integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg== cjs-module-lexer@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz#2fd46d9906a126965aa541345c499aaa18e8cd73" - integrity sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw== + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== cliui@^7.0.2: version "7.0.4" @@ -1047,7 +1082,7 @@ cliui@^7.0.2: co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== collect-v8-coverage@^1.0.0: version "1.0.1" @@ -1071,18 +1106,13 @@ color-convert@^2.0.1: color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== color-name@~1.1.4: version "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.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" - integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== - combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -1093,12 +1123,12 @@ combined-stream@^1.0.8: concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" @@ -1138,26 +1168,26 @@ data-urls@^2.0.0: whatwg-url "^8.0.0" debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" 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== + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.2.2: version "4.2.2" @@ -1167,7 +1197,7 @@ deepmerge@^4.2.2: delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== detect-newline@^3.0.0: version "3.1.0" @@ -1179,10 +1209,10 @@ diff-sequences@^26.6.2: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== -diff-sequences@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.1.tgz#9c9801d52ed5f576ff0a20e3022a13ee6e297e7c" - integrity sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg== +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== dir-glob@^3.0.1: version "3.0.1" @@ -1205,10 +1235,10 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" -electron-to-chromium@^1.3.723: - version "1.3.752" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz#0728587f1b9b970ec9ffad932496429aef750d09" - integrity sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A== +electron-to-chromium@^1.4.172: + version "1.4.180" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.180.tgz#380b06037836055d12c7de181ee90b8ed911c3e7" + integrity sha512-7at5ash3FD9U5gPa3/wPr6OdiZd/zBjvDZaaHBpcqFOFUhZiWnb7stkqk8xUFL9H9nk7Yok5vCCNK8wyC/+f8A== emittery@^0.8.1: version "0.8.1" @@ -1227,6 +1257,13 @@ enquirer@^2.3.5: dependencies: ansi-colors "^4.1.1" +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -1235,7 +1272,7 @@ escalade@^3.1.1: escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== escape-string-regexp@^2.0.0: version "2.0.0" @@ -1260,9 +1297,9 @@ escodegen@^2.0.0: source-map "~0.6.1" eslint-config-prettier@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" - integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== + version "8.5.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== eslint-scope@^5.1.1: version "5.1.1" @@ -1297,12 +1334,13 @@ eslint-visitor-keys@^2.0.0: integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== eslint@^7.28.0: - version "7.28.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.28.0.tgz#435aa17a0b82c13bb2be9d51408b617e49c1e820" - integrity sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g== + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== dependencies: "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.2" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -1375,9 +1413,9 @@ estraverse@^4.1.1: integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" @@ -1402,36 +1440,33 @@ execa@^5.0.0: exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== -expect@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.2.tgz#e66ca3a4c9592f1c019fa1d46459a9d2084f3422" - integrity sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w== +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== dependencies: - "@jest/types" "^27.0.2" - ansi-styles "^5.0.0" - jest-get-type "^27.0.1" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-regex-util "^27.0.1" + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.1.1: - version "3.2.5" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" - integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== +fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" + glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" + micromatch "^4.0.4" fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -1441,12 +1476,12 @@ fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" - integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify "^1.0.4" @@ -1488,9 +1523,9 @@ flat-cache@^3.0.4: rimraf "^3.0.2" flatted@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" - integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== + version "3.2.6" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" + integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== form-data@^3.0.0: version "3.0.1" @@ -1504,7 +1539,7 @@ form-data@^3.0.0: fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@^2.3.2: version "2.3.2" @@ -1519,7 +1554,7 @@ function-bind@^1.1.1: functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== gensync@^1.0.0-beta.2: version "1.0.0-beta.2" @@ -1541,7 +1576,7 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -glob-parent@^5.1.0, glob-parent@^5.1.2: +glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -1549,14 +1584,14 @@ glob-parent@^5.1.0, glob-parent@^5.1.2: is-glob "^4.0.1" glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.4" + minimatch "^3.1.1" once "^1.3.0" path-is-absolute "^1.0.0" @@ -1566,33 +1601,33 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.6.0, globals@^13.9.0: - version "13.9.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" - integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== + version "13.16.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.16.0.tgz#9be4aca28f311aaeb974ea54978ebbb5e35ce46a" + integrity sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q== dependencies: type-fest "^0.20.2" globby@^11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" - integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" slash "^3.0.0" -graceful-fs@^4.2.4: - version "4.2.6" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" - integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== +graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" @@ -1628,9 +1663,9 @@ http-proxy-agent@^4.0.1: debug "4" https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: agent-base "6" debug "4" @@ -1652,10 +1687,10 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.1.8, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" @@ -1666,9 +1701,9 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: resolve-from "^4.0.0" import-local@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" - integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== dependencies: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" @@ -1676,12 +1711,12 @@ import-local@^3.0.2: imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" @@ -1691,24 +1726,22 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -is-ci@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" - integrity sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ== - dependencies: - ci-info "^3.1.1" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== -is-core-module@^2.2.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" - integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== +is-core-module@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== dependencies: has "^1.0.3" is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" @@ -1721,9 +1754,9 @@ is-generator-fn@^2.0.0: integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== is-glob@^4.0.0, is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" @@ -1738,33 +1771,34 @@ is-potential-custom-element-name@^1.0.1: integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== is-stream@^2.0.0: - version "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== + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -istanbul-lib-coverage@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" - integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== dependencies: - "@babel/core" "^7.7.5" + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" + istanbul-lib-coverage "^3.2.0" semver "^6.3.0" istanbul-lib-report@^3.0.0: @@ -1777,100 +1811,103 @@ istanbul-lib-report@^3.0.0: supports-color "^7.1.0" istanbul-lib-source-maps@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" - integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: debug "^4.1.1" istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" - integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== +istanbul-reports@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.0.2.tgz#997253042b4a032950fc5f56abf3c5d1f8560801" - integrity sha512-eMeb1Pn7w7x3wue5/vF73LPCJ7DKQuC9wQUR5ebP9hDPpk5hzcT/3Hmz3Q5BOFpR3tgbmaWhJcMTVgC8Z1NuMw== +jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.5.1" execa "^5.0.0" throat "^6.0.1" -jest-circus@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.0.4.tgz#3b261514ee3b3da33def736a6352c98ff56bb6e6" - integrity sha512-QD+eblDiRphta630WRKewuASLs/oY1Zki2G4bccntRvrTHQ63ljwFR5TLduuK4Zg0ZPzW0+8o6AP7KRd1yKOjw== +jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== dependencies: - "@jest/environment" "^27.0.3" - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" - expect "^27.0.2" + expect "^27.5.1" is-generator-fn "^2.0.0" - jest-each "^27.0.2" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-runtime "^27.0.4" - jest-snapshot "^27.0.4" - jest-util "^27.0.2" - pretty-format "^27.0.2" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" slash "^3.0.0" stack-utils "^2.0.3" throat "^6.0.1" -jest-cli@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.0.4.tgz#491b12c754c0d7c6873b13a66f26b3a80a852910" - integrity sha512-E0T+/i2lxsWAzV7LKYd0SB7HUAvePqaeIh5vX43/G5jXLhv1VzjYzJAGEkTfvxV774ll9cyE2ljcL73PVMEOXQ== +jest-cli@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== dependencies: - "@jest/core" "^27.0.4" - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" chalk "^4.0.0" exit "^0.1.2" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^27.0.4" - jest-util "^27.0.2" - jest-validate "^27.0.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" prompts "^2.0.1" - yargs "^16.0.3" + yargs "^16.2.0" -jest-config@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.0.4.tgz#c4f41378acf40ca77860fb4e213b12109d87b8cf" - integrity sha512-VkQFAHWnPQefdvHU9A+G3H/Z3NrrTKqWpvxgQz3nkUdkDTWeKJE6e//BL+R7z79dXOMVksYgM/z6ndtN0hfChg== +jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^27.0.4" - "@jest/types" "^27.0.2" - babel-jest "^27.0.2" + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" chalk "^4.0.0" + ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.1" - graceful-fs "^4.2.4" - is-ci "^3.0.0" - jest-circus "^27.0.4" - jest-environment-jsdom "^27.0.3" - jest-environment-node "^27.0.3" - jest-get-type "^27.0.1" - jest-jasmine2 "^27.0.4" - jest-regex-util "^27.0.1" - jest-resolve "^27.0.4" - jest-runner "^27.0.4" - jest-util "^27.0.2" - jest-validate "^27.0.2" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" micromatch "^4.0.4" - pretty-format "^27.0.2" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" jest-diff@^26.0.0: version "26.6.2" @@ -1882,152 +1919,151 @@ jest-diff@^26.0.0: jest-get-type "^26.3.0" pretty-format "^26.6.2" -jest-diff@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.2.tgz#f315b87cee5dc134cf42c2708ab27375cc3f5a7e" - integrity sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw== +jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== dependencies: chalk "^4.0.0" - diff-sequences "^27.0.1" - jest-get-type "^27.0.1" - pretty-format "^27.0.2" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" -jest-docblock@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.1.tgz#bd9752819b49fa4fab1a50b73eb58c653b962e8b" - integrity sha512-TA4+21s3oebURc7VgFV4r7ltdIJ5rtBH1E3Tbovcg7AV+oLfD5DcJ2V2vJ5zFA9sL5CFd/d2D6IpsAeSheEdrA== +jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== dependencies: detect-newline "^3.0.0" -jest-each@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.0.2.tgz#865ddb4367476ced752167926b656fa0dcecd8c7" - integrity sha512-OLMBZBZ6JkoXgUenDtseFRWA43wVl2BwmZYIWQws7eS7pqsIvePqj/jJmEnfq91ALk3LNphgwNK/PRFBYi7ITQ== +jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.5.1" chalk "^4.0.0" - jest-get-type "^27.0.1" - jest-util "^27.0.2" - pretty-format "^27.0.2" - -jest-environment-jsdom@^27.0.3: - version "27.0.3" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.0.3.tgz#ed73e913ddc03864eb9f934b5cbabf1b63504e2e" - integrity sha512-5KLmgv1bhiimpSA8oGTnZYk6g4fsNyZiA/6gI2tAZUgrufd7heRUSVh4gRokzZVEj8zlwAQYT0Zs6tuJSW/ECA== - dependencies: - "@jest/environment" "^27.0.3" - "@jest/fake-timers" "^27.0.3" - "@jest/types" "^27.0.2" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + +jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" - jest-mock "^27.0.3" - jest-util "^27.0.2" + jest-mock "^27.5.1" + jest-util "^27.5.1" jsdom "^16.6.0" -jest-environment-node@^27.0.3: - version "27.0.3" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.0.3.tgz#b4acb3679d2552a4215732cab8b0ca7ec4398ee0" - integrity sha512-co2/IVnIFL3cItpFULCvXFg9us4gvWXgs7mutAMPCbFhcqh56QAOdKhNzC2+RycsC/k4mbMj1VF+9F/NzA0ROg== +jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== dependencies: - "@jest/environment" "^27.0.3" - "@jest/fake-timers" "^27.0.3" - "@jest/types" "^27.0.2" + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" - jest-mock "^27.0.3" - jest-util "^27.0.2" + jest-mock "^27.5.1" + jest-util "^27.5.1" jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-get-type@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.1.tgz#34951e2b08c8801eb28559d7eb732b04bbcf7815" - integrity sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg== +jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== -jest-haste-map@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.0.2.tgz#3f1819400c671237e48b4d4b76a80a0dbed7577f" - integrity sha512-37gYfrYjjhEfk37C4bCMWAC0oPBxDpG0qpl8lYg8BT//wf353YT/fzgA7+Dq0EtM7rPFS3JEcMsxdtDwNMi2cA== +jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.5.1" "@types/graceful-fs" "^4.1.2" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^27.0.1" - jest-serializer "^27.0.1" - jest-util "^27.0.2" - jest-worker "^27.0.2" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" micromatch "^4.0.4" walker "^1.0.7" optionalDependencies: fsevents "^2.3.2" -jest-jasmine2@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.0.4.tgz#c669519ccf4904a485338555e1e66cad36bb0670" - integrity sha512-yj3WrjjquZwkJw+eA4c9yucHw4/+EHndHWSqgHbHGQfT94ihaaQsa009j1a0puU8CNxPDk0c1oAPeOpdJUElwA== +jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^27.0.3" - "@jest/source-map" "^27.0.1" - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - expect "^27.0.2" + expect "^27.5.1" is-generator-fn "^2.0.0" - jest-each "^27.0.2" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-runtime "^27.0.4" - jest-snapshot "^27.0.4" - jest-util "^27.0.2" - pretty-format "^27.0.2" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" throat "^6.0.1" -jest-leak-detector@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.0.2.tgz#ce19aa9dbcf7a72a9d58907a970427506f624e69" - integrity sha512-TZA3DmCOfe8YZFIMD1GxFqXUkQnIoOGQyy4hFCA2mlHtnAaf+FeOMxi0fZmfB41ZL+QbFG6BVaZF5IeFIVy53Q== +jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== dependencies: - jest-get-type "^27.0.1" - pretty-format "^27.0.2" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" -jest-matcher-utils@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz#f14c060605a95a466cdc759acc546c6f4cbfc4f0" - integrity sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA== +jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== dependencies: chalk "^4.0.0" - jest-diff "^27.0.2" - jest-get-type "^27.0.1" - pretty-format "^27.0.2" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" -jest-message-util@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.0.2.tgz#181c9b67dff504d8f4ad15cba10d8b80f272048c" - integrity sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw== +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.0.2" + "@jest/types" "^27.5.1" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^27.0.2" + pretty-format "^27.5.1" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^27.0.3: - version "27.0.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.0.3.tgz#5591844f9192b3335c0dca38e8e45ed297d4d23d" - integrity sha512-O5FZn5XDzEp+Xg28mUz4ovVcdwBBPfAhW9+zJLO0Efn2qNbYcDaJvSlRiQ6BCZUCVOJjALicuJQI9mRFjv1o9Q== +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.5.1" "@types/node" "*" jest-pnp-resolver@^1.2.2: @@ -2035,187 +2071,181 @@ jest-pnp-resolver@^1.2.2: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.1.tgz#69d4b1bf5b690faa3490113c47486ed85dd45b68" - integrity sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ== +jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== -jest-resolve-dependencies@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.4.tgz#a07a242d70d668afd3fcf7f4270755eebb1fe579" - integrity sha512-F33UPfw1YGWCV2uxJl7wD6TvcQn5IC0LtguwY3r4L7R6H4twpLkp5Q2ZfzRx9A2I3G8feiy0O0sqcn/Qoym71A== +jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== dependencies: - "@jest/types" "^27.0.2" - jest-regex-util "^27.0.1" - jest-snapshot "^27.0.4" + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" -jest-resolve@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.0.4.tgz#8a27bc3f2f00c8ea28f3bc99bbf6f468300a703d" - integrity sha512-BcfyK2i3cG79PDb/6gB6zFeFQlcqLsQjGBqznFCpA0L/3l1L/oOsltdUjs5eISAWA9HS9qtj8v2PSZr/yWxONQ== +jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.5.1" chalk "^4.0.0" - escalade "^3.1.1" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" jest-pnp-resolver "^1.2.2" - jest-util "^27.0.2" - jest-validate "^27.0.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" resolve "^1.20.0" + resolve.exports "^1.1.0" slash "^3.0.0" -jest-runner@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.0.4.tgz#2787170a9509b792ae129794f6944d27d5d12a4f" - integrity sha512-NfmvSYLCsCJk2AG8Ar2NAh4PhsJJpO+/r+g4bKR5L/5jFzx/indUpnVBdrfDvuqhGLLAvrKJ9FM/Nt8o1dsqxg== +jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== dependencies: - "@jest/console" "^27.0.2" - "@jest/environment" "^27.0.3" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" chalk "^4.0.0" emittery "^0.8.1" - exit "^0.1.2" - graceful-fs "^4.2.4" - jest-docblock "^27.0.1" - jest-environment-jsdom "^27.0.3" - jest-environment-node "^27.0.3" - jest-haste-map "^27.0.2" - jest-leak-detector "^27.0.2" - jest-message-util "^27.0.2" - jest-resolve "^27.0.4" - jest-runtime "^27.0.4" - jest-util "^27.0.2" - jest-worker "^27.0.2" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" source-map-support "^0.5.6" throat "^6.0.1" -jest-runtime@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.0.4.tgz#2e4a6aa77cac32ac612dfe12768387a8aa15c2f0" - integrity sha512-voJB4xbAjS/qYPboV+e+gmg3jfvHJJY4CagFWBOM9dQKtlaiTjcpD2tWwla84Z7PtXSQPeIpXY0qksA9Dum29A== - dependencies: - "@jest/console" "^27.0.2" - "@jest/environment" "^27.0.3" - "@jest/fake-timers" "^27.0.3" - "@jest/globals" "^27.0.3" - "@jest/source-map" "^27.0.1" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" - "@types/yargs" "^16.0.0" +jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" - exit "^0.1.2" + execa "^5.0.0" glob "^7.1.3" - graceful-fs "^4.2.4" - jest-haste-map "^27.0.2" - jest-message-util "^27.0.2" - jest-mock "^27.0.3" - jest-regex-util "^27.0.1" - jest-resolve "^27.0.4" - jest-snapshot "^27.0.4" - jest-util "^27.0.2" - jest-validate "^27.0.2" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" slash "^3.0.0" strip-bom "^4.0.0" - yargs "^16.0.3" -jest-serializer@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.1.tgz#2464d04dcc33fb71dc80b7c82e3c5e8a08cb1020" - integrity sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ== +jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== dependencies: "@types/node" "*" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" -jest-snapshot@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.0.4.tgz#2b96e22ca90382b3e93bd0aae2ce4c78bf51fb5b" - integrity sha512-hnjrvpKGdSMvKfbHyaG5Kul7pDJGZvjVy0CKpzhu28MmAssDXS6GpynhXzgst1wBQoKD8c9b2VS2a5yhDLQRCA== +jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== dependencies: "@babel/core" "^7.7.2" "@babel/generator" "^7.7.2" - "@babel/parser" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.0.0" - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" "@types/babel__traverse" "^7.0.4" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^27.0.2" - graceful-fs "^4.2.4" - jest-diff "^27.0.2" - jest-get-type "^27.0.1" - jest-haste-map "^27.0.2" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-resolve "^27.0.4" - jest-util "^27.0.2" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" natural-compare "^1.4.0" - pretty-format "^27.0.2" + pretty-format "^27.5.1" semver "^7.3.2" -jest-util@^27.0.0, jest-util@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.2.tgz#fc2c7ace3c75ae561cf1e5fdb643bf685a5be7c7" - integrity sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA== +jest-util@^27.0.0, jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.5.1" "@types/node" "*" chalk "^4.0.0" - graceful-fs "^4.2.4" - is-ci "^3.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.0.2.tgz#7fe2c100089449cd5cbb47a5b0b6cb7cda5beee5" - integrity sha512-UgBF6/oVu1ofd1XbaSotXKihi8nZhg0Prm8twQ9uCuAfo59vlxCXMPI/RKmrZEVgi3Nd9dS0I8A0wzWU48pOvg== +jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.5.1" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^27.0.1" + jest-get-type "^27.5.1" leven "^3.1.0" - pretty-format "^27.0.2" + pretty-format "^27.5.1" -jest-watcher@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.2.tgz#dab5f9443e2d7f52597186480731a8c6335c5deb" - integrity sha512-8nuf0PGuTxWj/Ytfw5fyvNn/R80iXY8QhIT0ofyImUvdnoaBdT6kob0GmhXR+wO+ALYVnh8bQxN4Tjfez0JgkA== +jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== dependencies: - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^27.0.2" + jest-util "^27.5.1" string-length "^4.0.1" -jest-worker@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.2.tgz#4ebeb56cef48b3e7514552f80d0d80c0129f0b05" - integrity sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg== +jest-worker@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^8.0.0" jest@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.0.4.tgz#91d4d564b36bcf93b98dac1ab19f07089e670f53" - integrity sha512-Px1iKFooXgGSkk1H8dJxxBIrM3tsc5SIuI4kfKYK2J+4rvCvPGr/cXktxh0e9zIPQ5g09kOMNfHQEmusBUf/ZA== + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" + integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== dependencies: - "@jest/core" "^27.0.4" + "@jest/core" "^27.5.1" import-local "^3.0.2" - jest-cli "^27.0.4" + jest-cli "^27.5.1" js-tokens@^4.0.0: version "4.0.0" @@ -2231,9 +2261,9 @@ js-yaml@^3.13.1: esprima "^4.0.0" jsdom@^16.6.0: - version "16.6.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.6.0.tgz#f79b3786682065492a3da6a60a4695da983805ac" - integrity sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg== + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== dependencies: abab "^2.0.5" acorn "^8.2.4" @@ -2260,7 +2290,7 @@ jsdom@^16.6.0: whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" whatwg-url "^8.5.0" - ws "^7.4.5" + ws "^7.4.6" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -2268,6 +2298,11 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +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" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -2281,14 +2316,12 @@ json-schema-traverse@^1.0.0: json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json5@2.x, json5@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" - integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== - dependencies: - minimist "^1.2.5" +json5@2.x, json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== kleur@^3.0.3: version "3.0.3" @@ -2311,11 +2344,16 @@ levn@^0.4.1: levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== dependencies: prelude-ls "~1.1.2" type-check "~0.3.2" +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -2323,10 +2361,10 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -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.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== lodash.merge@^4.6.2: version "4.6.2" @@ -2336,9 +2374,9 @@ lodash.merge@^4.6.2: 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= + integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@4.x, lodash@^4.17.21, lodash@^4.7.0: +lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -2362,65 +2400,55 @@ make-error@1.x: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: - tmpl "1.0.x" + tmpl "1.0.5" merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.3.0: +merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: - braces "^3.0.1" - picomatch "^2.2.3" + braces "^3.0.2" + picomatch "^2.3.1" -mime-db@1.48.0: - version "1.48.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" - integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-types@^2.1.12: - version "2.1.31" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" - integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - mime-db "1.48.0" + mime-db "1.52.0" mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@1.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -2429,22 +2457,17 @@ ms@2.1.2: natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= - -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^1.1.71: - version "1.1.73" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" - integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== +node-releases@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.5.tgz#280ed5bc3eba0d96ce44897d8aee478bfb3d9666" + integrity sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q== normalize-path@^3.0.0: version "3.0.0" @@ -2459,14 +2482,14 @@ npm-run-path@^4.0.1: path-key "^3.0.0" nwsapi@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.1.tgz#10a9f268fbf4c461249ebcfe38e359aa36e2577c" + integrity sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg== once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" @@ -2501,11 +2524,6 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -p-each-series@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" - integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== - p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -2532,6 +2550,16 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + parse5@6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" @@ -2545,14 +2573,14 @@ path-exists@^4.0.0: path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.6: +path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -2562,17 +2590,20 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -pirates@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== pkg-dir@^4.2.0: version "4.2.0" @@ -2589,7 +2620,7 @@ prelude-ls@^1.2.1: prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== pretty-format@^26.0.0, pretty-format@^26.6.2: version "26.6.2" @@ -2601,13 +2632,12 @@ pretty-format@^26.0.0, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" -pretty-format@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.2.tgz#9283ff8c4f581b186b2d4da461617143dca478a4" - integrity sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig== +pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== dependencies: - "@jest/types" "^27.0.2" - ansi-regex "^5.0.0" + ansi-regex "^5.0.1" ansi-styles "^5.0.0" react-is "^17.0.1" @@ -2617,17 +2647,17 @@ progress@^2.0.0: integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== prompts@^2.0.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61" - integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ== + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== dependencies: kleur "^3.0.3" sisteransi "^1.0.5" 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== + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" @@ -2645,14 +2675,14 @@ react-is@^17.0.1: integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== regexpp@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== require-from-string@^2.0.2: version "2.0.2" @@ -2676,13 +2706,19 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + resolve@^1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" reusify@^1.0.4: version "1.0.4" @@ -2721,9 +2757,9 @@ saxes@^5.0.1: xmlchars "^2.2.0" semver@7.x, semver@^7.2.1, semver@^7.3.2, semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" @@ -2745,9 +2781,9 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== sisteransi@^1.0.5: version "1.0.5" @@ -2769,37 +2805,32 @@ slice-ansi@^4.0.0: is-fullwidth-code-point "^3.0.0" source-map-support@^0.5.6: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== stack-utils@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" - integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== dependencies: escape-string-regexp "^2.0.0" @@ -2811,21 +2842,21 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" + strip-ansi "^6.0.1" -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: - ansi-regex "^5.0.0" + ansi-regex "^5.0.1" strip-bom@^4.0.0: version "4.0.0" @@ -2871,22 +2902,26 @@ supports-hyperlinks@^2.0.0: has-flag "^4.0.0" supports-color "^7.0.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^6.0.9: - version "6.7.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" - integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== + version "6.8.0" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" + integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== dependencies: ajv "^8.0.1" - lodash.clonedeep "^4.5.0" lodash.truncate "^4.4.2" slice-ansi "^4.0.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" terminal-link@^2.0.0: version "2.1.1" @@ -2908,7 +2943,7 @@ test-exclude@^6.0.0: text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== throat@^6.0.1: version "6.0.1" @@ -2920,15 +2955,15 @@ tiny-typed-emitter@2.1.0: resolved "https://registry.yarnpkg.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz#b3b027fdd389ff81a152c8e847ee2f5be9fad7b5" integrity sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA== -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== to-regex-range@^5.0.1: version "5.0.1" @@ -2954,18 +2989,16 @@ tr46@^2.1.0: punycode "^2.1.1" ts-jest@^27.0.3: - version "27.0.3" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.0.3.tgz#808492f022296cde19390bb6ad627c8126bf93f8" - integrity sha512-U5rdMjnYam9Ucw+h0QvtNDbc5+88nxt7tbIvqaZUhFrfG4+SkWhMXjejCLVGcpILTPuV+H3W/GZDZrnZFpPeXw== + version "27.1.5" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.5.tgz#0ddf1b163fbaae3d5b7504a1e65c914a95cff297" + integrity sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA== dependencies: bs-logger "0.x" - buffer-from "1.x" fast-json-stable-stringify "2.x" jest-util "^27.0.0" json5 "2.x" - lodash "4.x" + lodash.memoize "4.x" make-error "1.x" - mkdirp "1.x" semver "7.x" yargs-parser "20.x" @@ -2991,7 +3024,7 @@ type-check@^0.4.0, type-check@~0.4.0: type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== dependencies: prelude-ls "~1.1.2" @@ -3018,15 +3051,23 @@ typedarray-to-buffer@^3.1.5: is-typedarray "^1.0.0" typescript@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" - integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== + version "4.7.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== 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== +update-browserslist-db@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.4.tgz#dbfc5a789caa26b1db8990796c2c8ebbce304824" + integrity sha512-jnmO2BEGUjsMOe/Fg9u0oczOe/ppIDZPebzccl1yDWGLFP16Pa1/RM5wEoKYPG2zstNcDuAStejyxsOuKINdGA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -3043,10 +3084,10 @@ v8-compile-cache@^2.0.3: 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.2" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz#30898d1a7fa0c84d225a2c1434fb958f290883c1" - integrity sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow== +v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -3067,11 +3108,11 @@ w3c-xmlserializer@^2.0.0: xml-name-validator "^3.0.0" walker@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: - makeerror "1.0.x" + makeerror "1.0.12" webidl-conversions@^5.0.0: version "5.0.0" @@ -3096,9 +3137,9 @@ whatwg-mimetype@^2.3.0: integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.6.0.tgz#27c0205a4902084b872aecb97cf0f2a7a3011f4c" - integrity sha512-os0KkeeqUOl7ccdDT1qqUcS4KH4tcBTSKK5Nl5WKb2lyxInIZ/CpjkqKa1Ss12mjfdcRX9mHmPPs7/SxG1Hbdw== + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== dependencies: lodash "^4.7.0" tr46 "^2.1.0" @@ -3128,7 +3169,7 @@ wrap-ansi@^7.0.0: wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^3.0.0: version "3.0.3" @@ -3140,10 +3181,10 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -ws@^7.4.5: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@^7.4.6: + version "7.5.8" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.8.tgz#ac2729881ab9e7cbaf8787fe3469a48c5c7f636a" + integrity sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw== xml-name-validator@^3.0.0: version "3.0.0" @@ -3166,11 +3207,11 @@ yallist@^4.0.0: integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yargs-parser@20.x, yargs-parser@^20.2.2: - version "20.2.7" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" - integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs@^16.0.3: +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 249529c5163e19af9f43020ae5e648afbcd17e5a Mon Sep 17 00:00:00 2001 From: Alexis Hushbeck Date: Mon, 15 Aug 2022 08:43:52 -0700 Subject: [PATCH 08/10] =?UTF-8?q?=E2=9C=85=20Fix=20Failing=20Integration?= =?UTF-8?q?=20Tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the update to tag names, the tests needed updating. **Test plan:** `yarn test` `yarn test:e2e` --- jest.config.js | 7 +------ test/integration/specs/simple.spec.ts | 10 +++++----- test/integration/specs/uidplus.spec.ts | 10 +++++----- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/jest.config.js b/jest.config.js index 1825b968..6dc68b04 100644 --- a/jest.config.js +++ b/jest.config.js @@ -32,12 +32,7 @@ module.exports = { coverageProvider: "v8", // A list of reporter names that Jest uses when writing coverage reports - // coverageReporters: [ - // "json", - // "text", - // "lcov", - // "clover" - // ], + coverageReporters: ["lcov"], // An object that configures minimum threshold enforcement for coverage results // coverageThreshold: undefined, diff --git a/test/integration/specs/simple.spec.ts b/test/integration/specs/simple.spec.ts index 1685f3e6..42770442 100644 --- a/test/integration/specs/simple.spec.ts +++ b/test/integration/specs/simple.spec.ts @@ -51,7 +51,7 @@ const simpleSet: TestSpec[] = [ }, }, tag: { - id: 1, + id: "A1", }, }, }, @@ -129,7 +129,7 @@ const simpleSet: TestSpec[] = [ }, }, tag: { - id: 1, + id: "A1", }, }, }, @@ -180,7 +180,7 @@ const simpleSet: TestSpec[] = [ }, }, tag: { - id: 106, + id: "a106", }, }, }, @@ -585,7 +585,7 @@ const simpleSet: TestSpec[] = [ ], }, tag: { - id: 567, + id: "a567", }, }, type: "ESEARCH", @@ -656,7 +656,7 @@ const simpleSet: TestSpec[] = [ min: 7, max: 3800, tag: { - id: 285, + id: "A285", }, }, type: "ESEARCH", diff --git a/test/integration/specs/uidplus.spec.ts b/test/integration/specs/uidplus.spec.ts index f64a60b3..9352ec39 100644 --- a/test/integration/specs/uidplus.spec.ts +++ b/test/integration/specs/uidplus.spec.ts @@ -61,7 +61,7 @@ const uidplusSet: TestSpec[] = [ }, }, tag: { - id: 3, + id: "A003", }, }, }, @@ -113,7 +113,7 @@ const uidplusSet: TestSpec[] = [ }, }, tag: { - id: 3, + id: "A003", }, }, }, @@ -170,7 +170,7 @@ const uidplusSet: TestSpec[] = [ }, }, tag: { - id: 3, + id: "A003", }, }, }, @@ -237,7 +237,7 @@ const uidplusSet: TestSpec[] = [ }, }, tag: { - id: 4, + id: "A004", }, }, }, @@ -290,7 +290,7 @@ const uidplusSet: TestSpec[] = [ }, }, tag: { - id: 4, + id: "A004", }, }, }, From 03670c8e1bcbb6b673ce035841b1ee5dcadc2109 Mon Sep 17 00:00:00 2001 From: Alexis Hushbeck Date: Mon, 15 Aug 2022 08:45:25 -0700 Subject: [PATCH 09/10] =?UTF-8?q?=F0=9F=9A=A7=20Update=20Build=20to=20Repo?= =?UTF-8?q?rt=20Coverage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Testing out reporting coverage via GH Actions. **Test plan:** Hope that this all works because GH actions are a pain sometimes --- .github/workflows/build.yml | 45 ++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 486dbec3..0b5f0338 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ on: branches: [main] jobs: - build: + test: runs-on: ubuntu-latest strategy: @@ -30,3 +30,46 @@ jobs: yarn install - run: yarn run build - run: yarn test + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + flag-name: suite-${{ matrix.node-version }} + parallel: true + + e2e: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [14.x, 16.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + - name: Install Deps + run: | + npm install -g yarn + yarn install + - run: yarn run build + - run: yarn test:e2e + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + flag-name: e2e-${{ matrix.node-version }} + parallel: true + + finish: + needs: [test, e2e] + runs-on: ubuntu-latest + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.github_token }} + parallel-finished: true From 8965f303b4d617da8a4226fad5994794010b6d1b Mon Sep 17 00:00:00 2001 From: Alexis Hushbeck Date: Mon, 15 Aug 2022 08:50:28 -0700 Subject: [PATCH 10/10] =?UTF-8?q?=F0=9F=A9=B9=20Fix=20GitHub=20Actions=20Y?= =?UTF-8?q?ML?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Languages that use indentation as syntax should burn. Spacing should not determine validity 🔥 --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0b5f0338..7f92a862 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,7 +69,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Coveralls Finished - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.github_token }} - parallel-finished: true + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.github_token }} + parallel-finished: true