diff --git a/package.json b/package.json index adaf7c1..e82ec1c 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "@types/bcrypt": "^3.0.0", "@types/chai": "^4.0.6", "@types/events": "^1.2.0", - "@types/expect": "^1.20.4", "@types/koa": "^2.11.0", "@types/koa-bodyparser": "^4.3.0", "@types/koa-router": "^7.4.0", @@ -60,15 +59,17 @@ "@types/yargs": "^11.0.0", "chai": "^4.1.2", "del": "^5.1.0", - "expect": "^23.5.0", + "expect": "^25.3.0", "fake-fs": "^0.5.0", "mocha": "^4.0.1", "nyc": "^13.3.0", "sinon": "^4.1.2", "source-map-support": "0.5.16", + "storex-hub-plugin-internal-selftest": "^0.0.1", "ts-node": "^7.0.1", "typescript": "^3.7.5", - "@types/prompt-sync": "^4.1.0" + "@types/prompt-sync": "^4.1.0", + "@worldbrain/storex-hub-interfaces": "^0.1.1" }, "resolutions": { "**/graphql": "^14.0.0" diff --git a/ts/main.test.ts b/ts/main.test.ts new file mode 100644 index 0000000..5bf9091 --- /dev/null +++ b/ts/main.test.ts @@ -0,0 +1,17 @@ +import { main } from "./main" +import expect from "expect" + +describe('Main entry point', () => { + it('should correctly discover plugins', async () => { + const { application, pluginManager } = await main({ + runtimeConfig: { discoverPlugins: 'true' }, + confirmPluginInstall: async () => 'install', + withoutServer: true, + }) + expect(pluginManager.loadedPlugins).toEqual({ + 'io.worldbrain.storex-hub.internal.self-test': expect.objectContaining({ + running: true + }) + }) + }) +}) \ No newline at end of file diff --git a/ts/main.ts b/ts/main.ts index 522cf39..399db71 100644 --- a/ts/main.ts +++ b/ts/main.ts @@ -9,35 +9,56 @@ import { BcryptAccessTokenManager } from "./access-tokens"; import { createHttpServer } from "./server"; import { PluginManager } from './plugins/manager'; import { discoverInstalledPlugins } from './plugins/discovery/main'; +import { PluginInstallConfirmer } from './plugins/discovery'; -export async function main() { - const application = await setupApplication() - await maybeRunPluginDiscovery(application) - await startServer(application) - await loadPlugins(application) +export interface RuntimeConfig { + dbFilePath?: string + discoverPlugins?: string } -export async function setupApplication() { - const application = new Application(getApplicationDependencies({ +export async function main(options?: { + runtimeConfig?: RuntimeConfig, + confirmPluginInstall?: PluginInstallConfirmer, + withoutServer?: boolean +}) { + const runtimeConfig = options?.runtimeConfig ?? getRuntimeConfig() + const application = await setupApplication(runtimeConfig) + await maybeRunPluginDiscovery(application, { runtimeConfig, confirmPluginInstall: options?.confirmPluginInstall }) + if (!options?.withoutServer) { + await startServer(application) + } + const pluginManager = await loadPlugins(application) + return { application, pluginManager } +} + +export function getRuntimeConfig(): RuntimeConfig { + return { dbFilePath: process.env.DB_PATH, + discoverPlugins: process.env.STOREX_HUB_DISCOVER_PLUGINS, + } +} + +export async function setupApplication(runtimeConfig?: RuntimeConfig) { + const application = new Application(getApplicationDependencies({ + dbFilePath: runtimeConfig?.dbFilePath, })) await application.setup() return application } -async function maybeRunPluginDiscovery(application: Application) { - if (!process.env.STOREX_HUB_DISCOVER_PLUGINS) { - return - } - - const patternOrTrue = process.env.STOREX_HUB_DISCOVER_PLUGINS - if (patternOrTrue.toLowerCase() === 'false') { +async function maybeRunPluginDiscovery(application: Application, options?: { + runtimeConfig?: RuntimeConfig + confirmPluginInstall?: PluginInstallConfirmer, +}) { + const patternOrTrue = options?.runtimeConfig?.discoverPlugins + if (!patternOrTrue || patternOrTrue.toLowerCase() === 'false') { return } await discoverInstalledPlugins(application, { nodeModulesPath: join(process.cwd(), 'node_modules'), - pluginDirGlob: patternOrTrue.toLowerCase() !== 'true' ? patternOrTrue : undefined + pluginDirGlob: patternOrTrue.toLowerCase() !== 'true' ? patternOrTrue : undefined, + confirmPluginInstall: options?.confirmPluginInstall, }) // TODO: Don't know why yet, but added plugins do not immediately get stored @@ -50,6 +71,7 @@ async function loadPlugins(application: Application) { pluginManagementStorage: storage.systemModules.plugins, }) await pluginManager.setup(() => application.api()) + return pluginManager } export async function startServer(application: Application) { diff --git a/ts/plugins/discovery/index.test.ts b/ts/plugins/discovery/index.test.ts index 38e582b..05068e4 100644 --- a/ts/plugins/discovery/index.test.ts +++ b/ts/plugins/discovery/index.test.ts @@ -1,7 +1,7 @@ +import expect from "expect" +import { PluginInfo } from "@worldbrain/storex-hub-interfaces/lib/plugins" import { withTestApplication } from "../../tests/api/index.tests" import { discoverPlugins } from "." -import { PluginInfo } from "../types" -import expect from "expect" import { Application } from "../../application" const PLUGINS: { [path: string]: PluginInfo } = { diff --git a/ts/plugins/discovery/index.ts b/ts/plugins/discovery/index.ts index f68c447..55c9c4e 100644 --- a/ts/plugins/discovery/index.ts +++ b/ts/plugins/discovery/index.ts @@ -1,9 +1,11 @@ -import { PluginInfo } from "../types"; +import { PluginInfo } from "@worldbrain/storex-hub-interfaces/lib/plugins"; import { PluginManagementStorage } from "../storage"; +export type PluginInstallConfirmer = (pluginInfo: PluginInfo, options: { pluginDir: string }) => Promise<'install' | 'skip' | 'abort'> + export async function discoverPlugins(pluginDirs: string[], options: { getPluginInfo: (pluginDir: string) => Promise - confirmPluginInstall: (pluginInfo: PluginInfo, options: { pluginDir: string }) => Promise<'install' | 'skip' | 'abort'> + confirmPluginInstall: PluginInstallConfirmer pluginManagementStorage: PluginManagementStorage }) { for (const pluginDir of pluginDirs) { diff --git a/ts/plugins/discovery/main.ts b/ts/plugins/discovery/main.ts index ca81df9..bccc7d5 100644 --- a/ts/plugins/discovery/main.ts +++ b/ts/plugins/discovery/main.ts @@ -2,8 +2,8 @@ import path from 'path' import { existsSync, readFileSync } from 'fs' import fastGlob from 'fast-glob' import createPrompt from 'prompt-sync' -import { discoverPlugins } from '.' -import { PluginInfo } from '../types' +import { PluginInfo } from "@worldbrain/storex-hub-interfaces/lib/plugins"; +import { discoverPlugins, PluginInstallConfirmer } from '.' import { Application } from '../../application' const prompt = createPrompt() @@ -14,6 +14,7 @@ function validatePluginInfo(untrusted: any): PluginInfo | null { export async function discoverInstalledPlugins(application: Application, options: { pluginDirGlob?: string nodeModulesPath: string + confirmPluginInstall?: PluginInstallConfirmer }) { const pluginDirGlob = ( options.pluginDirGlob || '/storex-hub-plugin-*' @@ -42,38 +43,40 @@ export async function discoverInstalledPlugins(application: Application, options const pluginInfo = validatePluginInfo(packageInfo['storexHub']) return pluginInfo }, - async confirmPluginInstall(pluginInfo: PluginInfo, { pluginDir }) { - let result: string | undefined - do { - console.log([ - `Found new plugin in directory ${pluginDir}:`, - `- Description: ${pluginInfo.description}`, - `- Website: ${pluginInfo.siteUrl}`, - ].join('\n')) - result = prompt( - `Only install plugins you trust. Do you want to install this one? [y/N] `, - 'N' - ) - if (!result) { - return 'abort' - } + confirmPluginInstall: options.confirmPluginInstall ?? confirmPluginInstallByPrompt, + }) +} - if (result) { - result = result.toLowerCase() - } - if (['y', 'n', 'yes', 'no'].indexOf(result) === -1) { - console.error(`Invalid response: ${result}`) - result = undefined - } - } while (!result) +const confirmPluginInstallByPrompt: PluginInstallConfirmer = async (pluginInfo: PluginInfo, { pluginDir }) => { + let result: string | undefined + do { + console.log([ + `Found new plugin in directory ${pluginDir}:`, + `- Description: ${pluginInfo.description}`, + `- Website: ${pluginInfo.siteUrl}`, + ].join('\n')) + result = prompt( + `Only install plugins you trust. Do you want to install this one? [y/N] `, + 'N' + ) + if (!result) { + return 'abort' + } - if (result.startsWith('y')) { - console.log('Installing plugin...') - return 'install' - } else { - console.log('OK, skipping this plugin...') - return 'skip' - } - }, - }) + if (result) { + result = result.toLowerCase() + } + if (['y', 'n', 'yes', 'no'].indexOf(result) === -1) { + console.error(`Invalid response: ${result}`) + result = undefined + } + } while (!result) + + if (result.startsWith('y')) { + console.log('Installing plugin...') + return 'install' + } else { + console.log('OK, skipping this plugin...') + return 'skip' + } } diff --git a/ts/plugins/manager.ts b/ts/plugins/manager.ts index 6d06146..631dd8b 100644 --- a/ts/plugins/manager.ts +++ b/ts/plugins/manager.ts @@ -1,8 +1,10 @@ import { PluginManagementStorage } from "./storage"; -import { PluginInfo, PluginEntryFunction, PluginInterface } from "./types"; +import { PluginInfo, PluginEntryFunction, PluginInterface } from "@worldbrain/storex-hub-interfaces/lib/plugins"; import { StorexHubApi_v0 } from "../public-api"; export class PluginManager { + loadedPlugins: { [identifier: string]: PluginInterface } = {} + constructor(private options: { pluginManagementStorage: PluginManagementStorage }) { @@ -39,15 +41,14 @@ export class PluginManager { return null } - let plugin: PluginInterface try { - plugin = await entryFunction({ api: await createAPI() }) + this.loadedPlugins[pluginInfo.identifier] = await entryFunction({ api: await createAPI() }) } catch (e) { console.error(`ERROR during initialization plugin '${pluginInfo.identifier}':`) console.error(e) return null } - return plugin + return this.loadedPlugins[pluginInfo.identifier] } } diff --git a/ts/plugins/storage/index.ts b/ts/plugins/storage/index.ts index d46b979..b2386d0 100644 --- a/ts/plugins/storage/index.ts +++ b/ts/plugins/storage/index.ts @@ -1,7 +1,7 @@ import * as path from 'path' import { StorageModule, StorageModuleConfig } from "@worldbrain/storex-pattern-modules"; import STORAGE_VERSIONS from "../../storage/versions"; -import { PluginInfo } from "../types"; +import { PluginInfo } from '@worldbrain/storex-hub-interfaces/lib/plugins'; export class PluginManagementStorage extends StorageModule { getConfig = (): StorageModuleConfig => ({ diff --git a/ts/plugins/test-plugins/one/main.ts b/ts/plugins/test-plugins/one/main.ts deleted file mode 100644 index a058652..0000000 --- a/ts/plugins/test-plugins/one/main.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { StorexHubApi_v0 } from "../../../public-api"; -import { PluginEntryFunction } from "../../types"; - -export const main: PluginEntryFunction = async (input: { api: StorexHubApi_v0 }) => { - return { - start: async () => { console.log('starting plugin!') }, - stop: async () => { console.log('stopping plugin!') } - } -} diff --git a/ts/plugins/test-plugins/one/package.json b/ts/plugins/test-plugins/one/package.json deleted file mode 100644 index 9d95dca..0000000 --- a/ts/plugins/test-plugins/one/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "storexHub": { - "identifier": "io.worldbrain.storex-hub.one", - "version": "0.0.1", - "description": "My description", - "siteUrl": "https://test.io/storex-hub", - "apps": [], - "mainPath": "main", - "entryFunction": "main" - } -} diff --git a/ts/plugins/types.ts b/ts/plugins/types.ts deleted file mode 100644 index c998d45..0000000 --- a/ts/plugins/types.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { StorexHubApi_v0 } from "../public-api"; - -export interface PluginInfo { - identifier: string - version: string - description: string - apps: Array<{ name: string, description?: string }> - siteUrl: string - mainPath: string - entryFunction: string -} - -export interface PluginInterface { - start(): Promise - stop(): Promise -} - -export type PluginEntryFunction = (input: { api: StorexHubApi_v0 }) => Promise diff --git a/ts/public-api/client.ts b/ts/public-api/client.ts deleted file mode 100644 index b28bd2f..0000000 --- a/ts/public-api/client.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { RemoteSubscriptionRequest_v0, ReceivedStorageChangeEvent_v0, AppAvailabilityChangedEvent_v0 } from "./common" - -export interface StorexHubCallbacks_v0 { - handleRemoteOperation?(options: HandleRemoteOperationOptions_v0): Promise - handleEvent?(options: HandleEventOptions_v0): Promise - handleSubscription?(options: HandleSubscriptionOptions_v0): Promise - handleUnsubscription?(options: HandleUnsubscriptionOptions_v0): Promise -} -export type AllStorexHubCallbacks_v0 = { [MethodName in keyof StorexHubCallbacks_v0]-?: StorexHubCallbacks_v0[MethodName] } - -export interface HandleRemoteOperationOptions_v0 { - operation: any[] - sourceApp: string -} - -export interface HandleRemoteOperationResult_v0 { - result: any -} - -export interface HandleEventOptions_v0 { - event: ClientEvent -} - -export type ClientEvent = ReceivedStorageChangeEvent_v0 | AppAvailabilityChangedEvent_v0 - -export type HandleEventResult_v0 = void - -export interface HandleSubscriptionOptions_v0 { - request: RemoteSubscriptionRequest_v0 -} - -export type HandleSubscriptionResult_v0 = { - subscriptionId: string -} - -export interface HandleUnsubscriptionOptions_v0 { - subscriptionId: string -} - -export type HandleUnubscriptionResult_v0 = void diff --git a/ts/public-api/common.ts b/ts/public-api/common.ts deleted file mode 100644 index ff43730..0000000 --- a/ts/public-api/common.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { StorageOperationChangeInfo } from "@worldbrain/storex-middleware-change-watcher/lib/types"; - -export type RemoteSubscriptionRequest_v0 = RemoteStorageChangeSubscriptionRequest_v0 -export interface RemoteStorageChangeSubscriptionRequest_v0 { - type: 'storage-change' - app: string - collections?: string[] -} -export interface StorageChangeEventBase_v0 { - type: 'storage-change' - info: StorageOperationChangeInfo<'post'> -} -export type SentStorageChangeEvent_v0 = StorageChangeEventBase_v0 -export interface ReceivedStorageChangeEvent_v0 extends StorageChangeEventBase_v0 { - app: string -} - -export interface AppAvailabilityChangedSubscriptionRequest_v0 { - type: 'app-availability-changed' -} -export interface AppAvailabilityChangedEvent_v0 { - type: 'app-availability-changed' - app: string - availability: boolean -} diff --git a/ts/public-api/index.ts b/ts/public-api/index.ts index 882be28..0bb7834 100644 --- a/ts/public-api/index.ts +++ b/ts/public-api/index.ts @@ -1,3 +1 @@ -export * from './server' -export * from './client' -export * from './common' +export * from '@worldbrain/storex-hub-interfaces/lib/api' diff --git a/ts/public-api/server.ts b/ts/public-api/server.ts deleted file mode 100644 index a5a9c01..0000000 --- a/ts/public-api/server.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { AppSchema } from '../types/apps'; -import * as common from './common'; - -export interface StorexHubApi_v0 { - registerApp(options: RegisterAppOptions_v0): Promise - identifyApp(options: IdentifyAppOptions_v0): Promise - getSessionInfo(): Promise - // unidentifyApp() : Promise - destroySession(): Promise - - executeOperation(options: { operation: any[] }): Promise<{ result: any }> - - executeRemoteOperation(options: ExecuteRemoteOperationOptions_v0): Promise - - subscribeToEvent(options: SubscribeToEventOptions_v0): Promise - unsubscribeFromEvent(options: UnsubscribeFromEventOptions_v0): Promise - emitEvent(options: EmitEventOptions_v0): Promise - - // requestPriviliges(options : { }) : Promise<{}> - // listPrivileges() : Promise<{}> - - updateSchema(options: UpdateSchemaOptions_v0): Promise - // describeSchema() : Promise<{}> // In terms of RDF - // updateAccessRules() : Promise<{}> - - // startMigration() : Promise<{}> - // getMigrationStatus() : Promise<{}> - - // exportData() : Promise<{}> - // importData(source : string, options : { mode : 'merge' | 'overwrite' }) : Promise<{}> - - // storeSecret() : Promise<{}> - // getSecret() : Promise<{}> - // deleteSecret() : Promise<{}> - - // storeApplicationConfig() : Promise<{}> - // getApplicationConfig() : Promise<{}> -} - -export interface RegisterAppOptions_v0 { - name: string - remote?: boolean - identify?: boolean -} - -export type RegisterAppResult_v0 = { status: 'success', accessToken: string } - | { status: 'app-already-exists' } - -export interface IdentifyAppOptions_v0 { - name: string - accessToken: string -} - -export type IdentifyAppResult_v0 = { status: 'success' } | -{ status: 'invalid-access-token' | 'dupliicate-identification' } - -export type GetSessionInfoResult_v0 = { - status: 'success', - appIdentifier?: string -} - -export interface ExecuteRemoteOperationOptions_v0 { - app: string - operation: any[] -} -export type ExecuteRemoteOperationResult_v0 = - { status: 'success', result: any } | - { status: 'not-identified' } | - { status: 'app-not-found' } | - { status: 'app-not-supported' } - -export interface SubscribeToEventOptions_v0 { - request: SubscriptionRequest_v0 -} -export type SubscriptionRequest_v0 = - common.AppAvailabilityChangedSubscriptionRequest_v0 | - ({ app: string } & common.RemoteSubscriptionRequest_v0) - - - -export type SubscribeToEventResult_v0 = - { status: 'unsupported-event' } | - { status: 'app-not-found' } | - { status: 'app-not-supported' } | - { status: 'success', subscriptionId: string } - -export interface UnsubscribeFromEventOptions_v0 { - subscriptionId: string -} -export type UnsubscribeFromEventResult_v0 = void - -export interface EmitEventOptions_v0 { - event: EmittableEvent_v0 - synchronous?: boolean -} -export type EmitEventResult_v0 = void - -export type EmittableEvent_v0 = common.SentStorageChangeEvent_v0 - -export interface UpdateSchemaOptions_v0 { - schema: AppSchema -} - -export type UpdateSchemaResult_v0 = { success: true } | { success: false, errorCode: UpdateSchemaError_v0, errorText: string } - -export enum UpdateSchemaError_v0 { - BAD_REQUEST = 1, - NOT_ALLOWED = 2, - SCHEMA_NOT_ALLOWED = 3, -} - -export type MethodDescription = SyncMethodDescription -export interface SyncMethodDescription { - path: string -} - -export const STOREX_HUB_API_v0: { [MethodName in keyof StorexHubApi_v0]: MethodDescription } = { - registerApp: { - path: '/app/register', - }, - identifyApp: { - path: '/app/identify', - }, - getSessionInfo: { - path: '/session', - }, - destroySession: { - path: '/session/destroy', - }, - executeOperation: { - path: '/storage/operation', - }, - updateSchema: { - path: '/schema/update', - }, - executeRemoteOperation: { - path: '/remote/operation' - }, - subscribeToEvent: { - path: '/remote/event/subscribe' - }, - unsubscribeFromEvent: { - path: '/remote/event/unsubscribe' - }, - emitEvent: { - path: '/event/emit' - } -} diff --git a/ts/public-api/utils.ts b/ts/public-api/utils.ts index 94805c5..f2c18f0 100644 --- a/ts/public-api/utils.ts +++ b/ts/public-api/utils.ts @@ -1,5 +1,4 @@ -import { RemoteSubscriptionRequest_v0 } from "./common"; -import { SubscriptionRequest_v0 } from "./server"; +import { RemoteSubscriptionRequest_v0, SubscriptionRequest_v0 } from "@worldbrain/storex-hub-interfaces/lib/api"; const REMOTE_EVENT_TYPES: { [event in RemoteSubscriptionRequest_v0['type']]: true } = { 'storage-change': true diff --git a/ts/session.ts b/ts/session.ts index 79cc2cd..3b755a8 100644 --- a/ts/session.ts +++ b/ts/session.ts @@ -2,10 +2,10 @@ import * as api from "./public-api"; import TypedEmitter from 'typed-emitter' import { AccessTokenManager } from "./access-tokens"; import { Storage } from "./storage/types"; -import { AppSchema } from "./types/apps"; import { EventEmitter } from "events"; import { StorexHubCallbacks_v0, AllStorexHubCallbacks_v0 } from "./public-api"; import { SingleArgumentOf, UnwrapPromise } from "./types/utils"; +import { AppSchema } from "@worldbrain/storex-hub-interfaces/lib/apps"; export interface SessionOptions { accessTokenManager: AccessTokenManager diff --git a/ts/storage/index.ts b/ts/storage/index.ts index 68b625f..67a0d74 100644 --- a/ts/storage/index.ts +++ b/ts/storage/index.ts @@ -1,8 +1,8 @@ import StorageManager, { StorageBackend } from "@worldbrain/storex"; +import { AppSchema } from "@worldbrain/storex-hub-interfaces/lib/apps"; import { SystemStorageModules, Storage } from "./types"; import { AppStorage } from "./modules/apps"; import { registerModuleMapCollections } from "@worldbrain/storex-pattern-modules"; -import { AppSchema } from "../types/apps"; import { PluginManagementStorage } from "../plugins/storage"; export async function createStorage(options: { createBackend: () => StorageBackend, appSchemas?: Array }): Promise { diff --git a/ts/storage/modules/apps.ts b/ts/storage/modules/apps.ts index 73619f8..283ae87 100644 --- a/ts/storage/modules/apps.ts +++ b/ts/storage/modules/apps.ts @@ -1,7 +1,6 @@ import { StorageModule, StorageModuleConfig } from '@worldbrain/storex-pattern-modules' +import { AppSchema } from '@worldbrain/storex-hub-interfaces/lib/apps'; import STORAGE_VERSIONS from '../versions'; -import { CollectionDefinitionMap } from '@worldbrain/storex'; -import { AppSchema } from '../../types/apps'; import { extendedJSONReviver } from '../../utils/json'; export class AppStorage extends StorageModule { diff --git a/ts/types/apps.ts b/ts/types/apps.ts deleted file mode 100644 index 7ff8798..0000000 --- a/ts/types/apps.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { CollectionDefinitionMap } from "@worldbrain/storex"; - -export interface AppSchema { - collectionDefinitions? : CollectionDefinitionMap - collectionDescriptions? : any - virtualTables? : any - terms? : any -} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 5e34315..ee7189c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35", "@babel/code-frame@^7.5.5": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== @@ -90,6 +90,16 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@jest/types@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.3.0.tgz#88f94b277a1d028fd7117bc1f74451e0fc2131e7" + integrity sha512-UkaDNewdqXAmCDbN2GlUM6amDKS78eCqiw/UmF5nE0mmLTd6moJkiZJML/X52Ke3LH7Swhw883IRXq8o9nWjVw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" + "@josephg/resolvable@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@josephg/resolvable/-/resolvable-1.0.0.tgz#cd75b09cfad18cd945de9221d403203aa07e3d0a" @@ -364,11 +374,6 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== -"@types/expect@^1.20.4": - version "1.20.4" - resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" - integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== - "@types/express-serve-static-core@*": version "4.17.2" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.2.tgz#f6f41fa35d42e79dbf6610eccbb2637e6008a0cf" @@ -400,6 +405,26 @@ resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" integrity sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ== +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" + integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" + integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== + dependencies: + "@types/istanbul-lib-coverage" "*" + "@types/istanbul-lib-report" "*" + "@types/js-yaml@^3.12.1": version "3.12.2" resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.2.tgz#a35a1809c33a68200fb6403d1ad708363c56470a" @@ -534,6 +559,11 @@ dependencies: "@types/node" "*" +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== + "@types/superagent@*": version "4.1.4" resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-4.1.4.tgz#63f74955a28073870cfd9c100bcacb26d72b3764" @@ -562,11 +592,23 @@ "@types/events" "*" "@types/node" "*" +"@types/yargs-parser@*": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" + integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== + "@types/yargs@^11.0.0": version "11.1.5" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-11.1.5.tgz#8d71dfe4848ac5d714b75eca3df9cac75a4f8dac" integrity sha512-1jmXgoIyzxQSm33lYgEXvegtkhloHbed2I0QGlTN66U2F9/ExqJWSCSmaWC0IB/g1tW+IYSp+tDhcZBYB1ZGog== +"@types/yargs@^15.0.0": + version "15.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.4.tgz#7e5d0f8ca25e9d5849f2ea443cf7c402decd8299" + integrity sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg== + dependencies: + "@types/yargs-parser" "*" + "@yarnpkg/lockfile@^1.0.2": version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" @@ -661,7 +703,7 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== @@ -711,18 +753,6 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= - dependencies: - arr-flatten "^1.0.1" - -arr-flatten@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - array-from@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" @@ -733,11 +763,6 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= - arraybuffer.slice@~0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" @@ -885,15 +910,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - braces@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -993,6 +1009,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.2, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -1406,12 +1430,17 @@ detect-libc@^1.0.2: resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= +diff-sequences@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" + integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== + diff@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" integrity sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww== -diff@^3.1.0, diff@^3.2.0: +diff@^3.1.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== @@ -1656,31 +1685,17 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= - dependencies: - is-posix-bracket "^0.1.0" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= - dependencies: - fill-range "^2.1.0" - -expect@^23.5.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98" - integrity sha512-dgSoOHgmtn/aDGRVFWclQyPDKl2CQRq0hmIEoUAuQs/2rn2NcvCWcSCovm6BLeuB/7EZuLGu2QfnR+qRt5OM4w== +expect@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-25.3.0.tgz#5fd36e51befd05afb7184bc954f8a4792d184c71" + integrity sha512-buboTXML2h/L0Kh44Ys2Cx49mX20ISc5KDirkxIs3Q9AJv0kazweUAbukegr+nHDOvFRKmxdojjIHCjqAceYfg== dependencies: - ansi-styles "^3.2.0" - jest-diff "^23.6.0" - jest-get-type "^22.1.0" - jest-matcher-utils "^23.6.0" - jest-message-util "^23.4.0" - jest-regex-util "^23.3.0" + "@jest/types" "^25.3.0" + ansi-styles "^4.0.0" + jest-get-type "^25.2.6" + jest-matcher-utils "^25.3.0" + jest-message-util "^25.3.0" + jest-regex-util "^25.2.6" extend@^3.0.0, extend@~3.0.2: version "3.0.2" @@ -1696,13 +1711,6 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= - dependencies: - is-extglob "^1.0.0" - extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -1773,22 +1781,6 @@ file-uri-to-path@1: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= - -fill-range@^2.1.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" - integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^3.0.0" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -1820,18 +1812,6 @@ find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -for-in@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= - dependencies: - for-in "^1.0.1" - foreground-child@^1.5.6: version "1.5.6" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" @@ -1984,21 +1964,6 @@ git-url-parse@11.1.2: dependencies: git-up "^4.0.0" -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= - dependencies: - is-glob "^2.0.0" - glob-parent@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" @@ -2148,6 +2113,11 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -2330,11 +2300,6 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - is-ci@^1.0.10: version "1.2.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" @@ -2347,28 +2312,6 @@ is-class-hotfix@~0.0.6: resolved "https://registry.yarnpkg.com/is-class-hotfix/-/is-class-hotfix-0.0.6.tgz#a527d31fb23279281dde5f385c77b5de70a72435" integrity sha512-0n+pzCC6ICtVr/WXnN2f03TK/3BfXY7me4cjCAqT8TYXEl0+JBRoqBo94JJHXcyDSLUeWbNX8Fvy5g5RJdAstQ== -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= - dependencies: - is-primitive "^2.0.0" - -is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -2396,13 +2339,6 @@ is-generator-function@^1.0.7: resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= - dependencies: - is-extglob "^1.0.0" - is-glob@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" @@ -2423,18 +2359,6 @@ is-npm@^1.0.0: resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= - dependencies: - kind-of "^3.0.2" - -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -2462,16 +2386,6 @@ is-path-inside@^3.0.1: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= - is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -2528,28 +2442,21 @@ isarray@0.0.1: resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= -isarray@1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - isarray@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -2612,45 +2519,48 @@ iterall@^1.2.2: resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== -jest-diff@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d" - integrity sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g== +jest-diff@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.3.0.tgz#0d7d6f5d6171e5dacde9e05be47b3615e147c26f" + integrity sha512-vyvs6RPoVdiwARwY4kqFWd4PirPLm2dmmkNzKqo38uZOzJvLee87yzDjIZLmY1SjM3XR5DwsUH+cdQ12vgqi1w== dependencies: - chalk "^2.0.1" - diff "^3.2.0" - jest-get-type "^22.1.0" - pretty-format "^23.6.0" + chalk "^3.0.0" + diff-sequences "^25.2.6" + jest-get-type "^25.2.6" + pretty-format "^25.3.0" -jest-get-type@^22.1.0: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" - integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== +jest-get-type@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" + integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== -jest-matcher-utils@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80" - integrity sha512-rosyCHQfBcol4NsckTn01cdelzWLU9Cq7aaigDf8VwwpIRvWE/9zLgX2bON+FkEW69/0UuYslUe22SOdEf2nog== +jest-matcher-utils@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.3.0.tgz#76765788a26edaa8bc5f0100aea52ae383559648" + integrity sha512-ZBUJ2fchNIZt+fyzkuCFBb8SKaU//Rln45augfUtbHaGyVxCO++ANARdBK9oPGXU3hEDgyy7UHnOP/qNOJXFUg== dependencies: - chalk "^2.0.1" - jest-get-type "^22.1.0" - pretty-format "^23.6.0" + chalk "^3.0.0" + jest-diff "^25.3.0" + jest-get-type "^25.2.6" + pretty-format "^25.3.0" -jest-message-util@^23.4.0: - version "23.4.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f" - integrity sha1-F2EMUJQjSVCNAaPR4L2iwHkIap8= +jest-message-util@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.3.0.tgz#e3836826fe5ca538a337b87d9bd2648190867f85" + integrity sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw== dependencies: - "@babel/code-frame" "^7.0.0-beta.35" - chalk "^2.0.1" - micromatch "^2.3.11" - slash "^1.0.0" + "@babel/code-frame" "^7.0.0" + "@jest/types" "^25.3.0" + "@types/stack-utils" "^1.0.1" + chalk "^3.0.0" + micromatch "^4.0.2" + slash "^3.0.0" stack-utils "^1.0.1" -jest-regex-util@^23.3.0: - version "23.3.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5" - integrity sha1-X4ZylUfCeFxAAs6qj4Sf6MpHG8U= +jest-regex-util@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" + integrity sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw== js-tokens@^4.0.0: version "4.0.0" @@ -2727,18 +2637,6 @@ keygrip@~1.1.0: dependencies: tsscmp "1.0.6" -kind-of@^3.0.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== - koa-bodyparser@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/koa-bodyparser/-/koa-bodyparser-4.2.1.tgz#4d7dacb5e6db1106649b595d9e5ccb158b6f3b29" @@ -3000,11 +2898,6 @@ map-age-cleaner@^0.1.1: dependencies: p-defer "^1.0.0" -math-random@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" - integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -3036,25 +2929,6 @@ methods@^1.1.1, methods@^1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - micromatch@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" @@ -3304,13 +3178,6 @@ normalize-package-data@^2.3.2: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - normalize-url@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" @@ -3401,14 +3268,6 @@ object-hash@^1.3.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - on-finished@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -3614,16 +3473,6 @@ pako@~1.0.2: resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -3767,18 +3616,15 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= - -pretty-format@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" - integrity sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw== +pretty-format@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.3.0.tgz#d0a4f988ff4a6cd350342fdabbb809aeb4d49ad5" + integrity sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA== dependencies: - ansi-regex "^3.0.0" - ansi-styles "^3.2.0" + "@jest/types" "^25.3.0" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^16.12.0" process-nextick-args@~2.0.0: version "2.0.1" @@ -3866,15 +3712,6 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -randomatic@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" - integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== - dependencies: - is-number "^4.0.0" - kind-of "^6.0.0" - math-random "^1.0.1" - raw-body@^2.2.0, raw-body@^2.3.3: version "2.4.1" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" @@ -3895,6 +3732,11 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-is@^16.12.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + read-pkg-up@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" @@ -3967,13 +3809,6 @@ realistic-structured-clone@^2.0.1: typeson "^5.8.2" typeson-registry "^1.0.0-alpha.20" -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== - dependencies: - is-equal-shallow "^0.1.3" - registry-auth-token@^3.0.1: version "3.4.0" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" @@ -3996,21 +3831,6 @@ release-zalgo@^1.0.0: dependencies: es6-error "^4.0.1" -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - request-promise-core@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" @@ -4249,11 +4069,6 @@ sinon@^4.1.2: supports-color "^5.1.0" type-detect "^4.0.5" -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -4833,6 +4648,13 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + tar-stream@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3"