From ba6b0d78cfa6b12632a8a4d39db759c9667cd190 Mon Sep 17 00:00:00 2001 From: Caroline Modic Date: Thu, 21 Oct 2021 17:17:13 -0700 Subject: [PATCH] feat(logging) add initial logging utils and use case --- .circleci/config.yml | 19 + apps/election-manager/package.json | 1 + apps/election-manager/src/AppRoot.tsx | 26 +- apps/election-manager/tsconfig.json | 1 + libs/@types/kiosk-browser/kiosk-browser.d.ts | 155 +-- libs/logging/.eslintignore | 3 + libs/logging/.eslintrc.json | 6 + libs/logging/.gitignore | 1 + libs/logging/jest.config.js | 6 + libs/logging/package.json | 68 ++ libs/logging/src/index.ts | 5 + libs/logging/src/logEventIDs.test.ts | 15 + libs/logging/src/logEventIDs.ts | 89 ++ libs/logging/src/logEventTypes.test.ts | 8 + libs/logging/src/logEventTypes.ts | 54 + libs/logging/src/logServer.ts | 0 libs/logging/src/logger.test.ts | 96 ++ libs/logging/src/logger.ts | 58 ++ libs/logging/src/types.ts | 25 + libs/logging/tsconfig.json | 28 + libs/logging/tsconfig.test.json | 17 + libs/test-utils/src/fakeKiosk.ts | 1 + pnpm-lock.yaml | 973 ++++++------------- vxsuite.code-workspace | 3 + 24 files changed, 908 insertions(+), 750 deletions(-) create mode 100644 libs/logging/.eslintignore create mode 100644 libs/logging/.eslintrc.json create mode 100644 libs/logging/.gitignore create mode 100644 libs/logging/jest.config.js create mode 100644 libs/logging/package.json create mode 100644 libs/logging/src/index.ts create mode 100644 libs/logging/src/logEventIDs.test.ts create mode 100644 libs/logging/src/logEventIDs.ts create mode 100644 libs/logging/src/logEventTypes.test.ts create mode 100644 libs/logging/src/logEventTypes.ts create mode 100644 libs/logging/src/logServer.ts create mode 100644 libs/logging/src/logger.test.ts create mode 100644 libs/logging/src/logger.ts create mode 100644 libs/logging/src/types.ts create mode 100644 libs/logging/tsconfig.json create mode 100644 libs/logging/tsconfig.test.json diff --git a/.circleci/config.yml b/.circleci/config.yml index 3091fa8032..3f478af4d8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -153,6 +153,24 @@ jobs: command: | pnpm --dir libs/fixtures test + test-logging: + executor: nodejs + resource_class: xlarge + steps: + - checkout-and-install + - run: + name: Build + command: | + pnpm --dir libs/logging build + - run: + name: Lint + command: | + pnpm --dir libs/logging lint + - run: + name: Test + command: | + pnpm --dir libs/logging test + test-hmpb-interpreter: executor: nodejs resource_class: xlarge @@ -407,6 +425,7 @@ workflows: - test-hmpb-interpreter - test-integration-testing-bsd - test-integration-testing-election-manager + - test-logging - test-lsd - test-module-converter-ms-sems - test-module-scan diff --git a/apps/election-manager/package.json b/apps/election-manager/package.json index 28ff49b81c..09d9918690 100644 --- a/apps/election-manager/package.json +++ b/apps/election-manager/package.json @@ -88,6 +88,7 @@ "@types/styled-components": "^5.1.7", "@votingworks/ballot-encoder": "workspace:*", "@votingworks/fixtures": "workspace:*", + "@votingworks/logging": "workspace:*", "@votingworks/qrcode.react": "^1.0.2", "@votingworks/types": "workspace:*", "@votingworks/ui": "workspace:*", diff --git a/apps/election-manager/src/AppRoot.tsx b/apps/election-manager/src/AppRoot.tsx index e5a4f1a584..01acb36637 100644 --- a/apps/election-manager/src/AppRoot.tsx +++ b/apps/election-manager/src/AppRoot.tsx @@ -3,7 +3,12 @@ import React, { useState, useRef, useEffect, useCallback } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import 'normalize.css'; import { sha256 } from 'js-sha256'; - +import { + Logger, + LogSource, + LogEventId, + LogDispositionStandardTypes, +} from '@votingworks/logging'; import { ElectionDefinition, parseElection, @@ -80,6 +85,7 @@ function AppRoot({ hardware, machineConfigProvider, }: Props): JSX.Element { + const logger = new Logger(LogSource.VxAdminApp, window.kiosk); const printBallotRef = useRef(null); const getElectionDefinition = useCallback(async (): Promise< @@ -310,6 +316,13 @@ function AppRoot({ const saveElection: SaveElection = useCallback( async (electionJSON) => { + const previousElection = electionDefinition; + if (previousElection) { + void logger.log(LogEventId.ElectionUnconfigured, 'admin', { + disposition: LogDispositionStandardTypes.Success, + previousElectionHash: previousElection.electionHash, + }); + } // we set a new election definition, reset everything await storage.clear(); setIsOfficialResults(false); @@ -322,6 +335,9 @@ function AppRoot({ const electionData = electionJSON; const electionHash = sha256(electionData); const election = safeParseElection(electionData).unsafeUnwrap(); + // Temporarily bootstrap an authenticated user session. This will be removed + // once we have a full story for how to bootstrap the auth process. + bootstrapAuthenticatedAdminSession(); setElectionDefinition({ electionData, @@ -331,9 +347,6 @@ function AppRoot({ const newConfiguredAt = new Date().toISOString(); setConfiguredAt(newConfiguredAt); - // Temporarily bootstrap an authenticated user session. This will be removed - // once we have a full story for how to bootstrap the auth process. - bootstrapAuthenticatedAdminSession(); await storage.set(configuredAtStorageKey, newConfiguredAt); await storage.set(electionDefinitionStorageKey, { @@ -341,10 +354,15 @@ function AppRoot({ electionData, electionHash, }); + await logger.log(LogEventId.ElectionConfigured, 'admin', { + disposition: LogDispositionStandardTypes.Success, + newElectionHash: electionHash, + }); } }, // eslint-disable-next-line react-hooks/exhaustive-deps [ + electionDefinition, storage, setIsOfficialResults, setCastVoteRecordFiles, diff --git a/apps/election-manager/tsconfig.json b/apps/election-manager/tsconfig.json index e210fd9e0c..7de2d428ed 100644 --- a/apps/election-manager/tsconfig.json +++ b/apps/election-manager/tsconfig.json @@ -24,6 +24,7 @@ { "path": "../../libs/test-utils" }, { "path": "../../libs/types" }, { "path": "../../libs/utils" }, + { "path": "../../libs/logging" }, { "path": "../../libs/ui" } ] } diff --git a/libs/@types/kiosk-browser/kiosk-browser.d.ts b/libs/@types/kiosk-browser/kiosk-browser.d.ts index 36b38326da..1978673b17 100644 --- a/libs/@types/kiosk-browser/kiosk-browser.d.ts +++ b/libs/@types/kiosk-browser/kiosk-browser.d.ts @@ -1,7 +1,7 @@ declare namespace KioskBrowser { export interface BatteryInfo { - discharging: boolean - level: number // Number between 0–1 + discharging: boolean; + level: number; // Number between 0–1 } export type PrintSides = @@ -22,57 +22,57 @@ declare namespace KioskBrowser { * that a right-side up portrait sheet flipped over on the short edge remains * right-side up, i.e. a bound-at-the-top ring binder. */ - | 'two-sided-short-edge' + | 'two-sided-short-edge'; export interface PrintOptions { - deviceName?: string - paperSource?: string - copies?: number - sides?: PrintSides + deviceName?: string; + paperSource?: string; + copies?: number; + sides?: PrintSides; } export interface PrinterInfo { // Docs: http://electronjs.org/docs/api/structures/printer-info - description: string - isDefault: boolean - name: string - status: number + description: string; + isDefault: boolean; + name: string; + status: number; // Added via kiosk-browser - connected: boolean - options?: { [key: string]: string } + connected: boolean; + options?: { [key: string]: string }; } export interface Device { - locationId: number - vendorId: number - productId: number - deviceName: string - manufacturer: string - serialNumber: string - deviceAddress: number + locationId: number; + vendorId: number; + productId: number; + deviceName: string; + manufacturer: string; + serialNumber: string; + deviceAddress: number; } export interface UsbDrive { - deviceName: string - mountPoint?: string + deviceName: string; + mountPoint?: string; } export interface SaveAsOptions { - title?: string - defaultPath?: string - buttonLabel?: string - filters?: FileFilter[] + title?: string; + defaultPath?: string; + buttonLabel?: string; + filters?: FileFilter[]; } export interface MakeDirectoryOptions { - recursive?: boolean - mode?: number + recursive?: boolean; + mode?: number; } export interface FileFilter { // Docs: http://electronjs.org/docs/api/structures/file-filter - extensions: string[] - name: string + extensions: string[]; + name: string; } export enum FileSystemEntryType { @@ -86,13 +86,13 @@ declare namespace KioskBrowser { } export interface FileSystemEntry { - readonly name: string - readonly path: string - readonly type: FileSystemEntryType - readonly size: number - readonly mtime: Date - readonly atime: Date - readonly ctime: Date + readonly name: string; + readonly path: string; + readonly type: FileSystemEntryType; + readonly size: number; + readonly mtime: Date; + readonly atime: Date; + readonly ctime: Date; } export interface FileWriter { @@ -100,106 +100,107 @@ declare namespace KioskBrowser { * Writes a chunk to the file. May be called multiple times. Data will be * written in the order of calls to `write`. */ - write(data: Uint8Array | string): Promise + write(data: Uint8Array | string): Promise; /** * Finishes writing to the file and closes it. Subsequent calls to `write` * will fail. Resolves when the file is successfully closed. */ - end(): Promise + end(): Promise; - filename: string + filename: string; } export interface SetClockParams { - isoDatetime: string - IANAZone: string + isoDatetime: string; + IANAZone: string; } export interface TotpInfo { - isoDatetime: string - code: string + isoDatetime: string; + code: string; } export interface SignParams { - signatureType: string - payload: string + signatureType: string; + payload: string; } - + export interface Kiosk { - print(options?: PrintOptions): Promise - getPrinterInfo(): Promise + print(options?: PrintOptions): Promise; + getPrinterInfo(): Promise; /** * Prints the current page to PDF and resolves with the PDF file bytes. */ - printToPDF(): Promise + printToPDF(): Promise; + log(message: string): Promise; - getBatteryInfo(): Promise - devices: import('rxjs').Observable> - printers: import('rxjs').Observable> - quit(): void + getBatteryInfo(): Promise; + devices: import('rxjs').Observable>; + printers: import('rxjs').Observable>; + quit(): void; /** * Opens a Save Dialog to allow the user to choose a destination for a file. * Once chosen, resolves with a handle to the file to write data to it. */ - saveAs(options?: SaveAsOptions): Promise + saveAs(options?: SaveAsOptions): Promise; /** * Writes a file to a specified file path */ - writeFile(path: string): Promise - writeFile(path: string, content: Uint8Array | string): Promise + writeFile(path: string): Promise; + writeFile(path: string, content: Uint8Array | string): Promise; /* * Creates a directory at the specified path. */ - makeDirectory(path: string, options?: MakeDirectoryOptions): Promise + makeDirectory(path: string, options?: MakeDirectoryOptions): Promise; // USB sticks - getUsbDrives(): Promise - mountUsbDrive(device: string): Promise - unmountUsbDrive(device: string): Promise + getUsbDrives(): Promise; + mountUsbDrive(device: string): Promise; + unmountUsbDrive(device: string): Promise; /** * Writes a file to a specified file path */ - writeFile(path: string): Promise - writeFile(path: string, content: Uint8Array | string): Promise + writeFile(path: string): Promise; + writeFile(path: string, content: Uint8Array | string): Promise; /** * Creates a directory at the specified path. */ - makeDirectory(path: string, options?: MakeDirectoryOptions): Promise + makeDirectory(path: string, options?: MakeDirectoryOptions): Promise; /** * Reads the list of files at a specified directory path */ - getFileSystemEntries(path: string): Promise + getFileSystemEntries(path: string): Promise; /** * Reads a file from a specified path */ - readFile(path: string): Promise - readFile(path: string, encoding: string): Promise + readFile(path: string): Promise; + readFile(path: string, encoding: string): Promise; // storage storage: { - set(key: string, value: unknown): Promise - get(key: string): Promise - remove(key: string): Promise - clear(): Promise - } + set(key: string, value: unknown): Promise; + get(key: string): Promise; + remove(key: string): Promise; + clear(): Promise; + }; - setClock(params: SetClockParams): Promise + setClock(params: SetClockParams): Promise; totp: { - get(): Promise - } + get(): Promise; + }; - sign(params: SignParams): Promise + sign(params: SignParams): Promise; } } -declare var kiosk: KioskBrowser.Kiosk | undefined +declare var kiosk: KioskBrowser.Kiosk | undefined; diff --git a/libs/logging/.eslintignore b/libs/logging/.eslintignore new file mode 100644 index 0000000000..e2c7cf4cc8 --- /dev/null +++ b/libs/logging/.eslintignore @@ -0,0 +1,3 @@ +build +coverage +jest.config.js \ No newline at end of file diff --git a/libs/logging/.eslintrc.json b/libs/logging/.eslintrc.json new file mode 100644 index 0000000000..02874d38d9 --- /dev/null +++ b/libs/logging/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "parserOptions": { + "project": "./tsconfig.test.json" + }, + "extends": ["plugin:vx/recommended"] +} diff --git a/libs/logging/.gitignore b/libs/logging/.gitignore new file mode 100644 index 0000000000..502167fa0b --- /dev/null +++ b/libs/logging/.gitignore @@ -0,0 +1 @@ +/lib diff --git a/libs/logging/jest.config.js b/libs/logging/jest.config.js new file mode 100644 index 0000000000..6596f6b03a --- /dev/null +++ b/libs/logging/jest.config.js @@ -0,0 +1,6 @@ +const shared = require('../../jest.config.shared'); + +module.exports = { + ...shared, + testEnvironment: 'jsdom', +}; diff --git a/libs/logging/package.json b/libs/logging/package.json new file mode 100644 index 0000000000..5673e2ebfe --- /dev/null +++ b/libs/logging/package.json @@ -0,0 +1,68 @@ +{ + "name": "@votingworks/logging", + "version": "1.0.0", + "private": true, + "description": "Utilities and definitions for logging in votingworks components", + "license": "GPL-3.0", + "author": "VotingWorks Eng ", + "main": "build/index.js", + "types": "build/index.d.js", + "files": [ + "build" + ], + "scripts": { + "type-check": "tsc --build", + "build": "tsc --build", + "build:watch": "tsc --build --watch", + "lint": "pnpm type-check && eslint .", + "lint:fix": "pnpm type-check && eslint . --fix", + "test": "is-ci test:ci test:watch", + "test:watch": "TZ=UTC jest --watch", + "test:coverage": "TZ=UTC jest --coverage", + "test:ci": "TZ=UTC pnpm build && pnpm test:coverage", + "pre-commit": "lint-staged" + }, + "lint-staged": { + "*.+(css|graphql|json|less|md|mdx|sass|scss|yaml|yml)": [ + "prettier --write" + ], + "*.+(js|jsx|ts|tsx)": [ + "eslint --quiet --fix" + ], + "package.json": [ + "sort-package-json" + ] + }, + "dependencies": { + "@types/kiosk-browser": "workspace:*", + "@types/node": "^12.20.11", + "@votingworks/types": "workspace:*", + "@votingworks/utils": "workspace:*", + "debug": "^4.3.2" + }, + "devDependencies": { + "@types/debug": "^4.1.6", + "@types/jest": "^26.0.23", + "@typescript-eslint/eslint-plugin": "^4.28.4", + "@typescript-eslint/parser": "^4.28.4", + "@votingworks/fixtures": "workspace:*", + "@votingworks/test-utils": "workspace:*", + "eslint": "^7.26.0", + "eslint-config-prettier": "^8.3.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-plugin-import": "^2.24.2", + "eslint-plugin-prettier": "^3.4.0", + "eslint-plugin-vx": "workspace:*", + "fast-check": "^2.18.0", + "fetch-mock": "^9.9.0", + "is-ci-cli": "^2.2.0", + "jest": "^26.6.3", + "jest-watch-typeahead": "^0.6.4", + "lint-staged": "^11.0.0", + "mockdate": "^3.0.2", + "prettier": "^2.3.0", + "sort-package-json": "^1.50.0", + "ts-jest": "^26.5.6", + "typescript": "^4.3.5" + } +} diff --git a/libs/logging/src/index.ts b/libs/logging/src/index.ts new file mode 100644 index 0000000000..cc5b5ba43b --- /dev/null +++ b/libs/logging/src/index.ts @@ -0,0 +1,5 @@ +/* istanbul ignore file */ +export * from './logger'; +export * from './types'; +export * from './logEventIDs'; +export * from './logEventTypes'; diff --git a/libs/logging/src/logEventIDs.test.ts b/libs/logging/src/logEventIDs.test.ts new file mode 100644 index 0000000000..eaf49f55c7 --- /dev/null +++ b/libs/logging/src/logEventIDs.test.ts @@ -0,0 +1,15 @@ +import { getDetailsForEventId, LogEventId } from './logEventIDs'; + +test('getDetailsForEventId implemented for all events properly', () => { + for (const eventId of Object.values(LogEventId)) { + const logDetails = getDetailsForEventId(eventId); + expect(logDetails.eventId).toEqual(eventId); + } +}); + +test('all event Ids are unique', () => { + const allEventIds = Object.values(LogEventId); + for (const eventId of allEventIds) { + expect(allEventIds.filter((e) => e === eventId)).toHaveLength(1); + } +}); diff --git a/libs/logging/src/logEventIDs.ts b/libs/logging/src/logEventIDs.ts new file mode 100644 index 0000000000..ae5429929e --- /dev/null +++ b/libs/logging/src/logEventIDs.ts @@ -0,0 +1,89 @@ +import { throwIllegalValue } from '@votingworks/utils'; +import { LogEventType } from './logEventTypes'; + +/** + * In order to add a new log event you must do three things: + * 1. Add the new event to the enum LogEventId + * 2. Define a LogDetails object representing the information about that log event. + * 3. Add a case statement to the switch in getDetailsForEventId returning your new LogDetails object when you see your new LogEventId. + * You will then be ready to use the log event from your code! + */ + +export enum LogEventId { + ElectionConfigured = 'election-configured', + ElectionUnconfigured = 'election-unconfigured', + MachineBootInit = 'machine-boot-init', + MachineBootComplete = 'machine-boot-complete', + MachineShutdownInit = 'machine-shutdown-init', + MachineShutdownComplete = 'machine-shutdown-complete', +} + +export interface LogDetails { + eventId: LogEventId; + eventType: LogEventType; + defaultMessage?: string; + documentationMessage: string; +} + +const ElectionConfiguredEvent: LogDetails = { + eventId: LogEventId.ElectionConfigured, + eventType: LogEventType.UserAction, + defaultMessage: 'Application has been configured for a new election.', + documentationMessage: + 'The user has configured current machine to a new election definition.', +}; + +const ElectionUnconfiguredEvent: LogDetails = { + eventId: LogEventId.ElectionUnconfigured, + eventType: LogEventType.UserAction, + defaultMessage: + 'Application has been unconfigured from the previous election.', + documentationMessage: + 'The user has unconfigured current machine to remove the current election definition.', +}; + +const MachineBootInitEvent: LogDetails = { + eventId: LogEventId.MachineBootInit, + eventType: LogEventType.SystemAction, + documentationMessage: 'The machine is beginning the boot process.', +}; + +const MachineBootCompleteEvent: LogDetails = { + eventId: LogEventId.MachineBootComplete, + eventType: LogEventType.SystemStatus, + documentationMessage: 'The machine has completed the boot process.', +}; + +const MachineShutdownInitEvent: LogDetails = { + eventId: LogEventId.MachineShutdownInit, + eventType: LogEventType.SystemAction, + documentationMessage: + 'The machine is beginning the shutdown process to power down or reboot, as indicated by the message.', +}; + +const MachineShutdownCompleteEvent: LogDetails = { + eventId: LogEventId.MachineShutdownComplete, + eventType: LogEventType.SystemStatus, + documentationMessage: + 'The machine has completed all the steps to shutdown and will now power down or reboot.', +}; + +export function getDetailsForEventId(eventId: LogEventId): LogDetails { + switch (eventId) { + case LogEventId.ElectionConfigured: + return ElectionConfiguredEvent; + case LogEventId.ElectionUnconfigured: + return ElectionUnconfiguredEvent; + case LogEventId.MachineBootInit: + return MachineBootInitEvent; + case LogEventId.MachineBootComplete: + return MachineBootCompleteEvent; + case LogEventId.MachineShutdownInit: + return MachineShutdownInitEvent; + case LogEventId.MachineShutdownComplete: + return MachineShutdownCompleteEvent; + /* istanbul ignore next - compile time check for completeness */ + default: + throwIllegalValue(eventId); + } +} diff --git a/libs/logging/src/logEventTypes.test.ts b/libs/logging/src/logEventTypes.test.ts new file mode 100644 index 0000000000..167723a2fa --- /dev/null +++ b/libs/logging/src/logEventTypes.test.ts @@ -0,0 +1,8 @@ +import { getDocumentationForEventType, LogEventType } from './logEventTypes'; + +test('getDocumentationForEventType implemented for all log event types properly', () => { + for (const eventType of Object.values(LogEventType)) { + const documentation = getDocumentationForEventType(eventType); + expect(documentation.eventType).toEqual(eventType); + } +}); diff --git a/libs/logging/src/logEventTypes.ts b/libs/logging/src/logEventTypes.ts new file mode 100644 index 0000000000..44e5fa63cc --- /dev/null +++ b/libs/logging/src/logEventTypes.ts @@ -0,0 +1,54 @@ +import { throwIllegalValue } from '@votingworks/utils'; + +/** + * In order to add a new log event type you must do three things: + * 1. Add the new event type to the enum LogEventType + * 2. Define a LogEventTypeDocumentation object with documentation about the meaning of the event type. This will be available publicly with the intended audience of users understanding the logs. + * 3. Add a case statement to the switch in getDocumentationForEventType returning your new LogEventTypeDocumentation object when you see the event type. + * You will then be ready to use this event type when defining log event Ids! + */ + +export enum LogEventType { + UserAction = 'user-action', + SystemAction = 'system-action', + SystemStatus = 'system-status', +} + +export interface LogEventTypeDocumentation { + eventType: LogEventType; + documentationMessage: string; +} + +const UserActionEventDocumentation: LogEventTypeDocumentation = { + eventType: LogEventType.UserAction, + documentationMessage: + 'A log that results from a user taking an action, i.e. an election admin uploading an election definition to a machine.', +}; + +const SystemActionEventDocumentation: LogEventTypeDocumentation = { + eventType: LogEventType.SystemAction, + documentationMessage: + 'A log that results from the system taking some action, i.e. the machine booting.', +}; + +const SystemStatusEventDocumentation: LogEventTypeDocumentation = { + eventType: LogEventType.SystemStatus, + documentationMessage: + 'A log that results from the system updating on the status of a process it is running, i.e. completion of machine shutdown or boot.', +}; + +export function getDocumentationForEventType( + eventType: LogEventType +): LogEventTypeDocumentation { + switch (eventType) { + case LogEventType.UserAction: + return UserActionEventDocumentation; + case LogEventType.SystemAction: + return SystemActionEventDocumentation; + case LogEventType.SystemStatus: + return SystemStatusEventDocumentation; + /* istanbul ignore next - compile time check for completeness */ + default: + throwIllegalValue(eventType); + } +} diff --git a/libs/logging/src/logServer.ts b/libs/logging/src/logServer.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libs/logging/src/logger.test.ts b/libs/logging/src/logger.test.ts new file mode 100644 index 0000000000..92b9bd9308 --- /dev/null +++ b/libs/logging/src/logger.test.ts @@ -0,0 +1,96 @@ +/* eslint-disable no-console */ +import { fakeKiosk } from '@votingworks/test-utils'; +import MockDate from 'mockdate'; +import { LogEventType } from '.'; +import { LogEventId } from './logEventIDs'; +import { Logger } from './logger'; +import { LogDispositionStandardTypes, LogSource } from './types'; + +MockDate.set('2020-07-24T00:00:00.000Z'); + +test('logger logs server logs as expected', async () => { + console.log = jest.fn(); + const logger = new Logger(LogSource.System); + await logger.log(LogEventId.MachineBootInit, 'system', { + message: 'I come back stronger than a 90s trend', + disposition: LogDispositionStandardTypes.Success, + reputation: 'callitwhatyouwant', + }); + expect(console.log).toHaveBeenCalledWith({ + source: LogSource.System, + eventId: LogEventId.MachineBootInit, + eventType: LogEventType.SystemAction, + user: 'system', + message: 'I come back stronger than a 90s trend', + disposition: LogDispositionStandardTypes.Success, + reputation: 'callitwhatyouwant', + }); +}); + +test('logger logs client logs as expected through kiosk browser with overridden message', async () => { + console.log = jest.fn(); + const kiosk = fakeKiosk(); + const logger = new Logger(LogSource.VxAdminApp, kiosk); + await logger.log(LogEventId.ElectionConfigured, 'admin', { + message: 'On my tallest tiptoes', + disposition: LogDispositionStandardTypes.NotApplicable, + folklore: 'mirrorball', + }); + expect(kiosk.log).toHaveBeenCalledTimes(1); + expect(kiosk.log).toHaveBeenCalledWith( + JSON.stringify({ + timeLogInitiated: new Date(2020, 6, 24).getTime().toString(), + source: LogSource.VxAdminApp, + eventId: LogEventId.ElectionConfigured, + eventType: LogEventType.UserAction, + user: 'admin', + message: 'On my tallest tiptoes', // overrides the default message + disposition: LogDispositionStandardTypes.NotApplicable, + folklore: 'mirrorball', + }) + ); + expect(console.log).not.toHaveBeenCalled(); +}); + +test('defaults to default message when defined and no disposition', async () => { + console.log = jest.fn(); + const kiosk = fakeKiosk(); + const logger = new Logger(LogSource.VxAdminApp, kiosk); + await logger.log(LogEventId.ElectionUnconfigured, 'admin'); + expect(kiosk.log).toHaveBeenCalledTimes(1); + expect(kiosk.log).toHaveBeenCalledWith( + JSON.stringify({ + timeLogInitiated: new Date(2020, 6, 24).getTime().toString(), + source: LogSource.VxAdminApp, + eventId: LogEventId.ElectionUnconfigured, + eventType: LogEventType.UserAction, + user: 'admin', + message: 'Application has been unconfigured from the previous election.', + disposition: LogDispositionStandardTypes.NotApplicable, + }) + ); + expect(console.log).not.toHaveBeenCalled(); +}); + +test('logs unknown disposition as expected', async () => { + console.log = jest.fn(); + const logger = new Logger(LogSource.System); + await logger.log(LogEventId.MachineBootComplete, 'system', { + message: 'threw out our cloaks and our daggers now', + disposition: 'daylight', + maybe: 'you', + ran: 'with', + the: 'wolves', + }); + expect(console.log).toHaveBeenCalledWith({ + source: LogSource.System, + eventId: LogEventId.MachineBootComplete, + eventType: LogEventType.SystemStatus, + user: 'system', + message: 'threw out our cloaks and our daggers now', + disposition: 'daylight', + maybe: 'you', + ran: 'with', + the: 'wolves', + }); +}); diff --git a/libs/logging/src/logger.ts b/libs/logging/src/logger.ts new file mode 100644 index 0000000000..ee7fdf7bdb --- /dev/null +++ b/libs/logging/src/logger.ts @@ -0,0 +1,58 @@ +import makeDebug from 'debug'; +import { Dictionary } from '@votingworks/types'; +import { getDetailsForEventId, LogLine } from '.'; +import { LogEventId } from './logEventIDs'; +import { + LogDisposition, + LogDispositionStandardTypes, + LoggingUserRole, + LogSource, +} from './types'; + +const debug = makeDebug('logger'); + +interface LogData extends Dictionary { + message?: string; + disposition?: LogDisposition; +} + +export class Logger { + constructor( + private readonly source: LogSource, + private readonly kiosk?: KioskBrowser.Kiosk + ) {} + + async log( + eventId: LogEventId, + user: LoggingUserRole, + logData: LogData = {} + ): Promise { + const eventSpecificDetails = getDetailsForEventId(eventId); + const { + message = eventSpecificDetails.defaultMessage, + disposition = LogDispositionStandardTypes.NotApplicable, + ...additionalData + } = logData; + const logLine: LogLine = { + source: this.source, + eventId, + eventType: eventSpecificDetails.eventType, + user, + message, + disposition, + ...additionalData, + }; + if (this.kiosk) { + debug(logLine); // for internal debugging use log to the console + await this.kiosk.log( + JSON.stringify({ + timeLogInitiated: Date.now().toString(), + ...logLine, + }) + ); + } else { + // eslint-disable-next-line no-console + console.log(logLine); + } + } +} diff --git a/libs/logging/src/types.ts b/libs/logging/src/types.ts new file mode 100644 index 0000000000..3dd3f45217 --- /dev/null +++ b/libs/logging/src/types.ts @@ -0,0 +1,25 @@ +import { CardDataTypes, Dictionary } from '@votingworks/types'; +import { LogEventId, LogEventType } from '.'; + +export enum LogDispositionStandardTypes { + Success = 'success', + Failure = 'failure', + NotApplicable = 'na', +} + +export type LoggingUserRole = CardDataTypes | 'vx-employee' | 'system'; +export type LogDisposition = LogDispositionStandardTypes | string; +export enum LogSource { + System = 'system', + VxAdminApp = 'vx-admin', +} + +export interface LogLine extends Dictionary { + source: LogSource; + eventId: LogEventId; + eventType: LogEventType; + user: LoggingUserRole; + disposition: LogDisposition; + message?: string; + time?: string; +} diff --git a/libs/logging/tsconfig.json b/libs/logging/tsconfig.json new file mode 100644 index 0000000000..a61dfa3b34 --- /dev/null +++ b/libs/logging/tsconfig.json @@ -0,0 +1,28 @@ +{ + "extends": "../../tsconfig.shared.json", + "compilerOptions": { + "module": "commonjs", + "lib": ["dom", "dom.iterable", "esnext"], + "declaration": true, + "rootDir": "src", + "outDir": "build", + "composite": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true + }, + "include": ["src"], + "exclude": ["**/*.test.ts"], + "references": [ + { "path": "../../libs/eslint-plugin-vx/tsconfig.build.json" }, + { "path": "../../libs/types" }, + { "path": "../../libs/fixtures" }, + { "path": "../../libs/utils" } + ] +} diff --git a/libs/logging/tsconfig.test.json b/libs/logging/tsconfig.test.json new file mode 100644 index 0000000000..4e679c3cb0 --- /dev/null +++ b/libs/logging/tsconfig.test.json @@ -0,0 +1,17 @@ +{ + "extends": "../eslint-plugin-vx/tsconfig.build.json", + "compilerOptions": { + "rootDir": ".", + "resolveJsonModule": true, + "esModuleInterop": true, + "noEmit": true + }, + "include": ["src", "src/data/*.json"], + "exclude": [], + "references": [ + { "path": "../../libs/eslint-plugin-vx/tsconfig.build.json" }, + { "path": "../../libs/test-utils" }, + { "path": "../../libs/types" }, + { "path": "../../libs/fixtures" } + ] +} diff --git a/libs/test-utils/src/fakeKiosk.ts b/libs/test-utils/src/fakeKiosk.ts index 082b14c5be..ec0e7de53d 100644 --- a/libs/test-utils/src/fakeKiosk.ts +++ b/libs/test-utils/src/fakeKiosk.ts @@ -78,5 +78,6 @@ export function fakeKiosk({ get: jest.fn(), }, sign: jest.fn(), + log: jest.fn(), }; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 819de3353c..a71d021699 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -474,6 +474,7 @@ importers: '@types/styled-components': 5.1.7 '@votingworks/ballot-encoder': link:../../libs/ballot-encoder '@votingworks/fixtures': link:../../libs/fixtures + '@votingworks/logging': link:../../libs/logging '@votingworks/qrcode.react': 1.0.2_react@17.0.1 '@votingworks/types': link:../../libs/types '@votingworks/ui': link:../../libs/ui @@ -575,6 +576,7 @@ importers: '@typescript-eslint/parser': ^4.28.4 '@votingworks/ballot-encoder': workspace:* '@votingworks/fixtures': workspace:* + '@votingworks/logging': workspace:* '@votingworks/qrcode.react': ^1.0.2 '@votingworks/test-utils': workspace:* '@votingworks/types': workspace:* @@ -1338,6 +1340,66 @@ importers: ts-node: ^9.0.0 typescript: ^4.3.5 uuid: ^8.3.1 + libs/logging: + dependencies: + '@types/kiosk-browser': link:../@types/kiosk-browser + '@types/node': 12.20.15 + '@votingworks/types': link:../types + '@votingworks/utils': link:../utils + debug: 4.3.2 + devDependencies: + '@types/debug': 4.1.7 + '@types/jest': 26.0.23 + '@typescript-eslint/eslint-plugin': 4.30.0_30d5b6043eb1943afef560c3f2647d4d + '@typescript-eslint/parser': 4.29.3_eslint@7.29.0+typescript@4.3.5 + '@votingworks/fixtures': link:../fixtures + '@votingworks/test-utils': link:../test-utils + eslint: 7.29.0 + eslint-config-prettier: 8.3.0_eslint@7.29.0 + eslint-import-resolver-node: 0.3.6 + eslint-plugin-import: 2.24.2_eslint@7.29.0+typescript@4.3.5 + eslint-plugin-prettier: 3.4.1_4e72879372edbffcbdaf0fa17b22c203 + eslint-plugin-vx: link:../eslint-plugin-vx + fast-check: 2.18.0 + fetch-mock: 9.11.0 + is-ci-cli: 2.2.0 + jest: 26.6.3 + jest-watch-typeahead: 0.6.5_jest@26.6.3 + lint-staged: 11.0.0 + mockdate: 3.0.5 + prettier: 2.3.2 + sort-package-json: 1.50.0 + ts-jest: 26.5.6_jest@26.6.3+typescript@4.3.5 + typescript: 4.3.5 + specifiers: + '@types/debug': ^4.1.6 + '@types/jest': ^26.0.23 + '@types/kiosk-browser': workspace:* + '@types/node': ^12.20.11 + '@typescript-eslint/eslint-plugin': ^4.28.4 + '@typescript-eslint/parser': ^4.28.4 + '@votingworks/fixtures': workspace:* + '@votingworks/test-utils': workspace:* + '@votingworks/types': workspace:* + '@votingworks/utils': workspace:* + debug: ^4.3.2 + eslint: ^7.26.0 + eslint-config-prettier: ^8.3.0 + eslint-import-resolver-node: ^0.3.6 + eslint-plugin-import: ^2.24.2 + eslint-plugin-prettier: ^3.4.0 + eslint-plugin-vx: workspace:* + fast-check: ^2.18.0 + fetch-mock: ^9.9.0 + is-ci-cli: ^2.2.0 + jest: ^26.6.3 + jest-watch-typeahead: ^0.6.4 + lint-staged: ^11.0.0 + mockdate: ^3.0.2 + prettier: ^2.3.0 + sort-package-json: ^1.50.0 + ts-jest: ^26.5.6 + typescript: ^4.3.5 libs/lsd: dependencies: bindings: 1.5.0 @@ -1825,27 +1887,6 @@ packages: node: '>=6.9.0' resolution: integrity: sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== - /@babel/core/7.12.10: - dependencies: - '@babel/code-frame': 7.12.11 - '@babel/generator': 7.12.11 - '@babel/helper-module-transforms': 7.12.1 - '@babel/helpers': 7.12.5 - '@babel/parser': 7.12.11 - '@babel/template': 7.12.7 - '@babel/traverse': 7.12.12 - '@babel/types': 7.12.12 - convert-source-map: 1.7.0 - debug: 4.3.1 - gensync: 1.0.0-beta.2 - json5: 2.1.3 - lodash: 4.17.20 - semver: 5.7.1 - source-map: 0.5.7 - engines: - node: '>=6.9.0' - resolution: - integrity: sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== /@babel/core/7.12.3: dependencies: '@babel/code-frame': 7.15.8 @@ -1960,6 +2001,7 @@ packages: '@babel/types': 7.12.12 jsesc: 2.5.2 source-map: 0.5.7 + dev: false resolution: integrity: sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== /@babel/generator/7.14.0: @@ -2156,6 +2198,7 @@ packages: '@babel/helper-get-function-arity': 7.12.10 '@babel/template': 7.12.7 '@babel/types': 7.12.12 + dev: false resolution: integrity: sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA== /@babel/helper-function-name/7.12.13: @@ -2195,6 +2238,7 @@ packages: /@babel/helper-get-function-arity/7.12.10: dependencies: '@babel/types': 7.12.12 + dev: false resolution: integrity: sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag== /@babel/helper-get-function-arity/7.12.13: @@ -2230,11 +2274,6 @@ packages: node: '>=6.9.0' resolution: integrity: sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA== - /@babel/helper-member-expression-to-functions/7.12.7: - dependencies: - '@babel/types': 7.12.12 - resolution: - integrity: sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw== /@babel/helper-member-expression-to-functions/7.13.12: dependencies: '@babel/types': 7.14.4 @@ -2266,6 +2305,7 @@ packages: /@babel/helper-module-imports/7.12.5: dependencies: '@babel/types': 7.12.12 + dev: false resolution: integrity: sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== /@babel/helper-module-imports/7.13.12: @@ -2287,19 +2327,6 @@ packages: node: '>=6.9.0' resolution: integrity: sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA== - /@babel/helper-module-transforms/7.12.1: - dependencies: - '@babel/helper-module-imports': 7.12.5 - '@babel/helper-replace-supers': 7.12.11 - '@babel/helper-simple-access': 7.12.1 - '@babel/helper-split-export-declaration': 7.12.11 - '@babel/helper-validator-identifier': 7.12.11 - '@babel/template': 7.12.7 - '@babel/traverse': 7.12.12 - '@babel/types': 7.12.12 - lodash: 4.17.20 - resolution: - integrity: sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== /@babel/helper-module-transforms/7.14.2: dependencies: '@babel/helper-module-imports': 7.13.12 @@ -2356,11 +2383,6 @@ packages: node: '>=6.9.0' resolution: integrity: sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg== - /@babel/helper-optimise-call-expression/7.12.10: - dependencies: - '@babel/types': 7.12.12 - resolution: - integrity: sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ== /@babel/helper-optimise-call-expression/7.12.13: dependencies: '@babel/types': 7.14.4 @@ -2397,14 +2419,6 @@ packages: dev: false resolution: integrity: sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A== - /@babel/helper-replace-supers/7.12.11: - dependencies: - '@babel/helper-member-expression-to-functions': 7.12.7 - '@babel/helper-optimise-call-expression': 7.12.10 - '@babel/traverse': 7.12.12 - '@babel/types': 7.12.12 - resolution: - integrity: sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA== /@babel/helper-replace-supers/7.14.4: dependencies: '@babel/helper-member-expression-to-functions': 7.13.12 @@ -2445,11 +2459,6 @@ packages: node: '>=6.9.0' resolution: integrity: sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw== - /@babel/helper-simple-access/7.12.1: - dependencies: - '@babel/types': 7.12.12 - resolution: - integrity: sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== /@babel/helper-simple-access/7.13.12: dependencies: '@babel/types': 7.14.4 @@ -2487,6 +2496,7 @@ packages: /@babel/helper-split-export-declaration/7.12.11: dependencies: '@babel/types': 7.12.12 + dev: false resolution: integrity: sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g== /@babel/helper-split-export-declaration/7.12.13: @@ -2547,13 +2557,6 @@ packages: dev: false resolution: integrity: sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow== - /@babel/helpers/7.12.5: - dependencies: - '@babel/template': 7.12.7 - '@babel/traverse': 7.12.12 - '@babel/types': 7.12.12 - resolution: - integrity: sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== /@babel/helpers/7.14.0: dependencies: '@babel/template': 7.12.13 @@ -2614,6 +2617,7 @@ packages: resolution: integrity: sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== /@babel/parser/7.12.11: + dev: false engines: node: '>=6.0.0' hasBin: true @@ -2952,14 +2956,6 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w== - /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/helper-plugin-utils': 7.14.5 - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 @@ -2986,18 +2982,10 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/helper-plugin-utils': 7.13.0 - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.13.0 + '@babel/helper-plugin-utils': 7.14.5 dev: false peerDependencies: '@babel/core': ^7.0.0-0 @@ -3006,7 +2994,7 @@ packages: /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.14.3: dependencies: '@babel/core': 7.14.3 - '@babel/helper-plugin-utils': 7.13.0 + '@babel/helper-plugin-utils': 7.14.5 dev: true peerDependencies: '@babel/core': ^7.0.0-0 @@ -3015,20 +3003,11 @@ packages: /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.15.8: dependencies: '@babel/core': 7.15.8 - '@babel/helper-plugin-utils': 7.13.0 - dev: true - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 '@babel/helper-plugin-utils': 7.14.5 peerDependencies: '@babel/core': ^7.0.0-0 resolution: - integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 @@ -3109,18 +3088,10 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-1lBLLmtxrwpm4VKmtVFselI/P3pX+G63fAtUUt6b2Nzgao77KNDwyuRt90Mj2/9pKobtt68FdvjfqohZjg/FCA== - /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/helper-plugin-utils': 7.13.0 - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.13.0 + '@babel/helper-plugin-utils': 7.14.5 dev: false peerDependencies: '@babel/core': ^7.0.0-0 @@ -3129,7 +3100,7 @@ packages: /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.14.3: dependencies: '@babel/core': 7.14.3 - '@babel/helper-plugin-utils': 7.13.0 + '@babel/helper-plugin-utils': 7.14.5 dev: true peerDependencies: '@babel/core': ^7.0.0-0 @@ -3138,20 +3109,11 @@ packages: /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.15.8: dependencies: '@babel/core': 7.15.8 - '@babel/helper-plugin-utils': 7.13.0 - dev: true - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 '@babel/helper-plugin-utils': 7.14.5 peerDependencies: '@babel/core': ^7.0.0-0 resolution: - integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 @@ -3196,14 +3158,6 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== - /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/helper-plugin-utils': 7.13.0 - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 @@ -3230,14 +3184,6 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/helper-plugin-utils': 7.14.5 - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 @@ -3264,14 +3210,6 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/helper-plugin-utils': 7.13.0 - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 @@ -3298,14 +3236,6 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/helper-plugin-utils': 7.13.0 - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 @@ -3332,14 +3262,6 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/helper-plugin-utils': 7.13.0 - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 @@ -3366,14 +3288,6 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/helper-plugin-utils': 7.14.5 - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 @@ -3400,46 +3314,22 @@ packages: '@babel/core': ^7.0.0-0 resolution: integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - /@babel/plugin-syntax-top-level-await/7.12.13_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/helper-plugin-utils': 7.13.0 - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== - /@babel/plugin-syntax-top-level-await/7.12.13_@babel+core@7.12.3: + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 - '@babel/helper-plugin-utils': 7.13.0 + '@babel/helper-plugin-utils': 7.14.5 dev: false + engines: + node: '>=6.9.0' peerDependencies: '@babel/core': ^7.0.0-0 resolution: - integrity: sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== - /@babel/plugin-syntax-top-level-await/7.12.13_@babel+core@7.14.3: + integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.14.3: dependencies: '@babel/core': 7.14.3 - '@babel/helper-plugin-utils': 7.13.0 - dev: true - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== - /@babel/plugin-syntax-top-level-await/7.12.13_@babel+core@7.15.8: - dependencies: - '@babel/core': 7.15.8 - '@babel/helper-plugin-utils': 7.13.0 - dev: true - peerDependencies: - '@babel/core': ^7.0.0-0 - resolution: - integrity: sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== - /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.12.3: - dependencies: - '@babel/core': 7.12.3 '@babel/helper-plugin-utils': 7.14.5 - dev: false + dev: true engines: node: '>=6.9.0' peerDependencies: @@ -3450,7 +3340,6 @@ packages: dependencies: '@babel/core': 7.15.8 '@babel/helper-plugin-utils': 7.14.5 - dev: false engines: node: '>=6.9.0' peerDependencies: @@ -4538,6 +4427,7 @@ packages: '@babel/code-frame': 7.12.11 '@babel/parser': 7.12.11 '@babel/types': 7.12.12 + dev: false resolution: integrity: sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== /@babel/template/7.14.5: @@ -4558,19 +4448,6 @@ packages: node: '>=6.9.0' resolution: integrity: sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== - /@babel/traverse/7.12.12: - dependencies: - '@babel/code-frame': 7.12.11 - '@babel/generator': 7.12.11 - '@babel/helper-function-name': 7.12.11 - '@babel/helper-split-export-declaration': 7.12.11 - '@babel/parser': 7.12.11 - '@babel/types': 7.12.12 - debug: 4.3.1 - globals: 11.12.0 - lodash: 4.17.20 - resolution: - integrity: sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== /@babel/traverse/7.12.12_supports-color@5.5.0: dependencies: '@babel/code-frame': 7.12.11 @@ -4666,6 +4543,7 @@ packages: '@babel/helper-validator-identifier': 7.12.11 lodash: 4.17.20 to-fast-properties: 2.0.0 + dev: false resolution: integrity: sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== /@babel/types/7.14.0: @@ -4865,7 +4743,7 @@ packages: /@eslint/eslintrc/0.4.2: dependencies: ajv: 6.12.6 - debug: 4.3.1 + debug: 4.3.2 espree: 7.3.1 globals: 13.9.0 ignore: 4.0.6 @@ -4938,7 +4816,7 @@ packages: /@jest/console/26.6.2: dependencies: '@jest/types': 26.6.2 - '@types/node': 14.17.26 + '@types/node': 16.0.0 chalk: 4.1.2 jest-message-util: 26.6.2 jest-util: 26.6.2 @@ -4963,7 +4841,7 @@ packages: /@jest/console/27.2.5: dependencies: '@jest/types': 27.2.5 - '@types/node': 14.17.26 + '@types/node': 16.0.0 chalk: 4.1.2 jest-message-util: 27.2.5 jest-util: 27.2.5 @@ -4993,9 +4871,9 @@ packages: '@jest/test-result': 26.6.2 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - ansi-escapes: 4.3.1 - chalk: 4.1.0 + '@types/node': 16.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.4 jest-changed-files: 26.6.2 @@ -5011,11 +4889,11 @@ packages: jest-util: 26.6.2 jest-validate: 26.6.2 jest-watcher: 26.6.2 - micromatch: 4.0.2 + micromatch: 4.0.4 p-each-series: 2.2.0 rimraf: 3.0.2 slash: 3.0.0 - strip-ansi: 6.0.0 + strip-ansi: 6.0.1 engines: node: '>= 10.14.2' resolution: @@ -5027,9 +4905,9 @@ packages: '@jest/test-result': 26.6.2 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - ansi-escapes: 4.3.1 - chalk: 4.1.0 + '@types/node': 16.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.4 jest-changed-files: 26.6.2 @@ -5045,11 +4923,11 @@ packages: jest-util: 26.6.2 jest-validate: 26.6.2 jest-watcher: 26.6.2 - micromatch: 4.0.2 + micromatch: 4.0.4 p-each-series: 2.2.0 rimraf: 3.0.2 slash: 3.0.0 - strip-ansi: 6.0.0 + strip-ansi: 6.0.1 dev: true engines: node: '>= 10.14.2' @@ -5064,9 +4942,9 @@ packages: '@jest/test-result': 26.6.2 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - ansi-escapes: 4.3.1 - chalk: 4.1.0 + '@types/node': 16.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.4 jest-changed-files: 26.6.2 @@ -5082,11 +4960,11 @@ packages: jest-util: 26.6.2 jest-validate: 26.6.2 jest-watcher: 26.6.2 - micromatch: 4.0.2 + micromatch: 4.0.4 p-each-series: 2.2.0 rimraf: 3.0.2 slash: 3.0.0 - strip-ansi: 6.0.0 + strip-ansi: 6.0.1 dev: true engines: node: '>= 10.14.2' @@ -5102,9 +4980,9 @@ packages: '@jest/test-result': 26.6.2 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - ansi-escapes: 4.3.1 - chalk: 4.1.0 + '@types/node': 16.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.4 jest-changed-files: 26.6.2 @@ -5120,11 +4998,11 @@ packages: jest-util: 26.6.2 jest-validate: 26.6.2 jest-watcher: 26.6.2 - micromatch: 4.0.2 + micromatch: 4.0.4 p-each-series: 2.2.0 rimraf: 3.0.2 slash: 3.0.0 - strip-ansi: 6.0.0 + strip-ansi: 6.0.1 dev: true engines: node: '>= 10.14.2' @@ -5261,7 +5139,7 @@ packages: dependencies: '@jest/types': 26.6.2 '@sinonjs/fake-timers': 6.0.1 - '@types/node': 14.17.26 + '@types/node': 16.0.0 jest-message-util: 26.6.2 jest-mock: 26.6.2 jest-util: 26.6.2 @@ -6459,7 +6337,6 @@ packages: resolution: integrity: sha512-cczlgVl+krjOb3j1625usarNEibI0IFRJrSWX9UsJ1HKYFgCQv9Nb7QAipUDXl3Xdz8NDTsiS78eAkPSxlzTlw== /@tootallnate/once/1.1.2: - dev: true engines: node: '>= 6' resolution: @@ -6890,9 +6767,6 @@ packages: /@types/node/14.14.35: resolution: integrity: sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag== - /@types/node/14.17.26: - resolution: - integrity: sha512-eSTNkK/nfmnC7IKpOJZixDgG0W2/eHz1qyFN7o/rwwwIHsVRp+G9nbh4BrQ77kbQ2zPu286AQRxkuRLPcR3gXw== /@types/node/15.0.1: dev: true resolution: @@ -7246,11 +7120,6 @@ packages: '@types/yargs-parser': 20.2.0 resolution: integrity: sha512-NRqD6T4gktUrDi1o1wLH3EKC1o2caCr7/wR87ODcbVITQF106OM3sFN92ysZ++wqelOd1CTzatnOBRDYYG6wGQ== - /@types/yargs/15.0.12: - dependencies: - '@types/yargs-parser': 20.2.0 - resolution: - integrity: sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw== /@types/yargs/15.0.13: dependencies: '@types/yargs-parser': 20.2.0 @@ -7464,7 +7333,6 @@ packages: semver: 7.3.5 tsutils: 3.21.0_typescript@4.3.5 typescript: 4.3.5 - dev: false engines: node: ^10.12.0 || >=12.0.0 peerDependencies: @@ -7740,7 +7608,6 @@ packages: eslint: 7.29.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0_eslint@7.29.0 - dev: false engines: node: ^10.12.0 || >=12.0.0 peerDependencies: @@ -8060,7 +7927,6 @@ packages: debug: 4.3.2 eslint: 7.29.0 typescript: 4.3.5 - dev: false engines: node: ^10.12.0 || >=12.0.0 peerDependencies: @@ -8109,7 +7975,6 @@ packages: dependencies: '@typescript-eslint/types': 4.30.0 '@typescript-eslint/visitor-keys': 4.30.0 - dev: false engines: node: ^8.10.0 || ^10.13.0 || >=11.10.1 resolution: @@ -8143,7 +8008,6 @@ packages: resolution: integrity: sha512-s1eV1lKNgoIYLAl1JUba8NhULmf+jOmmeFO1G5MN/RBCyyzg4TIOfIOICVNC06lor+Xmy4FypIIhFiJXOknhIg== /@typescript-eslint/types/4.30.0: - dev: false engines: node: ^8.10.0 || ^10.13.0 || >=11.10.1 resolution: @@ -8318,7 +8182,6 @@ packages: semver: 7.3.5 tsutils: 3.21.0_typescript@4.3.5 typescript: 4.3.5 - dev: false engines: node: ^10.12.0 || >=12.0.0 peerDependencies: @@ -8374,7 +8237,6 @@ packages: dependencies: '@typescript-eslint/types': 4.30.0 eslint-visitor-keys: 2.1.0 - dev: false engines: node: ^8.10.0 || ^10.13.0 || >=11.10.1 resolution: @@ -8598,15 +8460,7 @@ packages: hasBin: true resolution: integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - /acorn/8.3.0: - dev: true - engines: - node: '>=0.4.0' - hasBin: true - resolution: - integrity: sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw== /acorn/8.5.0: - dev: true engines: node: '>=0.4.0' hasBin: true @@ -8629,7 +8483,6 @@ packages: /agent-base/6.0.2: dependencies: debug: 4.3.2 - dev: true engines: node: '>= 6.0.0' resolution: @@ -8987,9 +8840,11 @@ packages: /asn1/0.2.4: dependencies: safer-buffer: 2.1.2 + dev: true resolution: integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== /assert-plus/1.0.0: + dev: true engines: node: '>=0.8' resolution: @@ -9065,9 +8920,11 @@ packages: resolution: integrity: sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== /aws-sign2/0.7.0: + dev: true resolution: integrity: sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= /aws4/1.11.0: + dev: true resolution: integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== /axe-core/4.3.3: @@ -9077,7 +8934,7 @@ packages: integrity: sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA== /axios/0.21.1_debug@4.3.1: dependencies: - follow-redirects: 1.14.1_debug@4.3.1 + follow-redirects: 1.14.1_debug@4.3.2 dev: true peerDependencies: debug: '*' @@ -9111,35 +8968,35 @@ packages: node: '>=4' resolution: integrity: sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ== - /babel-jest/26.6.3_@babel+core@7.12.10: + /babel-jest/26.6.3_@babel+core@7.12.3: dependencies: - '@babel/core': 7.12.10 + '@babel/core': 7.12.3 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 '@types/babel__core': 7.1.16 babel-plugin-istanbul: 6.0.0 - babel-preset-jest: 26.6.2_@babel+core@7.12.10 + babel-preset-jest: 26.6.2_@babel+core@7.12.3 chalk: 4.1.2 graceful-fs: 4.2.4 slash: 3.0.0 + dev: false engines: node: '>= 10.14.2' peerDependencies: '@babel/core': ^7.0.0 resolution: integrity: sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== - /babel-jest/26.6.3_@babel+core@7.12.3: + /babel-jest/26.6.3_@babel+core@7.15.8: dependencies: - '@babel/core': 7.12.3 + '@babel/core': 7.15.8 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 '@types/babel__core': 7.1.16 babel-plugin-istanbul: 6.0.0 - babel-preset-jest: 26.6.2_@babel+core@7.12.3 + babel-preset-jest: 26.6.2_@babel+core@7.15.8 chalk: 4.1.2 graceful-fs: 4.2.4 slash: 3.0.0 - dev: false engines: node: '>= 10.14.2' peerDependencies: @@ -9331,25 +9188,6 @@ packages: dev: false resolution: integrity: sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== - /babel-preset-current-node-syntax/1.0.1_@babel+core@7.12.10: - dependencies: - '@babel/core': 7.12.10 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.12.10 - '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.12.10 - '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.12.10 - '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.12.10 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.12.10 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.12.10 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.12.10 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.12.10 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.12.10 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.12.10 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.12.10 - '@babel/plugin-syntax-top-level-await': 7.12.13_@babel+core@7.12.10 - peerDependencies: - '@babel/core': ^7.0.0 - resolution: - integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== /babel-preset-current-node-syntax/1.0.1_@babel+core@7.12.3: dependencies: '@babel/core': 7.12.3 @@ -9364,7 +9202,7 @@ packages: '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.12.3 '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.12.3 '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.12.3 - '@babel/plugin-syntax-top-level-await': 7.12.13_@babel+core@7.12.3 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.12.3 dev: false peerDependencies: '@babel/core': ^7.0.0 @@ -9384,7 +9222,7 @@ packages: '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.14.3 '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.14.3 '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.14.3 - '@babel/plugin-syntax-top-level-await': 7.12.13_@babel+core@7.14.3 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.14.3 dev: true peerDependencies: '@babel/core': ^7.0.0 @@ -9404,29 +9242,28 @@ packages: '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.15.8 '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.15.8 '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.15.8 - '@babel/plugin-syntax-top-level-await': 7.12.13_@babel+core@7.15.8 - dev: true + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.15.8 peerDependencies: '@babel/core': ^7.0.0 resolution: integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - /babel-preset-jest/26.6.2_@babel+core@7.12.10: + /babel-preset-jest/26.6.2_@babel+core@7.12.3: dependencies: - '@babel/core': 7.12.10 + '@babel/core': 7.12.3 babel-plugin-jest-hoist: 26.6.2 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.12.10 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.12.3 + dev: false engines: node: '>= 10.14.2' peerDependencies: '@babel/core': ^7.0.0 resolution: integrity: sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== - /babel-preset-jest/26.6.2_@babel+core@7.12.3: + /babel-preset-jest/26.6.2_@babel+core@7.15.8: dependencies: - '@babel/core': 7.12.3 + '@babel/core': 7.15.8 babel-plugin-jest-hoist: 26.6.2 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.12.3 - dev: false + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.15.8 engines: node: '>= 10.14.2' peerDependencies: @@ -9519,6 +9356,7 @@ packages: /bcrypt-pbkdf/1.0.2: dependencies: tweetnacl: 0.14.5 + dev: true resolution: integrity: sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= /benchmark/2.1.4: @@ -10012,6 +9850,7 @@ packages: resolution: integrity: sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ== /caseless/0.12.0: + dev: true resolution: integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= /chalk/1.1.3: @@ -10262,7 +10101,7 @@ packages: /cli-truncate/2.1.0: dependencies: slice-ansi: 3.0.0 - string-width: 4.2.2 + string-width: 4.2.3 dev: true engines: node: '>=8' @@ -11191,6 +11030,7 @@ packages: /dashdash/1.14.1: dependencies: assert-plus: 1.0.0 + dev: true engines: node: '>=0.10' resolution: @@ -11336,11 +11176,7 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - /decimal.js/10.2.1: - resolution: - integrity: sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== /decimal.js/10.3.1: - dev: true resolution: integrity: sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== /decode-uri-component/0.2.0: @@ -11392,9 +11228,6 @@ packages: node: '>=4.0.0' resolution: integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - /deep-is/0.1.3: - resolution: - integrity: sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= /deep-is/0.1.4: resolution: integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== @@ -11740,6 +11573,7 @@ packages: dependencies: jsbn: 0.1.1 safer-buffer: 2.1.2 + dev: true resolution: integrity: sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= /ee-first/1.1.1: @@ -12003,26 +11837,12 @@ packages: node: '>=10' resolution: integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - /escodegen/1.14.3: - dependencies: - esprima: 4.0.1 - estraverse: 4.3.0 - esutils: 2.0.3 - optionator: 0.8.3 - engines: - node: '>=4.0' - hasBin: true - optionalDependencies: - source-map: 0.6.1 - resolution: - integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== /escodegen/2.0.0: dependencies: esprima: 4.0.1 estraverse: 5.3.0 esutils: 2.0.3 optionator: 0.8.3 - dev: true engines: node: '>=6.0' hasBin: true @@ -12287,6 +12107,15 @@ packages: eslint: '>=7.0.0' resolution: integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== + /eslint-config-prettier/8.3.0_eslint@7.29.0: + dependencies: + eslint: 7.29.0 + dev: true + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + resolution: + integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== /eslint-config-react-app/5.2.1_02b4072a867835d3744dd8fbd8b48cd4: dependencies: '@typescript-eslint/eslint-plugin': 4.29.3_45bc00290c8c374316d6c2f3e2573c27 @@ -12543,7 +12372,6 @@ packages: '@typescript-eslint/parser': 4.29.3_eslint@7.29.0+typescript@4.3.5 debug: 3.2.7 pkg-dir: 2.0.0 - dev: false engines: node: '>=4' peerDependencies: @@ -12917,7 +12745,6 @@ packages: read-pkg-up: 3.0.0 resolve: 1.20.0 tsconfig-paths: 3.11.0 - dev: false engines: node: '>=4' peerDependencies: @@ -13242,6 +13069,24 @@ packages: optional: true resolution: integrity: sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g== + /eslint-plugin-prettier/3.4.1_4e72879372edbffcbdaf0fa17b22c203: + dependencies: + eslint: 7.29.0 + eslint-config-prettier: 8.3.0_eslint@7.29.0 + prettier: 2.3.2 + prettier-linter-helpers: 1.0.0 + dev: true + engines: + node: '>=6.0.0' + peerDependencies: + eslint: '>=5.0.0' + eslint-config-prettier: '*' + prettier: '>=1.13.0' + peerDependenciesMeta: + eslint-config-prettier: + optional: true + resolution: + integrity: sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g== /eslint-plugin-prettier/3.4.1_7c5f1f59332aa465fcd97b1399d2f1c7: dependencies: eslint: 7.17.0 @@ -13523,7 +13368,6 @@ packages: dependencies: eslint: 7.29.0 eslint-visitor-keys: 2.1.0 - dev: false engines: node: ^10.0.0 || ^12.0.0 || >= 14.0.0 peerDependencies: @@ -13930,7 +13774,6 @@ packages: resolution: integrity: sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== /estraverse/5.3.0: - dev: true engines: node: '>=4.0' resolution: @@ -14071,11 +13914,11 @@ packages: cross-spawn: 7.0.3 get-stream: 6.0.1 human-signals: 2.1.0 - is-stream: 2.0.0 + is-stream: 2.0.1 merge-stream: 2.0.0 npm-run-path: 4.0.1 onetime: 5.1.2 - signal-exit: 3.0.3 + signal-exit: 3.0.5 strip-final-newline: 2.0.0 dev: true engines: @@ -14229,6 +14072,7 @@ packages: resolution: integrity: sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= /extend/3.0.2: + dev: true resolution: integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== /extglob/2.0.4: @@ -14271,6 +14115,7 @@ packages: resolution: integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== /extsprintf/1.3.0: + dev: true engines: '0': node >=0.6.0 resolution: @@ -14309,18 +14154,6 @@ packages: node: '>=8' resolution: integrity: sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== - /fast-glob/3.2.6: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.7 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.4 - dev: true - engines: - node: '>=8' - resolution: - integrity: sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ== /fast-glob/3.2.7: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -14587,9 +14420,21 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc= + /follow-redirects/1.14.1: + dev: false + engines: + node: '>=4.0' + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + resolution: + integrity: sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== /follow-redirects/1.14.1_debug@4.3.1: dependencies: debug: 4.3.1 + dev: false engines: node: '>=4.0' peerDependencies: @@ -14602,7 +14447,6 @@ packages: /follow-redirects/1.14.1_debug@4.3.2: dependencies: debug: 4.3.2 - dev: false engines: node: '>=4.0' peerDependencies: @@ -14618,6 +14462,7 @@ packages: resolution: integrity: sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= /forever-agent/0.6.1: + dev: true resolution: integrity: sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= /fork-ts-checker-webpack-plugin/4.1.6: @@ -14639,6 +14484,7 @@ packages: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.31 + dev: true engines: node: '>= 0.12' resolution: @@ -14658,7 +14504,6 @@ packages: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.33 - dev: true engines: node: '>= 6' resolution: @@ -14879,6 +14724,7 @@ packages: /getpass/0.1.7: dependencies: assert-plus: 1.0.0 + dev: true resolution: integrity: sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= /git-hooks-list/1.0.3: @@ -15006,8 +14852,8 @@ packages: '@types/glob': 7.1.3 array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.2.6 - glob: 7.1.7 + fast-glob: 3.2.7 + glob: 7.2.0 ignore: 5.1.8 merge2: 1.4.1 slash: 3.0.0 @@ -15130,6 +14976,7 @@ packages: resolution: integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== /har-schema/2.0.0: + dev: true engines: node: '>=4' resolution: @@ -15139,6 +14986,7 @@ packages: ajv: 6.12.6 har-schema: 2.0.0 deprecated: this library is no longer supported + dev: true engines: node: '>=6' resolution: @@ -15443,7 +15291,6 @@ packages: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 debug: 4.3.2 - dev: true engines: node: '>= 6' resolution: @@ -15504,7 +15351,7 @@ packages: /http-proxy/1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.14.1_debug@4.3.1 + follow-redirects: 1.14.1 requires-port: 1.0.0 dev: false engines: @@ -15540,6 +15387,7 @@ packages: assert-plus: 1.0.0 jsprim: 1.4.1 sshpk: 1.16.1 + dev: true engines: node: '>=0.8' npm: '>=1.3.7' @@ -15562,7 +15410,6 @@ packages: dependencies: agent-base: 6.0.2 debug: 4.3.2 - dev: true engines: node: '>= 6' resolution: @@ -15692,6 +15539,7 @@ packages: dependencies: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 + dev: true engines: node: '>=8' hasBin: true @@ -15788,6 +15636,7 @@ packages: resolution: integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== /ip-regex/2.1.0: + dev: false engines: node: '>=4' resolution: @@ -16221,11 +16070,7 @@ packages: node: '>=0.10.0' resolution: integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - /is-potential-custom-element-name/1.0.0: - resolution: - integrity: sha1-DFLlS8yjkbssSUsh6GJtczbG45c= /is-potential-custom-element-name/1.0.1: - dev: true resolution: integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== /is-promise/2.2.2: @@ -16377,6 +16222,7 @@ packages: resolution: integrity: sha1-TkMekrEalzFjaqH5yNHMvP2reN8= /isstream/0.1.2: + dev: true resolution: integrity: sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= /istanbul-lib-coverage/3.0.0: @@ -16579,15 +16425,15 @@ packages: '@jest/core': 26.6.3 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - chalk: 4.1.0 + chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.4 - import-local: 3.0.2 + import-local: 3.0.3 is-ci: 2.0.0 jest-config: 26.6.3 jest-util: 26.6.2 jest-validate: 26.6.2 - prompts: 2.4.0 + prompts: 2.4.2 yargs: 15.4.1 engines: node: '>= 10.14.2' @@ -16599,15 +16445,15 @@ packages: '@jest/core': 26.6.3_canvas@2.6.1 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - chalk: 4.1.0 + chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.4 - import-local: 3.0.2 + import-local: 3.0.3 is-ci: 2.0.0 jest-config: 26.6.3_canvas@2.6.1 jest-util: 26.6.2 jest-validate: 26.6.2 - prompts: 2.4.0 + prompts: 2.4.2 yargs: 15.4.1 dev: true engines: @@ -16622,15 +16468,15 @@ packages: '@jest/core': 26.6.3_canvas@2.6.1+ts-node@9.1.1 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - chalk: 4.1.0 + chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.4 - import-local: 3.0.2 + import-local: 3.0.3 is-ci: 2.0.0 jest-config: 26.6.3_canvas@2.6.1+ts-node@9.1.1 jest-util: 26.6.2 jest-validate: 26.6.2 - prompts: 2.4.0 + prompts: 2.4.2 yargs: 15.4.1 dev: true engines: @@ -16646,15 +16492,15 @@ packages: '@jest/core': 26.6.3_ts-node@9.1.1 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - chalk: 4.1.0 + chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.4 - import-local: 3.0.2 + import-local: 3.0.3 is-ci: 2.0.0 jest-config: 26.6.3_ts-node@9.1.1 jest-util: 26.6.2 jest-validate: 26.6.2 - prompts: 2.4.0 + prompts: 2.4.2 yargs: 15.4.1 dev: true engines: @@ -16716,13 +16562,13 @@ packages: integrity: sha512-WHnCqpfK+6EvT62me6WVs8NhtbjAS4/6vZJnk7/2+oOr50cwAzG4Wxt6RXX0hu6m1169ZGMlhYYUNeKBXCph/Q== /jest-config/26.6.3: dependencies: - '@babel/core': 7.12.10 + '@babel/core': 7.15.8 '@jest/test-sequencer': 26.6.3 '@jest/types': 26.6.2 - babel-jest: 26.6.3_@babel+core@7.12.10 - chalk: 4.1.0 + babel-jest: 26.6.3_@babel+core@7.15.8 + chalk: 4.1.2 deepmerge: 4.2.2 - glob: 7.1.6 + glob: 7.2.0 graceful-fs: 4.2.4 jest-environment-jsdom: 26.6.2 jest-environment-node: 26.6.2 @@ -16732,7 +16578,7 @@ packages: jest-resolve: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 - micromatch: 4.0.2 + micromatch: 4.0.4 pretty-format: 26.6.2 engines: node: '>= 10.14.2' @@ -16745,13 +16591,13 @@ packages: integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== /jest-config/26.6.3_canvas@2.6.1: dependencies: - '@babel/core': 7.12.10 + '@babel/core': 7.15.8 '@jest/test-sequencer': 26.6.3_canvas@2.6.1 '@jest/types': 26.6.2 - babel-jest: 26.6.3_@babel+core@7.12.10 - chalk: 4.1.0 + babel-jest: 26.6.3_@babel+core@7.15.8 + chalk: 4.1.2 deepmerge: 4.2.2 - glob: 7.1.6 + glob: 7.2.0 graceful-fs: 4.2.4 jest-environment-jsdom: 26.6.2_canvas@2.6.1 jest-environment-node: 26.6.2 @@ -16761,7 +16607,7 @@ packages: jest-resolve: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 - micromatch: 4.0.2 + micromatch: 4.0.4 pretty-format: 26.6.2 dev: true engines: @@ -16776,13 +16622,13 @@ packages: integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== /jest-config/26.6.3_canvas@2.6.1+ts-node@9.1.1: dependencies: - '@babel/core': 7.12.10 + '@babel/core': 7.15.8 '@jest/test-sequencer': 26.6.3_canvas@2.6.1+ts-node@9.1.1 '@jest/types': 26.6.2 - babel-jest: 26.6.3_@babel+core@7.12.10 - chalk: 4.1.0 + babel-jest: 26.6.3_@babel+core@7.15.8 + chalk: 4.1.2 deepmerge: 4.2.2 - glob: 7.1.6 + glob: 7.2.0 graceful-fs: 4.2.4 jest-environment-jsdom: 26.6.2_canvas@2.6.1 jest-environment-node: 26.6.2 @@ -16792,7 +16638,7 @@ packages: jest-resolve: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 - micromatch: 4.0.2 + micromatch: 4.0.4 pretty-format: 26.6.2 ts-node: 9.1.1_typescript@4.3.5 dev: true @@ -16808,13 +16654,13 @@ packages: integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== /jest-config/26.6.3_ts-node@9.1.1: dependencies: - '@babel/core': 7.12.10 + '@babel/core': 7.15.8 '@jest/test-sequencer': 26.6.3_ts-node@9.1.1 '@jest/types': 26.6.2 - babel-jest: 26.6.3_@babel+core@7.12.10 - chalk: 4.1.0 + babel-jest: 26.6.3_@babel+core@7.15.8 + chalk: 4.1.2 deepmerge: 4.2.2 - glob: 7.1.6 + glob: 7.2.0 graceful-fs: 4.2.4 jest-environment-jsdom: 26.6.2 jest-environment-node: 26.6.2 @@ -16824,7 +16670,7 @@ packages: jest-resolve: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 - micromatch: 4.0.2 + micromatch: 4.0.4 pretty-format: 26.6.2 ts-node: 9.1.1_typescript@4.3.5 dev: true @@ -17023,7 +16869,7 @@ packages: '@jest/fake-timers': 25.5.0 jest-mock: 25.5.0 jest-util: 25.5.0 - jsdom: 16.6.0 + jsdom: 16.7.0 dev: true engines: node: ^10.14.2 || >= 12.0.0 @@ -17034,10 +16880,10 @@ packages: '@jest/environment': 26.6.2 '@jest/fake-timers': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 + '@types/node': 16.0.0 jest-mock: 26.6.2 jest-util: 26.6.2 - jsdom: 16.4.0 + jsdom: 16.7.0 engines: node: '>= 10.14.2' resolution: @@ -17047,10 +16893,10 @@ packages: '@jest/environment': 26.6.2 '@jest/fake-timers': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 + '@types/node': 16.0.0 jest-mock: 26.6.2 jest-util: 26.6.2 - jsdom: 16.4.0_canvas@2.6.1 + jsdom: 16.7.0_canvas@2.6.1 dev: true engines: node: '>= 10.14.2' @@ -17066,7 +16912,7 @@ packages: '@types/node': 15.6.2 jest-mock: 27.0.3 jest-util: 27.0.2 - jsdom: 16.6.0 + jsdom: 16.7.0 dev: true engines: node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0 @@ -17091,7 +16937,7 @@ packages: '@jest/environment': 26.6.2 '@jest/fake-timers': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.17.26 + '@types/node': 16.0.0 jest-mock: 26.6.2 jest-util: 26.6.2 engines: @@ -17162,7 +17008,7 @@ packages: dependencies: '@jest/types': 26.6.2 '@types/graceful-fs': 4.1.5 - '@types/node': 14.17.26 + '@types/node': 16.0.0 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.4 @@ -17223,13 +17069,13 @@ packages: integrity: sha512-lYfNZIzwPccDJZIyk9Iz5iQMM/MH56NIIcGj7AFU1YyA4ewWFBl8z+YPJuSCRML/ee2cCt2y3W4K3VXPT6Nhzg== /jest-jasmine2/26.6.3: dependencies: - '@babel/traverse': 7.12.12 + '@babel/traverse': 7.15.4 '@jest/environment': 26.6.2 '@jest/source-map': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - chalk: 4.1.0 + '@types/node': 16.0.0 + chalk: 4.1.2 co: 4.6.0 expect: 26.6.2 is-generator-fn: 2.1.0 @@ -17247,13 +17093,13 @@ packages: integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== /jest-jasmine2/26.6.3_canvas@2.6.1: dependencies: - '@babel/traverse': 7.12.12 + '@babel/traverse': 7.15.4 '@jest/environment': 26.6.2 '@jest/source-map': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - chalk: 4.1.0 + '@types/node': 16.0.0 + chalk: 4.1.2 co: 4.6.0 expect: 26.6.2 is-generator-fn: 2.1.0 @@ -17274,13 +17120,13 @@ packages: integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== /jest-jasmine2/26.6.3_canvas@2.6.1+ts-node@9.1.1: dependencies: - '@babel/traverse': 7.12.12 + '@babel/traverse': 7.15.4 '@jest/environment': 26.6.2 '@jest/source-map': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - chalk: 4.1.0 + '@types/node': 16.0.0 + chalk: 4.1.2 co: 4.6.0 expect: 26.6.2 is-generator-fn: 2.1.0 @@ -17302,13 +17148,13 @@ packages: integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== /jest-jasmine2/26.6.3_ts-node@9.1.1: dependencies: - '@babel/traverse': 7.12.12 + '@babel/traverse': 7.15.4 '@jest/environment': 26.6.2 '@jest/source-map': 26.6.2 '@jest/test-result': 26.6.2 - '@jest/types': 26.6.2 - '@types/node': 14.14.21 - chalk: 4.1.0 + '@jest/types': 26.6.2 + '@types/node': 16.0.0 + chalk: 4.1.2 co: 4.6.0 expect: 26.6.2 is-generator-fn: 2.1.0 @@ -17535,7 +17381,7 @@ packages: /jest-mock/26.6.2: dependencies: '@jest/types': 26.6.2 - '@types/node': 14.17.26 + '@types/node': 16.0.0 engines: node: '>= 10.14.2' resolution: @@ -17723,8 +17569,8 @@ packages: '@jest/environment': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - chalk: 4.1.0 + '@types/node': 16.0.0 + chalk: 4.1.2 emittery: 0.7.2 exit: 0.1.2 graceful-fs: 4.2.4 @@ -17737,7 +17583,7 @@ packages: jest-runtime: 26.6.3 jest-util: 26.6.2 jest-worker: 26.6.2 - source-map-support: 0.5.19 + source-map-support: 0.5.20 throat: 5.0.0 engines: node: '>= 10.14.2' @@ -17749,8 +17595,8 @@ packages: '@jest/environment': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - chalk: 4.1.0 + '@types/node': 16.0.0 + chalk: 4.1.2 emittery: 0.7.2 exit: 0.1.2 graceful-fs: 4.2.4 @@ -17763,7 +17609,7 @@ packages: jest-runtime: 26.6.3_canvas@2.6.1 jest-util: 26.6.2 jest-worker: 26.6.2 - source-map-support: 0.5.19 + source-map-support: 0.5.20 throat: 5.0.0 dev: true engines: @@ -17778,8 +17624,8 @@ packages: '@jest/environment': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - chalk: 4.1.0 + '@types/node': 16.0.0 + chalk: 4.1.2 emittery: 0.7.2 exit: 0.1.2 graceful-fs: 4.2.4 @@ -17792,7 +17638,7 @@ packages: jest-runtime: 26.6.3_canvas@2.6.1+ts-node@9.1.1 jest-util: 26.6.2 jest-worker: 26.6.2 - source-map-support: 0.5.19 + source-map-support: 0.5.20 throat: 5.0.0 dev: true engines: @@ -17808,8 +17654,8 @@ packages: '@jest/environment': 26.6.2 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.14.21 - chalk: 4.1.0 + '@types/node': 16.0.0 + chalk: 4.1.2 emittery: 0.7.2 exit: 0.1.2 graceful-fs: 4.2.4 @@ -17822,7 +17668,7 @@ packages: jest-runtime: 26.6.3_ts-node@9.1.1 jest-util: 26.6.2 jest-worker: 26.6.2 - source-map-support: 0.5.19 + source-map-support: 0.5.20 throat: 5.0.0 dev: true engines: @@ -17897,12 +17743,12 @@ packages: '@jest/test-result': 26.6.2 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 - '@types/yargs': 15.0.12 - chalk: 4.1.0 + '@types/yargs': 15.0.14 + chalk: 4.1.2 cjs-module-lexer: 0.6.0 collect-v8-coverage: 1.0.1 exit: 0.1.2 - glob: 7.1.6 + glob: 7.2.0 graceful-fs: 4.2.4 jest-config: 26.6.3 jest-haste-map: 26.6.2 @@ -17931,12 +17777,12 @@ packages: '@jest/test-result': 26.6.2 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 - '@types/yargs': 15.0.12 - chalk: 4.1.0 + '@types/yargs': 15.0.14 + chalk: 4.1.2 cjs-module-lexer: 0.6.0 collect-v8-coverage: 1.0.1 exit: 0.1.2 - glob: 7.1.6 + glob: 7.2.0 graceful-fs: 4.2.4 jest-config: 26.6.3_canvas@2.6.1 jest-haste-map: 26.6.2 @@ -17968,12 +17814,12 @@ packages: '@jest/test-result': 26.6.2 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 - '@types/yargs': 15.0.12 - chalk: 4.1.0 + '@types/yargs': 15.0.14 + chalk: 4.1.2 cjs-module-lexer: 0.6.0 collect-v8-coverage: 1.0.1 exit: 0.1.2 - glob: 7.1.6 + glob: 7.2.0 graceful-fs: 4.2.4 jest-config: 26.6.3_canvas@2.6.1+ts-node@9.1.1 jest-haste-map: 26.6.2 @@ -18006,12 +17852,12 @@ packages: '@jest/test-result': 26.6.2 '@jest/transform': 26.6.2 '@jest/types': 26.6.2 - '@types/yargs': 15.0.12 - chalk: 4.1.0 + '@types/yargs': 15.0.14 + chalk: 4.1.2 cjs-module-lexer: 0.6.0 collect-v8-coverage: 1.0.1 exit: 0.1.2 - glob: 7.1.6 + glob: 7.2.0 graceful-fs: 4.2.4 jest-config: 26.6.3_ts-node@9.1.1 jest-haste-map: 26.6.2 @@ -18101,7 +17947,7 @@ packages: integrity: sha512-qtO6VxPbS8umqhEDpjA4pqTkKQ1Hy4ZSi9mDVeE9Za7LKBo2LdW2jmT+Iod3XFaJqINikZQsn2wEi0j9wPRbLg== /jest-serializer/26.6.2: dependencies: - '@types/node': 14.17.26 + '@types/node': 16.0.0 graceful-fs: 4.2.4 engines: node: '>= 10.14.2' @@ -18233,7 +18079,7 @@ packages: /jest-util/26.6.2: dependencies: '@jest/types': 26.6.2 - '@types/node': 14.17.26 + '@types/node': 16.0.0 chalk: 4.1.2 graceful-fs: 4.2.4 is-ci: 2.0.0 @@ -18258,7 +18104,7 @@ packages: /jest-util/27.2.5: dependencies: '@jest/types': 27.2.5 - '@types/node': 14.17.26 + '@types/node': 16.0.0 chalk: 4.1.2 graceful-fs: 4.2.4 is-ci: 3.0.0 @@ -18425,7 +18271,7 @@ packages: dependencies: '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 - '@types/node': 14.17.26 + '@types/node': 16.0.0 ansi-escapes: 4.3.2 chalk: 4.1.2 jest-util: 26.6.2 @@ -18452,7 +18298,7 @@ packages: dependencies: '@jest/test-result': 27.2.5 '@jest/types': 27.2.5 - '@types/node': 14.17.26 + '@types/node': 16.0.0 ansi-escapes: 4.3.2 chalk: 4.1.2 jest-util: 27.2.5 @@ -18528,7 +18374,7 @@ packages: /jest/26.6.3: dependencies: '@jest/core': 26.6.3 - import-local: 3.0.2 + import-local: 3.0.3 jest-cli: 26.6.3 dev: true engines: @@ -18539,7 +18385,7 @@ packages: /jest/26.6.3_canvas@2.6.1: dependencies: '@jest/core': 26.6.3_canvas@2.6.1 - import-local: 3.0.2 + import-local: 3.0.3 jest-cli: 26.6.3_canvas@2.6.1 dev: true engines: @@ -18552,7 +18398,7 @@ packages: /jest/26.6.3_canvas@2.6.1+ts-node@9.1.1: dependencies: '@jest/core': 26.6.3_canvas@2.6.1+ts-node@9.1.1 - import-local: 3.0.2 + import-local: 3.0.3 jest-cli: 26.6.3_canvas@2.6.1+ts-node@9.1.1 dev: true engines: @@ -18566,7 +18412,7 @@ packages: /jest/26.6.3_ts-node@9.1.1: dependencies: '@jest/core': 26.6.3_ts-node@9.1.1 - import-local: 3.0.2 + import-local: 3.0.3 jest-cli: 26.6.3_ts-node@9.1.1 dev: true engines: @@ -18637,93 +18483,18 @@ packages: resolution: integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== /jsbn/0.1.1: - resolution: - integrity: sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - /jsdom/16.4.0: - dependencies: - abab: 2.0.5 - acorn: 7.4.1 - acorn-globals: 6.0.0 - cssom: 0.4.4 - cssstyle: 2.3.0 - data-urls: 2.0.0 - decimal.js: 10.2.1 - domexception: 2.0.1 - escodegen: 1.14.3 - html-encoding-sniffer: 2.0.1 - is-potential-custom-element-name: 1.0.0 - nwsapi: 2.2.0 - parse5: 5.1.1 - request: 2.88.2 - request-promise-native: 1.0.9_request@2.88.2 - saxes: 5.0.1 - symbol-tree: 3.2.4 - tough-cookie: 3.0.1 - w3c-hr-time: 1.0.2 - w3c-xmlserializer: 2.0.0 - webidl-conversions: 6.1.0 - whatwg-encoding: 1.0.5 - whatwg-mimetype: 2.3.0 - whatwg-url: 8.4.0 - ws: 7.4.3 - xml-name-validator: 3.0.0 - engines: - node: '>=10' - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - resolution: - integrity: sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w== - /jsdom/16.4.0_canvas@2.6.1: - dependencies: - abab: 2.0.5 - acorn: 7.4.1 - acorn-globals: 6.0.0 - canvas: 2.6.1 - cssom: 0.4.4 - cssstyle: 2.3.0 - data-urls: 2.0.0 - decimal.js: 10.2.1 - domexception: 2.0.1 - escodegen: 1.14.3 - html-encoding-sniffer: 2.0.1 - is-potential-custom-element-name: 1.0.0 - nwsapi: 2.2.0 - parse5: 5.1.1 - request: 2.88.2 - request-promise-native: 1.0.9_request@2.88.2 - saxes: 5.0.1 - symbol-tree: 3.2.4 - tough-cookie: 3.0.1 - w3c-hr-time: 1.0.2 - w3c-xmlserializer: 2.0.0 - webidl-conversions: 6.1.0 - whatwg-encoding: 1.0.5 - whatwg-mimetype: 2.3.0 - whatwg-url: 8.4.0 - ws: 7.4.3 - xml-name-validator: 3.0.0 dev: true - engines: - node: '>=10' - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true resolution: - integrity: sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w== - /jsdom/16.6.0: + integrity: sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + /jsdom/16.7.0: dependencies: abab: 2.0.5 - acorn: 8.3.0 + acorn: 8.5.0 acorn-globals: 6.0.0 cssom: 0.4.4 cssstyle: 2.3.0 data-urls: 2.0.0 - decimal.js: 10.2.1 + decimal.js: 10.3.1 domexception: 2.0.1 escodegen: 2.0.0 form-data: 3.0.1 @@ -18741,10 +18512,9 @@ packages: webidl-conversions: 6.1.0 whatwg-encoding: 1.0.5 whatwg-mimetype: 2.3.0 - whatwg-url: 8.5.0 - ws: 7.4.6 + whatwg-url: 8.7.0 + ws: 7.5.5 xml-name-validator: 3.0.0 - dev: true engines: node: '>=10' peerDependencies: @@ -18753,12 +18523,13 @@ packages: canvas: optional: true resolution: - integrity: sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg== - /jsdom/16.7.0: + integrity: sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== + /jsdom/16.7.0_canvas@2.6.1: dependencies: abab: 2.0.5 acorn: 8.5.0 acorn-globals: 6.0.0 + canvas: 2.6.1 cssom: 0.4.4 cssstyle: 2.3.0 data-urls: 2.0.0 @@ -18825,12 +18596,14 @@ packages: resolution: integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== /json-schema/0.2.3: + dev: true resolution: integrity: sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= /json-stable-stringify-without-jsonify/1.0.1: resolution: integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= /json-stringify-safe/5.0.1: + dev: true resolution: integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= /json3/3.3.3: @@ -18846,6 +18619,7 @@ packages: /json5/2.1.3: dependencies: minimist: 1.2.5 + dev: true engines: node: '>=6' hasBin: true @@ -18877,6 +18651,7 @@ packages: extsprintf: 1.3.0 json-schema: 0.2.3 verror: 1.10.0 + dev: true engines: '0': node >=0.6.0 resolution: @@ -19032,7 +18807,7 @@ packages: integrity: sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg== /lint-staged/11.0.0: dependencies: - chalk: 4.1.1 + chalk: 4.1.2 cli-truncate: 2.1.0 commander: 7.2.0 cosmiconfig: 7.0.0 @@ -19349,7 +19124,7 @@ packages: integrity: sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== /log-symbols/4.1.0: dependencies: - chalk: 4.1.1 + chalk: 4.1.2 is-unicode-supported: 0.1.0 dev: true engines: @@ -19664,14 +19439,6 @@ packages: node: '>=0.10.0' resolution: integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - /micromatch/4.0.2: - dependencies: - braces: 3.0.2 - picomatch: 2.2.2 - engines: - node: '>=8' - resolution: - integrity: sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== /micromatch/4.0.4: dependencies: braces: 3.0.2 @@ -19693,12 +19460,8 @@ packages: node: '>= 0.6' resolution: integrity: sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== - /mime-db/1.47.0: - engines: - node: '>= 0.6' - resolution: - integrity: sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== /mime-db/1.48.0: + dev: true engines: node: '>= 0.6' resolution: @@ -19715,16 +19478,10 @@ packages: node: '>= 0.6' resolution: integrity: sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ== - /mime-types/2.1.30: - dependencies: - mime-db: 1.47.0 - engines: - node: '>= 0.6' - resolution: - integrity: sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== /mime-types/2.1.31: dependencies: mime-db: 1.48.0 + dev: true engines: node: '>= 0.6' resolution: @@ -20329,6 +20086,7 @@ packages: resolution: integrity: sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== /oauth-sign/0.9.0: + dev: true resolution: integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== /object-assign/4.1.1: @@ -20549,7 +20307,7 @@ packages: integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== /optionator/0.9.1: dependencies: - deep-is: 0.1.3 + deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 @@ -20790,11 +20548,7 @@ packages: node: '>=8' resolution: integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - /parse5/5.1.1: - resolution: - integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== /parse5/6.0.1: - dev: true resolution: integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== /parseurl/1.3.3: @@ -20927,11 +20681,6 @@ packages: /picocolors/1.0.0: resolution: integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - /picomatch/2.2.2: - engines: - node: '>=8.6' - resolution: - integrity: sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== /picomatch/2.3.0: engines: node: '>=8.6' @@ -22057,7 +21806,6 @@ packages: dependencies: kleur: 3.0.3 sisteransi: 1.0.5 - dev: true engines: node: '>= 6' resolution: @@ -22163,6 +21911,7 @@ packages: resolution: integrity: sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8= /qs/6.5.2: + dev: true engines: node: '>=0.6' resolution: @@ -22958,56 +22707,6 @@ packages: dev: true resolution: integrity: sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4= - /request-promise-core/1.1.4_request@2.88.2: - dependencies: - lodash: 4.17.21 - request: 2.88.2 - engines: - node: '>=0.10.0' - peerDependencies: - request: ^2.34 - resolution: - integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - /request-promise-native/1.0.9_request@2.88.2: - dependencies: - request: 2.88.2 - request-promise-core: 1.1.4_request@2.88.2 - stealthy-require: 1.1.1 - tough-cookie: 2.5.0 - deprecated: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 - engines: - node: '>=0.12.0' - peerDependencies: - request: ^2.34 - resolution: - integrity: sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - /request/2.88.2: - dependencies: - aws-sign2: 0.7.0 - aws4: 1.11.0 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - har-validator: 5.1.5 - http-signature: 1.2.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.30 - oauth-sign: 0.9.0 - performance-now: 2.1.0 - qs: 6.5.2 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 3.4.0 - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 - engines: - node: '>= 6' - resolution: - integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== /require-directory/2.1.1: engines: node: '>=0.10.0' @@ -23142,7 +22841,7 @@ packages: /restore-cursor/3.1.0: dependencies: onetime: 5.1.2 - signal-exit: 3.0.3 + signal-exit: 3.0.5 engines: node: '>=8' resolution: @@ -23878,6 +23577,7 @@ packages: jsbn: 0.1.1 safer-buffer: 2.1.2 tweetnacl: 0.14.5 + dev: true engines: node: '>=0.10.0' hasBin: true @@ -23977,11 +23677,6 @@ packages: node: '>= 0.6' resolution: integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - /stealthy-require/1.1.1: - engines: - node: '>=0.10.0' - resolution: - integrity: sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= /stream-browserify/2.0.2: dependencies: inherits: 2.0.4 @@ -24979,25 +24674,16 @@ packages: dependencies: psl: 1.8.0 punycode: 2.1.1 + dev: true engines: node: '>=0.8' resolution: integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - /tough-cookie/3.0.1: - dependencies: - ip-regex: 2.1.0 - psl: 1.8.0 - punycode: 2.1.1 - engines: - node: '>=6' - resolution: - integrity: sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== /tough-cookie/4.0.0: dependencies: psl: 1.8.0 punycode: 2.1.1 universalify: 0.1.2 - dev: true engines: node: '>=6' resolution: @@ -25007,13 +24693,6 @@ packages: punycode: 2.1.1 resolution: integrity: sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= - /tr46/2.0.2: - dependencies: - punycode: 2.1.1 - engines: - node: '>=8' - resolution: - integrity: sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== /tr46/2.1.0: dependencies: punycode: 2.1.1 @@ -25366,9 +25045,11 @@ packages: /tunnel-agent/0.6.0: dependencies: safe-buffer: 5.2.1 + dev: true resolution: integrity: sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= /tweetnacl/0.14.5: + dev: true resolution: integrity: sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= /type-check/0.3.2: @@ -25832,6 +25513,7 @@ packages: assert-plus: 1.0.0 core-util-is: 1.0.2 extsprintf: 1.3.0 + dev: true engines: '0': node >=0.6.0 resolution: @@ -26145,25 +25827,6 @@ packages: webidl-conversions: 4.0.2 resolution: integrity: sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== - /whatwg-url/8.4.0: - dependencies: - lodash.sortby: 4.7.0 - tr46: 2.0.2 - webidl-conversions: 6.1.0 - engines: - node: '>=10' - resolution: - integrity: sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw== - /whatwg-url/8.5.0: - dependencies: - lodash: 4.17.21 - tr46: 2.1.0 - webidl-conversions: 6.1.0 - dev: true - engines: - node: '>=10' - resolution: - integrity: sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== /whatwg-url/8.7.0: dependencies: lodash: 4.17.21 @@ -26416,8 +26079,8 @@ packages: /wrap-ansi/7.0.0: dependencies: ansi-styles: 4.3.0 - string-width: 4.2.2 - strip-ansi: 6.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 engines: node: '>=10' resolution: @@ -26439,35 +26102,7 @@ packages: dev: false resolution: integrity: sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== - /ws/7.4.3: - engines: - node: '>=8.3.0' - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - resolution: - integrity: sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA== - /ws/7.4.6: - dev: true - engines: - node: '>=8.3.0' - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - resolution: - integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== /ws/7.5.5: - dev: true engines: node: '>=8.3.0' peerDependencies: diff --git a/vxsuite.code-workspace b/vxsuite.code-workspace index 73ed5c1662..bbf21bedb1 100644 --- a/vxsuite.code-workspace +++ b/vxsuite.code-workspace @@ -39,6 +39,9 @@ { "path": "libs/ui" }, + { + "path": "libs/logging" + }, { "path": "apps/precinct-scanner" },