From 741254803fb567a2371f6d26c7de5386f127fb39 Mon Sep 17 00:00:00 2001 From: Mike Plummer Date: Tue, 16 Aug 2022 22:05:09 +0000 Subject: [PATCH 01/45] feat: ACI Notification Banners (#23256) --- .../app/cypress/component/support/index.ts | 2 + .../app/cypress/e2e/specs_list_flaky.cy.ts | 9 +- .../cypress/e2e/specs_list_latest_runs.cy.ts | 2 +- packages/app/cypress/e2e/top-nav.cy.ts | 2 + .../app/src/specs/SpecsListBanners.cy.tsx | 167 +++++++++++++++++- packages/app/src/specs/SpecsListBanners.vue | 103 ++++++++++- .../specs/banners/ConnectProjectBanner.cy.tsx | 14 ++ .../specs/banners/ConnectProjectBanner.vue | 78 ++++++++ .../banners/CreateOrganizationBanner.cy.tsx | 26 +++ .../banners/CreateOrganizationBanner.vue | 79 +++++++++ .../app/src/specs/banners/LoginBanner.cy.tsx | 14 ++ .../app/src/specs/banners/LoginBanner.vue | 70 ++++++++ .../app/src/specs/banners/RecordBanner.cy.tsx | 30 ++++ .../app/src/specs/banners/RecordBanner.vue | 78 ++++++++ .../src/specs/banners/TrackedBanner.cy.tsx | 64 +++++++ .../app/src/specs/banners/TrackedBanner.vue | 75 ++++++++ packages/app/src/specs/banners/index.ts | 7 + .../src/actions/ProjectActions.ts | 2 +- .../data-context/src/data/coreDataShape.ts | 3 +- .../cypress/e2e/support/e2eSupport.ts | 1 + .../cypress/support/component.ts | 1 - .../src/assets/icons/action-record_x16.svg | 9 +- .../gql-components/HeaderBarContent.cy.tsx | 8 +- .../src/gql-components/HeaderBarContent.vue | 26 ++- .../frontend-shared/src/locales/en-US.json | 21 +++ packages/server/lib/project-base.ts | 3 +- packages/types/src/config.ts | 18 ++ packages/types/src/preferences.ts | 4 +- 28 files changed, 885 insertions(+), 31 deletions(-) create mode 100644 packages/app/src/specs/banners/ConnectProjectBanner.cy.tsx create mode 100644 packages/app/src/specs/banners/ConnectProjectBanner.vue create mode 100644 packages/app/src/specs/banners/CreateOrganizationBanner.cy.tsx create mode 100644 packages/app/src/specs/banners/CreateOrganizationBanner.vue create mode 100644 packages/app/src/specs/banners/LoginBanner.cy.tsx create mode 100644 packages/app/src/specs/banners/LoginBanner.vue create mode 100644 packages/app/src/specs/banners/RecordBanner.cy.tsx create mode 100644 packages/app/src/specs/banners/RecordBanner.vue create mode 100644 packages/app/src/specs/banners/TrackedBanner.cy.tsx create mode 100644 packages/app/src/specs/banners/TrackedBanner.vue create mode 100644 packages/app/src/specs/banners/index.ts diff --git a/packages/app/cypress/component/support/index.ts b/packages/app/cypress/component/support/index.ts index fe1e8f9c468f..2219b78813af 100644 --- a/packages/app/cypress/component/support/index.ts +++ b/packages/app/cypress/component/support/index.ts @@ -1,3 +1,5 @@ +/// +import '../../../../frontend-shared/cypress/support/component.ts' import { registerMountFn } from '@packages/frontend-shared/cypress/support/common' // *********************************************************** // This example support/index.ts is processed and diff --git a/packages/app/cypress/e2e/specs_list_flaky.cy.ts b/packages/app/cypress/e2e/specs_list_flaky.cy.ts index 4619f374912e..12881e1a974f 100644 --- a/packages/app/cypress/e2e/specs_list_flaky.cy.ts +++ b/packages/app/cypress/e2e/specs_list_flaky.cy.ts @@ -14,14 +14,7 @@ describe('App: Spec List - Flaky Indicator', () => { cy.remoteGraphQLIntercept(async (obj) => { await new Promise((r) => setTimeout(r, 20)) - if (obj.result.data && 'cloudProjectBySlug' in obj.result.data) { - obj.result.data.cloudProjectBySlug = { - __typename: 'CloudProject', - retrievedAt: new Date().toISOString(), - id: `id${obj.variables.slug}`, - projectId: 'abc123', - } - } else if (obj.result.data && 'cloudSpecByPath' in obj.result.data) { + if (obj.result.data && 'cloudSpecByPath' in obj.result.data) { if (obj.variables.specPath.includes('123.spec.js')) { obj.result.data.cloudSpecByPath = { __typename: 'CloudProjectSpec', diff --git a/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts b/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts index 28a76b60039b..c1a0e13861ab 100644 --- a/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts +++ b/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts @@ -314,7 +314,7 @@ describe('App/Cloud Integration - Latest runs and Average duration', { viewportW cy.get(averageDurationSelector('accounts_new.spec.js')).contains('2:03') }) - it('lazily loads data for off-screen specs', () => { + it('lazily loads data for off-screen specs', { viewportHeight: 500 }, () => { // make sure the virtualized list didn't load z008.spec.js cy.get(specRowSelector('z008.spec.js')).should('not.exist') diff --git a/packages/app/cypress/e2e/top-nav.cy.ts b/packages/app/cypress/e2e/top-nav.cy.ts index dd889ad88b6f..b8a94ff7d142 100644 --- a/packages/app/cypress/e2e/top-nav.cy.ts +++ b/packages/app/cypress/e2e/top-nav.cy.ts @@ -655,6 +655,7 @@ describe('Growth Prompts Can Open Automatically', () => { firstOpened: 1609459200000, lastOpened: 1609459200000, promptsShown: {}, + banners: { _disabled: true }, }) }, ) @@ -672,6 +673,7 @@ describe('Growth Prompts Can Open Automatically', () => { firstOpened: 1609459200000, lastOpened: 1609459200000, promptsShown: { ci1: 1609459200000 }, + banners: { _disabled: true }, }) }, ) diff --git a/packages/app/src/specs/SpecsListBanners.cy.tsx b/packages/app/src/specs/SpecsListBanners.cy.tsx index f6f2b5d17c2a..0cc1da81315f 100644 --- a/packages/app/src/specs/SpecsListBanners.cy.tsx +++ b/packages/app/src/specs/SpecsListBanners.cy.tsx @@ -1,11 +1,18 @@ import SpecsListBanners from './SpecsListBanners.vue' import { ref } from 'vue' import type { Ref } from 'vue' -import { SpecsListBannersFragmentDoc } from '../generated/graphql-test' +import { SpecsListBannersFragment, SpecsListBannersFragmentDoc } from '../generated/graphql-test' +import interval from 'human-interval' +import { CloudUserStubs, CloudProjectStubs } from '@packages/graphql/test/stubCloudTypes' +import { AllowedState, BannerIds } from '@packages/types' +import { assignIn, set } from 'lodash' const AlertSelector = 'alert-header' const AlertCloseBtnSelector = 'alert-suffix-icon' +type BannerKey = keyof typeof BannerIds +type BannerId = typeof BannerIds[BannerKey] + describe('', () => { const validateBaseRender = () => { it('should render as expected', () => { @@ -48,6 +55,75 @@ describe('', () => { }) } + const stateWithFirstOpenedDaysAgo = (days: number) => { + return { + firstOpened: Date.now() - interval(`${days} days`), + } + } + + const mountWithState = (query: Partial, state?: Partial, props?: object) => { + cy.mountFragment(SpecsListBannersFragmentDoc, { + onResult: (result) => { + assignIn(result, query) + set(result, 'currentProject.savedState', state) + }, + render: (gql) => , + }) + } + + const validateSmartNotificationBehaviors = (bannerId: BannerId, bannerTestId: string, gql: Partial) => { + it('should not render when using cypress < 4 days', () => { + mountWithState(gql, stateWithFirstOpenedDaysAgo(3)) + + cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist') + }) + + it('should not render when previously-dismissed', () => { + mountWithState(gql, { + ...stateWithFirstOpenedDaysAgo(4), + banners: { + [bannerId]: { + dismissed: Date.now(), + }, + }, + }) + + cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist') + }) + + context('banner conditions are met and when cypress use >= 4 days', () => { + it('should render when not previously-dismissed', () => { + mountWithState(gql, stateWithFirstOpenedDaysAgo(4)) + cy.get(`[data-cy="${bannerTestId}"]`).should('be.visible') + }) + + it('should be preempted by spec not found banner', () => { + mountWithState(gql, stateWithFirstOpenedDaysAgo(4), { isSpecNotFound: true }) + cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist') + }) + + it('should be preempted by offline warning banner', () => { + mountWithState(gql, stateWithFirstOpenedDaysAgo(4), { isOffline: true }) + cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist') + }) + + it('should be preempted by fetch error banner', () => { + mountWithState(gql, stateWithFirstOpenedDaysAgo(4), { isFetchError: true }) + cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist') + }) + + it('should be preempted by project not found banner', () => { + mountWithState(gql, stateWithFirstOpenedDaysAgo(4), { isProjectNotFound: true }) + cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist') + }) + + it('should be preempted by request access banner', () => { + mountWithState(gql, stateWithFirstOpenedDaysAgo(4), { isProjectUnauthorized: true }) + cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist') + }) + }) + } + describe('spec not found', () => { const visible: any = ref(true) @@ -141,6 +217,7 @@ describe('', () => { message: 'test', hasRequestedAccess: false, }, + savedState: {}, } }, render: (gql) => , @@ -170,6 +247,7 @@ describe('', () => { message: 'test', hasRequestedAccess: true, }, + savedState: {}, } }, render: (gql) => , @@ -181,4 +259,91 @@ describe('', () => { validateCloseOnPropChange(visible) validateReopenOnPropChange(visible) }) + + describe('login', () => { + const gql: Partial = { + cloudViewer: null, + cachedUser: null, + currentProject: { + __typename: 'CurrentProject', + id: 'abc123', + } as any, + } + + validateSmartNotificationBehaviors(BannerIds.ACI_082022_LOGIN, 'login-banner', gql) + }) + + describe('create organization', () => { + const gql: Partial = { + cloudViewer: { + ...CloudUserStubs.me, + firstOrganization: { + __typename: 'CloudOrganizationConnection', + nodes: [], + }, + }, + currentProject: { + __typename: 'CurrentProject', + id: 'abc123', + } as any, + } + + beforeEach(() => { + cy.gqlStub.Query.cloudViewer = gql.cloudViewer as any + }) + + validateSmartNotificationBehaviors(BannerIds.ACI_082022_CREATE_ORG, 'create-organization-banner', gql) + }) + + describe('connect project', () => { + const gql: Partial = { + cloudViewer: { + ...CloudUserStubs.me, + firstOrganization: { + __typename: 'CloudOrganizationConnection', + nodes: [{ __typename: 'CloudOrganization', id: '987' }], + }, + }, + currentProject: { + __typename: 'CurrentProject', + id: 'abc123', + projectId: null, + } as any, + } + + validateSmartNotificationBehaviors(BannerIds.ACI_082022_CONNECT_PROJECT, 'connect-project-banner', gql) + }) + + describe('record', () => { + const gql: Partial = { + cloudViewer: { + ...CloudUserStubs.me, + firstOrganization: { + __typename: 'CloudOrganizationConnection', + nodes: [{ __typename: 'CloudOrganization', id: '987' }], + }, + }, + currentProject: { + __typename: 'CurrentProject', + id: 'abc123', + title: 'my-test-project', + currentTestingType: 'component', + projectId: 'abcd', + cloudProject: { + ...CloudProjectStubs.componentProject, + runs: { + __typename: 'CloudRunConnection', + nodes: [], + }, + }, + } as any, + } + + beforeEach(() => { + cy.gqlStub.Query.currentProject = gql.currentProject as any + cy.gqlStub.Query.cloudViewer = gql.cloudViewer as any + }) + + validateSmartNotificationBehaviors(BannerIds.ACI_082022_RECORD, 'record-banner', gql) + }) }) diff --git a/packages/app/src/specs/SpecsListBanners.vue b/packages/app/src/specs/SpecsListBanners.vue index 234df7f26fb3..6d2f9c60e45f 100644 --- a/packages/app/src/specs/SpecsListBanners.vue +++ b/packages/app/src/specs/SpecsListBanners.vue @@ -16,7 +16,7 @@

{{ t('specPage.noSpecError.explainer') }}

+ + + + diff --git a/packages/app/src/specs/banners/ConnectProjectBanner.cy.tsx b/packages/app/src/specs/banners/ConnectProjectBanner.cy.tsx new file mode 100644 index 000000000000..aea9e561b263 --- /dev/null +++ b/packages/app/src/specs/banners/ConnectProjectBanner.cy.tsx @@ -0,0 +1,14 @@ +import { defaultMessages } from '@cy/i18n' +import ConnectProjectBanner from './ConnectProjectBanner.vue' + +describe('', () => { + it('should render expected content', () => { + cy.mount({ render: () => }) + + cy.contains(defaultMessages.specPage.banners.connectProject.title).should('be.visible') + cy.contains(defaultMessages.specPage.banners.connectProject.content).should('be.visible') + cy.contains(defaultMessages.specPage.banners.connectProject.buttonLabel).should('be.visible') + + cy.percySnapshot() + }) +}) diff --git a/packages/app/src/specs/banners/ConnectProjectBanner.vue b/packages/app/src/specs/banners/ConnectProjectBanner.vue new file mode 100644 index 000000000000..994acbc6c729 --- /dev/null +++ b/packages/app/src/specs/banners/ConnectProjectBanner.vue @@ -0,0 +1,78 @@ + + + diff --git a/packages/app/src/specs/banners/CreateOrganizationBanner.cy.tsx b/packages/app/src/specs/banners/CreateOrganizationBanner.cy.tsx new file mode 100644 index 000000000000..7399398e23bb --- /dev/null +++ b/packages/app/src/specs/banners/CreateOrganizationBanner.cy.tsx @@ -0,0 +1,26 @@ +import { defaultMessages } from '@cy/i18n' +import CreateOrganizationBanner from './CreateOrganizationBanner.vue' + +describe('', () => { + it('should render expected content', () => { + const linkHref = 'http://dummy.cypress.io/organizations/create' + + cy.gqlStub.Query.cloudViewer = { + __typename: 'CloudUser', + id: 'test123', + cloudOrganizationsUrl: linkHref, + } as any + + cy.mount({ render: () => }) + + cy.contains(defaultMessages.specPage.banners.createOrganization.title).should('be.visible') + cy.contains(defaultMessages.specPage.banners.createOrganization.content).should('be.visible') + cy.contains(defaultMessages.specPage.banners.createOrganization.buttonLabel).should('be.visible') + + cy.get('a') + .should('have.attr', 'href') + .and('contain', linkHref) + + cy.percySnapshot() + }) +}) diff --git a/packages/app/src/specs/banners/CreateOrganizationBanner.vue b/packages/app/src/specs/banners/CreateOrganizationBanner.vue new file mode 100644 index 000000000000..9edbd18f4911 --- /dev/null +++ b/packages/app/src/specs/banners/CreateOrganizationBanner.vue @@ -0,0 +1,79 @@ + + + diff --git a/packages/app/src/specs/banners/LoginBanner.cy.tsx b/packages/app/src/specs/banners/LoginBanner.cy.tsx new file mode 100644 index 000000000000..be35a5586ea4 --- /dev/null +++ b/packages/app/src/specs/banners/LoginBanner.cy.tsx @@ -0,0 +1,14 @@ +import { defaultMessages } from '@cy/i18n' +import LoginBanner from './LoginBanner.vue' + +describe('', () => { + it('should render expected content', () => { + cy.mount({ render: () => }) + + cy.contains(defaultMessages.specPage.banners.login.title).should('be.visible') + cy.contains(defaultMessages.specPage.banners.login.content).should('be.visible') + cy.contains(defaultMessages.specPage.banners.login.buttonLabel).should('be.visible') + + cy.percySnapshot() + }) +}) diff --git a/packages/app/src/specs/banners/LoginBanner.vue b/packages/app/src/specs/banners/LoginBanner.vue new file mode 100644 index 000000000000..d98a2279c474 --- /dev/null +++ b/packages/app/src/specs/banners/LoginBanner.vue @@ -0,0 +1,70 @@ + + + diff --git a/packages/app/src/specs/banners/RecordBanner.cy.tsx b/packages/app/src/specs/banners/RecordBanner.cy.tsx new file mode 100644 index 000000000000..ff7f8acf8d2b --- /dev/null +++ b/packages/app/src/specs/banners/RecordBanner.cy.tsx @@ -0,0 +1,30 @@ +import { defaultMessages } from '@cy/i18n' +import RecordBanner from './RecordBanner.vue' + +describe('', () => { + it('should render expected content', () => { + cy.mount({ render: () => }) + + cy.gqlStub.Query.currentProject = { + id: 'test_id', + title: 'project_title', + currentTestingType: 'component', + cloudProject: { + __typename: 'CloudProject', + id: 'cloud_id', + recordKeys: [{ + __typename: 'CloudRecordKey', + id: 'recordKey1', + key: 'abcd-efg-1234', + }], + } as any, + } as any + + cy.contains(defaultMessages.specPage.banners.record.title).should('be.visible') + cy.contains(defaultMessages.specPage.banners.record.content).should('be.visible') + + cy.findByText('cypress run --component --record --key abcd-efg-1234') + + cy.percySnapshot() + }) +}) diff --git a/packages/app/src/specs/banners/RecordBanner.vue b/packages/app/src/specs/banners/RecordBanner.vue new file mode 100644 index 000000000000..3e364cc99b07 --- /dev/null +++ b/packages/app/src/specs/banners/RecordBanner.vue @@ -0,0 +1,78 @@ + + + diff --git a/packages/app/src/specs/banners/TrackedBanner.cy.tsx b/packages/app/src/specs/banners/TrackedBanner.cy.tsx new file mode 100644 index 000000000000..8a1feb89c0d7 --- /dev/null +++ b/packages/app/src/specs/banners/TrackedBanner.cy.tsx @@ -0,0 +1,64 @@ +import TrackedBanner from './TrackedBanner.vue' +import { ref } from 'vue' +import { TrackedBanner_SetProjectStateDocument } from '../../generated/graphql' + +describe('', () => { + it('should pass through props and child content', () => { + cy.mount({ render: () => Test Content }) + + cy.findByText('Test Content').should('be.visible') + cy.findByTestId('alert-suffix-icon').should('be.visible') + + cy.percySnapshot() + }) + + it('should record when banner is made visible', () => { + cy.clock(1234) + const recordStub = cy.stub() + const shown = ref(true) + + cy.stubMutationResolver(TrackedBanner_SetProjectStateDocument, (defineResult, { value }) => { + recordStub(value) + + return defineResult({ setPreferences: {} as any }) + }) + + // Initially mount as visible + // @ts-ignore + cy.mount({ render: () => }) + + cy.get('[data-cy="banner"]').as('banner') + + cy.get('@banner').should('be.visible') + .then(() => { + expect(recordStub).to.have.been.calledWith('{"banners":{"test-banner":{"lastShown":1234}}}') + }) + }) + + it('should record when banner is dismissed', () => { + cy.clock(1234) + const recordStub = cy.stub() + const shown = ref(true) + + cy.stubMutationResolver(TrackedBanner_SetProjectStateDocument, (defineResult, { value }) => { + recordStub(value) + + return defineResult({ setPreferences: {} as any }) + }) + + // Initially mount as visible + // @ts-ignore + cy.mount({ render: () => }) + + cy.get('[data-cy="banner"]').as('banner') + + cy.get('@banner').should('be.visible') + + cy.get('@banner').findByTestId('alert-suffix-icon').click() + + cy.get('@banner').should('not.exist') + .then(() => { + expect(recordStub).to.have.been.calledWith('{"banners":{"test-banner":{"dismissed":1234}}}') + }) + }) +}) diff --git a/packages/app/src/specs/banners/TrackedBanner.vue b/packages/app/src/specs/banners/TrackedBanner.vue new file mode 100644 index 000000000000..e9f8b925e32a --- /dev/null +++ b/packages/app/src/specs/banners/TrackedBanner.vue @@ -0,0 +1,75 @@ + + + diff --git a/packages/app/src/specs/banners/index.ts b/packages/app/src/specs/banners/index.ts new file mode 100644 index 000000000000..c952e10fddbb --- /dev/null +++ b/packages/app/src/specs/banners/index.ts @@ -0,0 +1,7 @@ +export { default as LoginBanner } from './LoginBanner.vue' + +export { default as CreateOrganizationBanner } from './CreateOrganizationBanner.vue' + +export { default as ConnectProjectBanner } from './ConnectProjectBanner.vue' + +export { default as RecordBanner } from './RecordBanner.vue' diff --git a/packages/data-context/src/actions/ProjectActions.ts b/packages/data-context/src/actions/ProjectActions.ts index 3562bd88fb01..ef57970327cd 100644 --- a/packages/data-context/src/actions/ProjectActions.ts +++ b/packages/data-context/src/actions/ProjectActions.ts @@ -35,7 +35,7 @@ export interface ProjectApiShape { getConfig(): ReceivedCypressOptions | undefined getRemoteStates(): { reset(): void, getPrimary(): Cypress.RemoteState } | undefined getCurrentBrowser: () => Cypress.Browser | undefined - getCurrentProjectSavedState(): {} | undefined + getCurrentProjectSavedState(): AllowedState | undefined setPromptShown(slug: string): void setProjectPreferences(stated: AllowedState): void makeProjectSavedState(projectRoot: string): void diff --git a/packages/data-context/src/data/coreDataShape.ts b/packages/data-context/src/data/coreDataShape.ts index f941033cb231..ebf1734b129b 100644 --- a/packages/data-context/src/data/coreDataShape.ts +++ b/packages/data-context/src/data/coreDataShape.ts @@ -1,4 +1,4 @@ -import { FoundBrowser, Editor, AllowedState, AllModeOptions, TestingType, BrowserStatus, PACKAGE_MANAGERS, AuthStateName, MIGRATION_STEPS, MigrationStep } from '@packages/types' +import { FoundBrowser, Editor, AllowedState, AllModeOptions, TestingType, BrowserStatus, PACKAGE_MANAGERS, AuthStateName, MIGRATION_STEPS, MigrationStep, BannerState } from '@packages/types' import type { WizardFrontendFramework, WizardBundler } from '@packages/scaffold-config' import type { NexusGenObjects } from '@packages/graphql/src/gen/nxs.gen' import type { App, BrowserWindow } from 'electron' @@ -35,6 +35,7 @@ export interface SavedStateShape { firstOpened?: number | null lastOpened?: number | null promptsShown?: object | null + banners?: BannerState | null lastProjectId?: string | null specFilter?: string | null } diff --git a/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts b/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts index 02bda550a70c..b2cce8cb6688 100644 --- a/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts +++ b/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts @@ -304,6 +304,7 @@ function startAppServer (mode: 'component' | 'e2e' = 'e2e', options: { skipMocki firstOpened: 1609459200000, lastOpened: 1609459200000, promptsShown: { ci1: 1609459200000 }, + banners: { _disabled: true }, }) } diff --git a/packages/frontend-shared/cypress/support/component.ts b/packages/frontend-shared/cypress/support/component.ts index 2b73857ff135..5e948d3a92ab 100644 --- a/packages/frontend-shared/cypress/support/component.ts +++ b/packages/frontend-shared/cypress/support/component.ts @@ -20,7 +20,6 @@ declare global { } } } - cy.i18n = defaultMessages cy.gqlStub = GQLStubRegistry diff --git a/packages/frontend-shared/src/assets/icons/action-record_x16.svg b/packages/frontend-shared/src/assets/icons/action-record_x16.svg index 3b0617103e50..47b01e392576 100644 --- a/packages/frontend-shared/src/assets/icons/action-record_x16.svg +++ b/packages/frontend-shared/src/assets/icons/action-record_x16.svg @@ -1,6 +1,5 @@ - - - - - + + + + diff --git a/packages/frontend-shared/src/gql-components/HeaderBarContent.cy.tsx b/packages/frontend-shared/src/gql-components/HeaderBarContent.cy.tsx index 60ac66dad2cf..102115453f64 100644 --- a/packages/frontend-shared/src/gql-components/HeaderBarContent.cy.tsx +++ b/packages/frontend-shared/src/gql-components/HeaderBarContent.cy.tsx @@ -357,7 +357,7 @@ describe('', { viewportWidth: 1000, viewportHeight: 750 }, ( }) function mountWithSavedState (options?: {state?: object, projectId?: string }) { - return cy.mountFragment(HeaderBar_HeaderBarContentFragmentDoc, { + const mountResult = cy.mountFragment(HeaderBar_HeaderBarContentFragmentDoc, { onResult: (result) => { if (!result.currentProject) { return @@ -378,6 +378,12 @@ describe('', { viewportWidth: 1000, viewportHeight: 750 }, ( }, render: (gqlVal) =>
, }) + + // Auto-opening prompts wait 2000ms after mount before opening + // Advance to that point so that prompts will have had a chance to open + cy.tick(2000) + + return mountResult } it('opens when after 4 days from first open, no projectId, and not already shown', () => { diff --git a/packages/frontend-shared/src/gql-components/HeaderBarContent.vue b/packages/frontend-shared/src/gql-components/HeaderBarContent.vue index efee244786d6..595b853635fa 100644 --- a/packages/frontend-shared/src/gql-components/HeaderBarContent.vue +++ b/packages/frontend-shared/src/gql-components/HeaderBarContent.vue @@ -166,7 +166,7 @@ + + \ No newline at end of file diff --git a/packages/driver/src/cross-origin/communicator.ts b/packages/driver/src/cross-origin/communicator.ts index 0e98df5ee5ef..477407a7f543 100644 --- a/packages/driver/src/cross-origin/communicator.ts +++ b/packages/driver/src/cross-origin/communicator.ts @@ -9,7 +9,7 @@ const debug = debugFn('cypress:driver:multi-origin') const CROSS_ORIGIN_PREFIX = 'cross:origin:' const LOG_EVENTS = [`${CROSS_ORIGIN_PREFIX}log:added`, `${CROSS_ORIGIN_PREFIX}log:changed`] -const FINAL_SNAPSHOT_EVENT = `${CROSS_ORIGIN_PREFIX}final:snapshot:generated` +const SNAPSHOT_EVENT_PREFIX = `${CROSS_ORIGIN_PREFIX}snapshot:` /** * Primary Origin communicator. Responsible for sending/receiving events throughout @@ -50,8 +50,8 @@ export class PrimaryOriginCommunicator extends EventEmitter { data.data = reifyLogFromSerialization(data.data as any) } - // reify the final snapshot coming back from the secondary domain if requested by the runner. - if (FINAL_SNAPSHOT_EVENT === data?.event) { + // reify the final or requested snapshot coming back from the secondary domain if requested by the runner. + if (data?.event.includes(SNAPSHOT_EVENT_PREFIX) && !Cypress._.isEmpty(data?.data)) { data.data = reifySnapshotFromSerialization(data.data as any) } @@ -191,8 +191,9 @@ export class SpecBridgeCommunicator extends EventEmitter { data = preprocessLogForSerialization(data as any) } - // If requested by the runner, preprocess the final snapshot before sending through postMessage() to attempt to serialize the DOM body of the snapshot. - if (FINAL_SNAPSHOT_EVENT === eventName) { + // If requested by the runner, preprocess the snapshot before sending through postMessage() to attempt to serialize the DOM body of the snapshot. + // NOTE: SNAPSHOT_EVENT_PREFIX events, if requested by the log manager, are namespaced per primary log + if (eventName.includes(SNAPSHOT_EVENT_PREFIX) && !Cypress._.isEmpty(data)) { data = preprocessSnapshotForSerialization(data as any) } diff --git a/packages/driver/src/cross-origin/cypress.ts b/packages/driver/src/cross-origin/cypress.ts index c30c4485f861..2724fd9da847 100644 --- a/packages/driver/src/cross-origin/cypress.ts +++ b/packages/driver/src/cross-origin/cypress.ts @@ -43,10 +43,23 @@ const createCypress = () => { // if true, this is the correct specbridge to take the snapshot and send it back const finalSnapshot = cy.createSnapshot(FINAL_SNAPSHOT_NAME) - Cypress.specBridgeCommunicator.toPrimary('final:snapshot:generated', finalSnapshot) + Cypress.specBridgeCommunicator.toPrimary('snapshot:final:generated', finalSnapshot) } }) + Cypress.specBridgeCommunicator.on('generate:snapshot:for:log', ({ name, id }) => { + // if the snapshot cannot be taken (in a transitory space), set to an empty object in order to not fail serialization + let requestedCrossOriginSnapshot = {} + + // don't attempt to take snapshots after the spec bridge has been unloaded. Instead, send an empty snapshot back to the primary + // to display current state of dom + if (cy.state('document') !== undefined) { + requestedCrossOriginSnapshot = cy.createSnapshot(name) || {} + } + + Cypress.specBridgeCommunicator.toPrimary(`snapshot:for:log:generated:${id}`, requestedCrossOriginSnapshot) + }) + Cypress.specBridgeCommunicator.toPrimary('bridge:ready') } diff --git a/packages/driver/src/cypress/log.ts b/packages/driver/src/cypress/log.ts index 7346dbf178fa..56ee9ed5fa73 100644 --- a/packages/driver/src/cypress/log.ts +++ b/packages/driver/src/cypress/log.ts @@ -341,20 +341,7 @@ export class Log { return _.pick(this.attributes, args) } - snapshot (name?, options: any = {}) { - // bail early and don't snapshot if we're in headless mode - // or we're not storing tests - if (!this.config('isInteractive') || (this.config('numTestsKeptInMemory') === 0)) { - return this - } - - _.defaults(options, { - at: null, - next: null, - }) - - const snapshot = this.cy.createSnapshot(name, this.get('$el')) - + private addSnapshot (snapshot, options, shouldRebindSnapshotFn = true) { const snapshots = this.get('snapshots') || [] // don't add snapshot if we couldn't create one, which can happen @@ -367,21 +354,58 @@ export class Log { this.set('snapshots', snapshots) - if (options.next) { - const fn = this.snapshot + if (options.next && shouldRebindSnapshotFn) { + const originalLogSnapshotFn = this.snapshot this.snapshot = function () { - // restore the fn - this.snapshot = fn + // restore the original snapshot function + this.snapshot = originalLogSnapshotFn // call orig fn with next as name - return fn.call(this, options.next) + return originalLogSnapshotFn.call(this, options.next) } } return this } + snapshot (name?, options: any = {}) { + // bail early and don't snapshot if we're in headless mode + // or we're not storing tests + if (!this.config('isInteractive') || (this.config('numTestsKeptInMemory') === 0)) { + return this + } + + _.defaults(options, { + at: null, + next: null, + }) + + if (this.config('experimentalSessionAndOrigin') && !Cypress.isCrossOriginSpecBridge) { + const activeSpecBridgeOriginPolicyIfApplicable = this.state('currentActiveOriginPolicy') || undefined + // @ts-ignore + const { originPolicy: originPolicyThatIsSoonToBeOrIsActive } = Cypress.Location.create(this.state('anticipatingCrossOriginResponse')?.href || this.state('url')) + + if (activeSpecBridgeOriginPolicyIfApplicable && activeSpecBridgeOriginPolicyIfApplicable === originPolicyThatIsSoonToBeOrIsActive) { + Cypress.emit('request:snapshot:from:spec:bridge', { + log: this, + name, + options, + specBridge: activeSpecBridgeOriginPolicyIfApplicable, + addSnapshot: this.addSnapshot, + }) + + return this + } + } + + const snapshot = this.cy.createSnapshot(name, this.get('$el')) + + this.addSnapshot(snapshot, options) + + return this + } + error (err) { const logGroupIds = this.state('logGroupIds') || [] From 95f4e226708fd84cf20a9d04d101b2deb41fe33d Mon Sep 17 00:00:00 2001 From: Matt Schile Date: Wed, 17 Aug 2022 10:51:26 -0600 Subject: [PATCH 06/45] updating name --- .github/workflows/add_to_triage_project.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/add_to_triage_project.yml b/.github/workflows/add_to_triage_project.yml index d13b5fd9109f..d0f913bc1e49 100644 --- a/.github/workflows/add_to_triage_project.yml +++ b/.github/workflows/add_to_triage_project.yml @@ -1,4 +1,4 @@ -name: Add issue/PR to triage project +name: Add issue/PR to project on: issues: @@ -10,7 +10,7 @@ on: jobs: add-to-triage-project: - name: Add issue/PR to triage project + name: Add to triage project runs-on: ubuntu-latest steps: - uses: actions/add-to-project@v0.3.0 From a27affe4477da85f07a5075dc2fca3ae61d50489 Mon Sep 17 00:00:00 2001 From: Kukhyeon Heo Date: Thu, 18 Aug 2022 02:54:02 +0900 Subject: [PATCH 07/45] chore: refactor server/lib/config.ts to pkg/config (#22530) Co-authored-by: Rachel Co-authored-by: Emily Rohrbough Co-authored-by: Rachel --- package.json | 1 + packages/config/package.json | 4 +- packages/config/src/index.ts | 4 + packages/config/src/project/index.ts | 133 ++ packages/config/src/project/types.ts | 1 + packages/config/src/project/utils.ts | 538 +++++++ .../util/coerce.ts => config/src/utils.ts} | 45 +- packages/config/test/project/index.spec.ts | 194 +++ packages/config/test/project/utils.spec.ts | 1267 +++++++++++++++ packages/config/test/utils.spec.ts | 166 ++ packages/data-context/src/DataContext.ts | 4 +- .../src/data/ProjectConfigManager.ts | 16 +- packages/data-context/test/unit/helper.ts | 2 - packages/driver/package.json | 1 - packages/network/lib/uri.ts | 34 +- packages/network/test/unit/uri_spec.ts | 19 + packages/server/lib/config.ts | 606 +------ packages/server/lib/makeDataContext.ts | 10 - packages/server/lib/modes/record.js | 5 +- packages/server/lib/remote_states.ts | 5 +- packages/server/lib/scaffold.js | 8 +- packages/server/lib/util/args.js | 7 +- packages/server/lib/util/config.ts | 45 - packages/server/lib/util/keys.js | 20 - packages/server/lib/util/origin.js | 14 - packages/server/lib/util/path_helpers.js | 38 - packages/server/package.json | 1 - .../test/integration/http_requests_spec.js | 2 +- .../server/test/integration/server_spec.js | 3 +- .../performance/proxy_performance_spec.js | 8 +- packages/server/test/unit/config_spec.js | 1389 ----------------- packages/server/test/unit/project_spec.js | 2 +- packages/server/test/unit/server_spec.js | 5 +- packages/server/test/unit/util/coerce_spec.js | 86 - packages/server/test/unit/util/config_spec.js | 48 - packages/server/test/unit/util/keys_spec.ts | 20 - packages/server/test/unit/util/origin_spec.js | 18 - .../test/unit/util/path_helpers_spec.js | 21 - packages/ts/tsconfig.json | 2 +- patches/return-deep-diff+0.4.0.patch | 7 + 40 files changed, 2443 insertions(+), 2356 deletions(-) create mode 100644 packages/config/src/project/index.ts create mode 100644 packages/config/src/project/types.ts create mode 100644 packages/config/src/project/utils.ts rename packages/{server/lib/util/coerce.ts => config/src/utils.ts} (64%) create mode 100644 packages/config/test/project/index.spec.ts create mode 100644 packages/config/test/project/utils.spec.ts create mode 100644 packages/config/test/utils.spec.ts delete mode 100644 packages/server/lib/util/config.ts delete mode 100644 packages/server/lib/util/keys.js delete mode 100644 packages/server/lib/util/origin.js delete mode 100644 packages/server/lib/util/path_helpers.js delete mode 100644 packages/server/test/unit/util/coerce_spec.js delete mode 100644 packages/server/test/unit/util/config_spec.js delete mode 100644 packages/server/test/unit/util/keys_spec.ts delete mode 100644 packages/server/test/unit/util/origin_spec.js delete mode 100644 packages/server/test/unit/util/path_helpers_spec.js create mode 100644 patches/return-deep-diff+0.4.0.patch diff --git a/package.json b/package.json index cca80030cf0b..11c78836947d 100644 --- a/package.json +++ b/package.json @@ -119,6 +119,7 @@ "@types/send": "^0.17.1", "@types/sinon-chai": "3.2.3", "@types/through2": "^2.0.36", + "@types/underscore.string": "0.0.38", "@typescript-eslint/eslint-plugin": "4.18.0", "@typescript-eslint/parser": "4.18.0", "@urql/introspection": "^0.3.0", diff --git a/packages/config/package.json b/packages/config/package.json index 3b8fbb510566..e8c31a04093f 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -27,9 +27,11 @@ "debug": "^4.3.2", "fs-extra": "^9.1.0", "lodash": "^4.17.21", - "recast": "0.20.4" + "recast": "0.20.4", + "return-deep-diff": "0.4.0" }, "devDependencies": { + "@packages/errors": "0.0.0-development", "@packages/root": "0.0.0-development", "@packages/ts": "0.0.0-development", "@packages/types": "0.0.0-development", diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 95f8b23d9d7a..5b42e02b3041 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -2,4 +2,8 @@ // babel transforms, etc. into client-side usage of the config code export * from './browser' +export * from './project' + export { addProjectIdToCypressConfig, addToCypressConfig, addTestingTypeToCypressConfig, AddTestingTypeToCypressConfigOptions, defineConfigAvailable } from './ast-utils/addToCypressConfig' + +export * from './utils' diff --git a/packages/config/src/project/index.ts b/packages/config/src/project/index.ts new file mode 100644 index 000000000000..9c68ce2f7c03 --- /dev/null +++ b/packages/config/src/project/index.ts @@ -0,0 +1,133 @@ +import _ from 'lodash' +import Debug from 'debug' +import deepDiff from 'return-deep-diff' + +import errors, { ConfigValidationFailureInfo, CypressError } from '@packages/errors' +import type { + ResolvedFromConfig, TestingType, FullConfig, +} from '@packages/types' + +import { + validate, + validateNoBreakingConfig, +} from '../browser' +import { + setPluginResolvedOn, + mergeDefaults, +} from './utils' + +const debug = Debug('cypress:config:project') + +// TODO: any -> SetupFullConfigOptions in data-context/src/data/ProjectConfigManager.ts +export function setupFullConfigWithDefaults (obj: any = {}, getFilesByGlob: any): Promise { + debug('setting config object %o', obj) + let { projectRoot, projectName, config, envFile, options, cliConfig } = obj + + // just force config to be an object so we dont have to do as much + // work in our tests + if (config == null) { + config = {} + } + + debug('config is %o', config) + + // flatten the object's properties into the master config object + config.envFile = envFile + config.projectRoot = projectRoot + config.projectName = projectName + + // @ts-ignore + return mergeDefaults(config, options, cliConfig, getFilesByGlob) +} + +// TODO: update types from data-context/src/data/ProjectLifecycleManager.ts +// updateWithPluginValues(config: FullConfig, modifiedConfig: Partial, testingType: TestingType): FullConfig +export function updateWithPluginValues (cfg: FullConfig, modifiedConfig: any, testingType: TestingType): FullConfig { + if (!modifiedConfig) { + modifiedConfig = {} + } + + debug('updateWithPluginValues %o', { cfg, modifiedConfig }) + + // make sure every option returned from the plugins file + // passes our validation functions + validate(modifiedConfig, (validationResult: ConfigValidationFailureInfo | string) => { + let configFile = cfg.configFile! + + if (_.isString(validationResult)) { + return errors.throwErr('CONFIG_VALIDATION_MSG_ERROR', 'configFile', configFile, validationResult) + } + + return errors.throwErr('CONFIG_VALIDATION_ERROR', 'configFile', configFile, validationResult) + }) + + debug('validate that there is no breaking config options added by setupNodeEvents') + + function makeSetupError (cyError: CypressError) { + cyError.name = `Error running ${testingType}.setupNodeEvents()` + + return cyError + } + + validateNoBreakingConfig(modifiedConfig, errors.warning, (err, options) => { + throw makeSetupError(errors.get(err, options)) + }, testingType) + + validateNoBreakingConfig(modifiedConfig[testingType], errors.warning, (err, options) => { + throw makeSetupError(errors.get(err, { + ...options, + name: `${testingType}.${options.name}`, + })) + }, testingType) + + const originalResolvedBrowsers = _.cloneDeep(cfg?.resolved?.browsers) ?? { + value: cfg.browsers, + from: 'default', + } as ResolvedFromConfig + + const diffs = deepDiff(cfg, modifiedConfig, true) + + debug('config diffs %o', diffs) + + const userBrowserList = diffs && diffs.browsers && _.cloneDeep(diffs.browsers) + + if (userBrowserList) { + debug('user browser list %o', userBrowserList) + } + + // for each override go through + // and change the resolved values of cfg + // to point to the plugin + if (diffs) { + debug('resolved config before diffs %o', cfg.resolved) + setPluginResolvedOn(cfg.resolved, diffs) + debug('resolved config object %o', cfg.resolved) + } + + // merge cfg into overrides + const merged = _.defaultsDeep(diffs, cfg) + + debug('merged config object %o', merged) + + // the above _.defaultsDeep combines arrays, + // if diffs.browsers = [1] and cfg.browsers = [1, 2] + // then the merged result merged.browsers = [1, 2] + // which is NOT what we want + if (Array.isArray(userBrowserList) && userBrowserList.length) { + merged.browsers = userBrowserList + merged.resolved.browsers.value = userBrowserList + } + + if (modifiedConfig.browsers === null) { + // null breaks everything when merging lists + debug('replacing null browsers with original list %o', originalResolvedBrowsers) + merged.browsers = cfg.browsers + if (originalResolvedBrowsers) { + merged.resolved.browsers = originalResolvedBrowsers + } + } + + debug('merged plugins config %o', merged) + + return merged +} diff --git a/packages/config/src/project/types.ts b/packages/config/src/project/types.ts new file mode 100644 index 000000000000..d0cbc4ff8c7b --- /dev/null +++ b/packages/config/src/project/types.ts @@ -0,0 +1 @@ +export type Config = Record diff --git a/packages/config/src/project/utils.ts b/packages/config/src/project/utils.ts new file mode 100644 index 000000000000..be927d357086 --- /dev/null +++ b/packages/config/src/project/utils.ts @@ -0,0 +1,538 @@ +import Bluebird from 'bluebird' +import Debug from 'debug' +import fs from 'fs-extra' +import _ from 'lodash' +import path from 'path' + +import type { + ResolvedFromConfig, + ResolvedConfigurationOptionSource, +} from '@packages/types' +import errors, { ConfigValidationFailureInfo, CypressError } from '@packages/errors' + +import type { Config } from './types' + +import { + allowed, + getDefaultValues, + matchesConfigKey, + getPublicConfigKeys, + validate, + validateNoBreakingConfig, +} from '../browser' +import { hideKeys, setUrls, coerce } from '../utils' +import { options } from '../options' + +const debug = Debug('cypress:config:project:utils') + +const hideSpecialVals = function (val: string, key: string) { + if (_.includes(CYPRESS_SPECIAL_ENV_VARS, key)) { + return hideKeys(val) + } + + return val +} + +// an object with a few utility methods for easy stubbing from unit tests +export const utils = { + getProcessEnvVars (obj: NodeJS.ProcessEnv) { + return _.reduce(obj, (memo: Record, value: string | undefined, key: string) => { + if (!value) { + return memo + } + + if (isCypressEnvLike(key)) { + memo[removeEnvPrefix(key)] = coerce(value) + } + + return memo + }, {}) + }, + + resolveModule (name: string) { + return require.resolve(name) + }, + + // returns: + // false - if the file should not be set + // string - found filename + // null - if there is an error finding the file + discoverModuleFile (options: { + filename: string + projectRoot: string + }) { + debug('discover module file %o', options) + const { filename } = options + + // they have it explicitly set, so it should be there + return fs.pathExists(filename) + .then((found) => { + if (found) { + debug('file exists, assuming it will load') + + return filename + } + + debug('could not find %o', { filename }) + + return null + }) + }, +} + +const CYPRESS_ENV_PREFIX = 'CYPRESS_' + +const CYPRESS_ENV_PREFIX_LENGTH = CYPRESS_ENV_PREFIX.length + +export const CYPRESS_RESERVED_ENV_VARS = [ + 'CYPRESS_INTERNAL_ENV', +] + +export const CYPRESS_SPECIAL_ENV_VARS = [ + 'RECORD_KEY', +] + +const isCypressEnvLike = (key: string) => { + return _.chain(key) + .invoke('toUpperCase') + .startsWith(CYPRESS_ENV_PREFIX) + .value() && + !_.includes(CYPRESS_RESERVED_ENV_VARS, key) +} + +const removeEnvPrefix = (key: string) => { + return key.slice(CYPRESS_ENV_PREFIX_LENGTH) +} + +export function parseEnv (cfg: Record, cliEnvs: Record, resolved: Record = {}) { + const envVars: any = (resolved.env = {}) + + const resolveFrom = (from: string, obj = {}) => { + return _.each(obj, (val, key) => { + return envVars[key] = { + value: val, + from, + } + }) + } + + const configEnv = cfg.env != null ? cfg.env : {} + const envFile = cfg.envFile != null ? cfg.envFile : {} + let processEnvs = utils.getProcessEnvVars(process.env) || {} + + cliEnvs = cliEnvs != null ? cliEnvs : {} + + const configFromEnv = _.reduce(processEnvs, (memo: string[], val, key) => { + const cfgKey = matchesConfigKey(key) + + if (cfgKey) { + // only change the value if it hasn't been + // set by the CLI. override default + config + if (resolved[cfgKey] !== 'cli') { + cfg[cfgKey] = val + resolved[cfgKey] = { + value: val, + from: 'env', + } as ResolvedFromConfig + } + + memo.push(key) + } + + return memo + }, []) + + processEnvs = _.chain(processEnvs) + .omit(configFromEnv) + .mapValues(hideSpecialVals) + .value() + + resolveFrom('config', configEnv) + resolveFrom('envFile', envFile) + resolveFrom('env', processEnvs) + resolveFrom('cli', cliEnvs) + + // configEnvs is from cypress.config.{js,ts,mjs,cjs} + // envFile is from cypress.env.json + // processEnvs is from process env vars + // cliEnvs is from CLI arguments + return _.extend(configEnv, envFile, processEnvs, cliEnvs) +} + +// combines the default configuration object with values specified in the +// configuration file like "cypress.{ts|js}". Values in configuration file +// overwrite the defaults. +export function resolveConfigValues (config: Config, defaults: Record, resolved: any = {}) { + // pick out only known configuration keys + return _ + .chain(config) + .pick(getPublicConfigKeys()) + .mapValues((val, key) => { + const source = (s: ResolvedConfigurationOptionSource): ResolvedFromConfig => { + return { + value: val, + from: s, + } + } + + const r = resolved[key] + + if (r) { + if (_.isObject(r)) { + return r + } + + return source(r) + } + + if (_.isEqual(config[key], defaults[key]) || key === 'browsers') { + // "browsers" list is special, since it is dynamic by default + // and can only be overwritten via plugins file + return source('default') + } + + return source('config') + }) + .value() +} + +// Given an object "resolvedObj" and a list of overrides in "obj" +// marks all properties from "obj" inside "resolvedObj" using +// {value: obj.val, from: "plugin"} +export function setPluginResolvedOn (resolvedObj: Record, obj: Record): any { + return _.each(obj, (val, key) => { + if (_.isObject(val) && !_.isArray(val) && resolvedObj[key]) { + // recurse setting overrides + // inside of objected + return setPluginResolvedOn(resolvedObj[key], val) + } + + const valueFrom: ResolvedFromConfig = { + value: val, + from: 'plugin', + } + + resolvedObj[key] = valueFrom + }) +} + +export function setAbsolutePaths (obj: Config) { + obj = _.clone(obj) + + // if we have a projectRoot + const pr = obj.projectRoot + + if (pr) { + // reset fileServerFolder to be absolute + // obj.fileServerFolder = path.resolve(pr, obj.fileServerFolder) + + // and do the same for all the rest + _.extend(obj, convertRelativeToAbsolutePaths(pr, obj)) + } + + return obj +} + +const folders = _(options).filter({ isFolder: true }).map('name').value() + +const convertRelativeToAbsolutePaths = (projectRoot: string, obj: Config) => { + return _.reduce(folders, (memo: Record, folder) => { + const val = obj[folder] + + if ((val != null) && (val !== false)) { + memo[folder] = path.resolve(projectRoot, val) + } + + return memo + }, {}) +} + +// instead of the built-in Node process, specify a path to 3rd party Node +export const setNodeBinary = (obj: Config, userNodePath?: string, userNodeVersion?: string) => { + // if execPath isn't found we weren't executed from the CLI and should used the bundled node version. + if (userNodePath && userNodeVersion && obj.nodeVersion !== 'bundled') { + obj.resolvedNodePath = userNodePath + obj.resolvedNodeVersion = userNodeVersion + + return obj + } + + obj.resolvedNodeVersion = process.versions.node + + return obj +} + +export function relativeToProjectRoot (projectRoot: string, file: string) { + if (!file.startsWith(projectRoot)) { + return file + } + + // captures leading slash(es), both forward slash and back slash + const leadingSlashRe = /^[\/|\\]*(?![\/|\\])/ + + return file.replace(projectRoot, '').replace(leadingSlashRe, '') +} + +// async function +export async function setSupportFileAndFolder (obj: Config, getFilesByGlob: any) { + if (!obj.supportFile) { + return Bluebird.resolve(obj) + } + + obj = _.clone(obj) + + const supportFilesByGlob = await getFilesByGlob(obj.projectRoot, obj.supportFile) + + if (supportFilesByGlob.length > 1) { + return errors.throwErr('MULTIPLE_SUPPORT_FILES_FOUND', obj.supportFile, supportFilesByGlob) + } + + if (supportFilesByGlob.length === 0) { + if (obj.resolved.supportFile.from === 'default') { + return errors.throwErr('DEFAULT_SUPPORT_FILE_NOT_FOUND', relativeToProjectRoot(obj.projectRoot, obj.supportFile)) + } + + return errors.throwErr('SUPPORT_FILE_NOT_FOUND', relativeToProjectRoot(obj.projectRoot, obj.supportFile)) + } + + // TODO move this logic to find support file into util/path_helpers + const sf: string = supportFilesByGlob[0]! + + debug(`setting support file ${sf}`) + debug(`for project root ${obj.projectRoot}`) + + return Bluebird + .try(() => { + // resolve full path with extension + obj.supportFile = utils.resolveModule(sf) + + return debug('resolved support file %s', obj.supportFile) + }).then(() => { + if (!checkIfResolveChangedRootFolder(obj.supportFile, sf)) { + return + } + + debug('require.resolve switched support folder from %s to %s', sf, obj.supportFile) + // this means the path was probably symlinked, like + // /tmp/foo -> /private/tmp/foo + // which can confuse the rest of the code + // switch it back to "normal" file + const supportFileName = path.basename(obj.supportFile) + const base = sf?.endsWith(supportFileName) ? path.dirname(sf) : sf + + obj.supportFile = path.join(base || '', supportFileName) + + return fs.pathExists(obj.supportFile) + .then((found) => { + if (!found) { + errors.throwErr('SUPPORT_FILE_NOT_FOUND', relativeToProjectRoot(obj.projectRoot, obj.supportFile)) + } + + return debug('switching to found file %s', obj.supportFile) + }) + }).catch({ code: 'MODULE_NOT_FOUND' }, () => { + debug('support JS module %s does not load', sf) + + return utils.discoverModuleFile({ + filename: sf, + projectRoot: obj.projectRoot, + }) + .then((result) => { + if (result === null) { + return errors.throwErr('SUPPORT_FILE_NOT_FOUND', relativeToProjectRoot(obj.projectRoot, sf)) + } + + debug('setting support file to %o', { result }) + obj.supportFile = result + + return obj + }) + }) + .then(() => { + if (obj.supportFile) { + // set config.supportFolder to its directory + obj.supportFolder = path.dirname(obj.supportFile) + debug(`set support folder ${obj.supportFolder}`) + } + + return obj + }) +} + +export function mergeDefaults ( + config: Config = {}, + options: Record = {}, + cliConfig: Record = {}, + getFilesByGlob: any, +) { + const resolved: any = {} + const { testingType } = options + + config.rawJson = _.cloneDeep(config) + + _.extend(config, _.pick(options, 'configFile', 'morgan', 'isTextTerminal', 'socketId', 'report', 'browsers')) + debug('merged config with options, got %o', config) + + _ + .chain(allowed({ ...cliConfig, ...options })) + .omit('env') + .omit('browsers') + .each((val: any, key) => { + // If users pass in testing-type specific keys (eg, specPattern), + // we want to merge this with what we've read from the config file, + // rather than override it entirely. + if (typeof config[key] === 'object' && typeof val === 'object') { + if (Object.keys(val).length) { + resolved[key] = 'cli' + config[key] = { ...config[key], ...val } + } + } else { + resolved[key] = 'cli' + config[key] = val + } + }).value() + + let url = config.baseUrl + + if (url) { + // replace multiple slashes at the end of string to single slash + // so http://localhost/// will be http://localhost/ + // https://regexr.com/48rvt + config.baseUrl = url.replace(/\/\/+$/, '/') + } + + const defaultsForRuntime = getDefaultValues(options) + + _.defaultsDeep(config, defaultsForRuntime) + + let additionalIgnorePattern = config.additionalIgnorePattern + + if (testingType === 'component' && config.e2e && config.e2e.specPattern) { + additionalIgnorePattern = config.e2e.specPattern + } + + config = { + ...config, + ...config[testingType], + additionalIgnorePattern, + } + + // split out our own app wide env from user env variables + // and delete envFile + config.env = parseEnv(config, { ...cliConfig.env, ...options.env }, resolved) + + config.cypressEnv = process.env.CYPRESS_INTERNAL_ENV + debug('using CYPRESS_INTERNAL_ENV %s', config.cypressEnv) + if (!isValidCypressInternalEnvValue(config.cypressEnv)) { + throw errors.throwErr('INVALID_CYPRESS_INTERNAL_ENV', config.cypressEnv) + } + + delete config.envFile + + // when headless + if (config.isTextTerminal && !process.env.CYPRESS_INTERNAL_FORCE_FILEWATCH) { + // dont ever watch for file changes + config.watchForFileChanges = false + + // and forcibly reset numTestsKeptInMemory + // to zero + config.numTestsKeptInMemory = 0 + } + + config = setResolvedConfigValues(config, defaultsForRuntime, resolved) + + if (config.port) { + config = setUrls(config) + } + + // validate config again here so that we catch configuration errors coming + // from the CLI overrides or env var overrides + validate(_.omit(config, 'browsers'), (validationResult: ConfigValidationFailureInfo | string) => { + // return errors.throwErr('CONFIG_VALIDATION_ERROR', errMsg) + if (_.isString(validationResult)) { + return errors.throwErr('CONFIG_VALIDATION_MSG_ERROR', null, null, validationResult) + } + + return errors.throwErr('CONFIG_VALIDATION_ERROR', null, null, validationResult) + }) + + config = setAbsolutePaths(config) + + config = setNodeBinary(config, options.userNodePath, options.userNodeVersion) + + debug('validate that there is no breaking config options before setupNodeEvents') + + function makeConfigError (cyError: CypressError) { + cyError.name = `Obsolete option used in config object` + + return cyError + } + + validateNoBreakingConfig(config[testingType], errors.warning, (err, options) => { + throw makeConfigError(errors.get(err, { ...options, name: `${testingType}.${options.name}` })) + }, testingType) + + validateNoBreakingConfig(config, errors.warning, (err, ...args) => { + throw makeConfigError(errors.get(err, ...args)) + }, testingType) + + // TODO: https://github.com/cypress-io/cypress/issues/23093 + // testIsolation should equal 'strict' by default when experimentalSessionAndOrigin=true + // Once experimentalSessionAndOrigin is made GA, remove this logic and update the defaultValue + // to be be 'strict' + if (testingType === 'e2e' && config.experimentalSessionAndOrigin) { + if (config.rawJson.testIsolation) { + config.resolved.testIsolation.from = 'config' + } else { + config.testIsolation = 'strict' + config.resolved.testIsolation.value = 'strict' + config.resolved.testIsolation.from === 'default' + } + } + + // We need to remove the nested propertied by testing type because it has been + // flattened/compacted based on the current testing type that is selected + // making the config only available with the properties that are valid, + // also, having the correct values that can be used in the setupNodeEvents + delete config['e2e'] + delete config['component'] + delete config['resolved']['e2e'] + delete config['resolved']['component'] + + return setSupportFileAndFolder(config, getFilesByGlob) +} + +function isValidCypressInternalEnvValue (value: string) { + // names of config environments, see "config/app.yml" + const names = ['development', 'test', 'staging', 'production'] + + return _.includes(names, value) +} + +function setResolvedConfigValues (config: Config, defaults: any, resolved: any) { + const obj = _.clone(config) + + obj.resolved = resolveConfigValues(config, defaults, resolved) + debug('resolved config is %o', obj.resolved.browsers) + + return obj +} + +// require.resolve walks the symlinks, which can really change +// the results. For example +// /tmp/foo is symlink to /private/tmp/foo on Mac +// thus resolving /tmp/foo to find /tmp/foo/index.js +// can return /private/tmp/foo/index.js +// which can really confuse the rest of the code. +// Detect this switch by checking if the resolution of absolute +// paths moved the prefix +// +// Good case: no switcheroo, return false +// /foo/bar -> /foo/bar/index.js +// Bad case: return true +// /tmp/foo/bar -> /private/tmp/foo/bar/index.js +export const checkIfResolveChangedRootFolder = (resolved: string, initial: string) => { + return path.isAbsolute(resolved) && + path.isAbsolute(initial) && + !resolved.startsWith(initial) +} diff --git a/packages/server/lib/util/coerce.ts b/packages/config/src/utils.ts similarity index 64% rename from packages/server/lib/util/coerce.ts rename to packages/config/src/utils.ts index 5eb86ef6db38..be69b9524e92 100644 --- a/packages/server/lib/util/coerce.ts +++ b/packages/config/src/utils.ts @@ -1,5 +1,42 @@ import _ from 'lodash' -import toBoolean from 'underscore.string/toBoolean' +import { toBoolean } from 'underscore.string' +import * as uri from '@packages/network/lib/uri' + +export const hideKeys = (token?: string | number | boolean) => { + if (!token) { + return + } + + if (typeof token !== 'string') { + // maybe somehow we passes key=true? + // https://github.com/cypress-io/cypress/issues/14571 + return + } + + return [ + token.slice(0, 5), + token.slice(-5), + ].join('...') +} + +export function setUrls (obj: any) { + obj = _.clone(obj) + + // TODO: rename this to be proxyServer + const proxyUrl = `http://localhost:${obj.port}` + + const rootUrl = obj.baseUrl + ? uri.origin(obj.baseUrl) + : proxyUrl + + return { + ...obj, + proxyUrl, + browserUrl: rootUrl + obj.clientRoute, + reporterUrl: rootUrl + obj.reporterRoute, + xhrUrl: `${obj.namespace}${obj.xhrRoute}`, + } +} // https://github.com/cypress-io/cypress/issues/6810 const toArray = (value: any) => { @@ -36,7 +73,7 @@ const fromJson = (value: string) => { } } -export const coerce = (value: string) => { +export const coerce = (value: any) => { const num = _.toNumber(value) if (_.invoke(num, 'toString') === value) { @@ -63,3 +100,7 @@ export const coerce = (value: string) => { return value } + +export const isResolvedConfigPropDefault = (config: Record, prop: string) => { + return config.resolved[prop].from === 'default' +} diff --git a/packages/config/test/project/index.spec.ts b/packages/config/test/project/index.spec.ts new file mode 100644 index 000000000000..82350d2a115b --- /dev/null +++ b/packages/config/test/project/index.spec.ts @@ -0,0 +1,194 @@ +import { expect } from 'chai' + +import errors from '@packages/errors' + +import { updateWithPluginValues } from '../../src/project' + +describe('config/src/project/index', () => { + context('.updateWithPluginValues', () => { + it('is noop when no overrides', () => { + expect(updateWithPluginValues({ foo: 'bar' } as any, null as any, 'e2e')).to.deep.eq({ + foo: 'bar', + }) + }) + + it('is noop with empty overrides', () => { + expect(updateWithPluginValues({ foo: 'bar' } as any, {} as any, 'e2e')).to.deep.eq({ + foo: 'bar', + }) + }) + + it('updates resolved config values and returns config with overrides', () => { + const cfg = { + foo: 'bar', + baz: 'quux', + quux: 'foo', + lol: 1234, + env: { + a: 'a', + b: 'b', + }, + // previously resolved values + resolved: { + foo: { value: 'bar', from: 'default' }, + baz: { value: 'quux', from: 'cli' }, + quux: { value: 'foo', from: 'default' }, + lol: { value: 1234, from: 'env' }, + env: { + a: { value: 'a', from: 'config' }, + b: { value: 'b', from: 'config' }, + }, + }, + } + + const overrides = { + baz: 'baz', + quux: ['bar', 'quux'], + env: { + b: 'bb', + c: 'c', + }, + } + + expect(updateWithPluginValues(cfg as any, overrides, 'e2e')).to.deep.eq({ + foo: 'bar', + baz: 'baz', + lol: 1234, + quux: ['bar', 'quux'], + env: { + a: 'a', + b: 'bb', + c: 'c', + }, + resolved: { + foo: { value: 'bar', from: 'default' }, + baz: { value: 'baz', from: 'plugin' }, + quux: { value: ['bar', 'quux'], from: 'plugin' }, + lol: { value: 1234, from: 'env' }, + env: { + a: { value: 'a', from: 'config' }, + b: { value: 'bb', from: 'plugin' }, + c: { value: 'c', from: 'plugin' }, + }, + }, + }) + }) + + it('keeps the list of browsers if the plugins returns empty object', () => { + const browser = { + name: 'fake browser name', + family: 'chromium', + displayName: 'My browser', + version: 'x.y.z', + path: '/path/to/browser', + majorVersion: 'x', + } + + const cfg = { + browsers: [browser], + resolved: { + browsers: { + value: [browser], + from: 'default', + }, + }, + } + + const overrides = {} + + expect(updateWithPluginValues(cfg as any, overrides, 'e2e')).to.deep.eq({ + browsers: [browser], + resolved: { + browsers: { + value: [browser], + from: 'default', + }, + }, + }) + }) + + it('catches browsers=null returned from plugins', () => { + const browser = { + name: 'fake browser name', + family: 'chromium', + displayName: 'My browser', + version: 'x.y.z', + path: '/path/to/browser', + majorVersion: 'x', + } + + const cfg = { + projectRoot: '/foo/bar', + browsers: [browser], + resolved: { + browsers: { + value: [browser], + from: 'default', + }, + }, + } + + const overrides = { + browsers: null, + } + + sinon.stub(errors, 'throwErr') + updateWithPluginValues(cfg as any, overrides, 'e2e') + + expect(errors.throwErr).to.have.been.calledWith('CONFIG_VALIDATION_MSG_ERROR') + }) + + it('allows user to filter browsers', () => { + const browserOne = { + name: 'fake browser name', + family: 'chromium', + displayName: 'My browser', + version: 'x.y.z', + path: '/path/to/browser', + majorVersion: 'x', + } + const browserTwo = { + name: 'fake electron', + family: 'chromium', + displayName: 'Electron', + version: 'x.y.z', + // Electron browser is built-in, no external path + path: '', + majorVersion: 'x', + } + + const cfg = { + browsers: [browserOne, browserTwo], + resolved: { + browsers: { + value: [browserOne, browserTwo], + from: 'default', + }, + }, + } + + const overrides = { + browsers: [browserTwo], + } + + const updated = updateWithPluginValues(cfg as any, overrides, 'e2e') + + expect(updated.resolved, 'resolved values').to.deep.eq({ + browsers: { + value: [browserTwo], + from: 'plugin', + }, + }) + + expect(updated, 'all values').to.deep.eq({ + browsers: [browserTwo], + resolved: { + browsers: { + value: [browserTwo], + from: 'plugin', + }, + }, + }) + }) + }) +}) diff --git a/packages/config/test/project/utils.spec.ts b/packages/config/test/project/utils.spec.ts new file mode 100644 index 000000000000..3b8fab921591 --- /dev/null +++ b/packages/config/test/project/utils.spec.ts @@ -0,0 +1,1267 @@ +import '@packages/server/test/spec_helper' + +import _ from 'lodash' +import { expect } from 'chai' +import sinon from 'sinon' +import stripAnsi from 'strip-ansi' +import Debug from 'debug' +import os from 'node:os' + +import errors from '@packages/errors' +import Fixtures from '@tooling/system-tests' + +import { + checkIfResolveChangedRootFolder, + parseEnv, + utils, + resolveConfigValues, + setPluginResolvedOn, + setAbsolutePaths, + setNodeBinary, + relativeToProjectRoot, + setSupportFileAndFolder, + mergeDefaults, +} from '../../src/project/utils' +import path from 'node:path' + +const debug = Debug('test') + +describe('config/src/project/utils', () => { + before(function () { + this.env = process.env; + + (process as any).env = _.omit(process.env, 'CYPRESS_DEBUG') + + Fixtures.scaffold() + }) + + after(function () { + process.env = this.env + }) + + afterEach(() => { + sinon.restore() + }) + + describe('checkIfResolveChangedRootFolder', () => { + it('ignores non-absolute paths', () => { + expect(checkIfResolveChangedRootFolder('foo/index.js', 'foo')).to.be.false + }) + + it('handles paths that do not switch', () => { + expect(checkIfResolveChangedRootFolder('/foo/index.js', '/foo')).to.be.false + }) + + it('detects path switch', () => { + expect(checkIfResolveChangedRootFolder('/private/foo/index.js', '/foo')).to.be.true + }) + }) + + context('.getProcessEnvVars', () => { + it('returns process envs prefixed with cypress', () => { + const envs = { + CYPRESS_BASE_URL: 'value', + RANDOM_ENV: 'ignored', + } as unknown as NodeJS.ProcessEnv + + expect(utils.getProcessEnvVars(envs)).to.deep.eq({ + BASE_URL: 'value', + }) + }) + + it('does not return CYPRESS_RESERVED_ENV_VARS', () => { + const envs = { + CYPRESS_INTERNAL_ENV: 'value', + } as unknown as NodeJS.ProcessEnv + + expect(utils.getProcessEnvVars(envs)).to.deep.eq({}) + }); + + ['cypress_', 'CYPRESS_'].forEach((key) => { + it(`reduces key: ${key}`, () => { + const obj = { + cypress_host: 'http://localhost:8888', + foo: 'bar', + env: '123', + } as unknown as NodeJS.ProcessEnv + + obj[`${key}version`] = '0.12.0' + + expect(utils.getProcessEnvVars(obj)).to.deep.eq({ + host: 'http://localhost:8888', + version: '0.12.0', + }) + }) + }) + + it('does not merge reserved environment variables', () => { + const obj = { + CYPRESS_INTERNAL_ENV: 'production', + CYPRESS_FOO: 'bar', + CYPRESS_CRASH_REPORTS: '0', + CYPRESS_PROJECT_ID: 'abc123', + } as NodeJS.ProcessEnv + + expect(utils.getProcessEnvVars(obj)).to.deep.eq({ + FOO: 'bar', + PROJECT_ID: 'abc123', + CRASH_REPORTS: 0, + }) + }) + }) + + context('environment name check', () => { + it('throws an error for unknown CYPRESS_INTERNAL_ENV', async () => { + sinon.stub(errors, 'throwErr').withArgs('INVALID_CYPRESS_INTERNAL_ENV', 'foo-bar'); + (process as any).env.CYPRESS_INTERNAL_ENV = 'foo-bar' + const cfg = { + projectRoot: '/foo/bar/', + supportFile: false, + } + const options = {} + + const getFilesByGlob = sinon.stub().returns(['path/to/file']) + + try { + await mergeDefaults(cfg, options, {}, getFilesByGlob) + } catch { + // + } + + expect(errors.throwErr).have.been.calledOnce + }) + + it('allows production CYPRESS_INTERNAL_ENV', async () => { + sinon.stub(errors, 'throwErr') + process.env.CYPRESS_INTERNAL_ENV = 'production' + const cfg = { + projectRoot: '/foo/bar/', + supportFile: false, + } + const options = {} + + const getFilesByGlob = sinon.stub().returns(['path/to/file']) + + await mergeDefaults(cfg, options, {}, getFilesByGlob) + + expect(errors.throwErr).not.to.be.called + }) + }) + + context('.parseEnv', () => { + it('merges together env from config, env from file, env from process, and env from CLI', () => { + sinon.stub(utils, 'getProcessEnvVars').returns({ + version: '0.12.1', + user: 'bob', + }) + + const obj = { + env: { + version: '0.10.9', + project: 'todos', + host: 'localhost', + baz: 'quux', + }, + + envFile: { + host: 'http://localhost:8888', + user: 'brian', + foo: 'bar', + }, + } + + const envCLI = { + version: '0.14.0', + project: 'pie', + } + + expect(parseEnv(obj, envCLI)).to.deep.eq({ + version: '0.14.0', + project: 'pie', + host: 'http://localhost:8888', + user: 'bob', + foo: 'bar', + baz: 'quux', + }) + }) + }) + + context('.resolveConfigValues', () => { + beforeEach(function () { + this.expected = function (obj) { + const merged = resolveConfigValues(obj.config, obj.defaults, obj.resolved) + + expect(merged).to.deep.eq(obj.final) + } + }) + + it('sets baseUrl to default', function () { + return this.expected({ + config: { baseUrl: null }, + defaults: { baseUrl: null }, + resolved: {}, + final: { + baseUrl: { + value: null, + from: 'default', + }, + }, + }) + }) + + it('sets baseUrl to config', function () { + return this.expected({ + config: { baseUrl: 'localhost' }, + defaults: { baseUrl: null }, + resolved: {}, + final: { + baseUrl: { + value: 'localhost', + from: 'config', + }, + }, + }) + }) + + it('does not change existing resolved values', function () { + return this.expected({ + config: { baseUrl: 'localhost' }, + defaults: { baseUrl: null }, + resolved: { baseUrl: 'cli' }, + final: { + baseUrl: { + value: 'localhost', + from: 'cli', + }, + }, + }) + }) + + it('ignores values not found in configKeys', function () { + return this.expected({ + config: { baseUrl: 'localhost', foo: 'bar' }, + defaults: { baseUrl: null }, + resolved: { baseUrl: 'cli' }, + final: { + baseUrl: { + value: 'localhost', + from: 'cli', + }, + }, + }) + }) + }) + + context('.setPluginResolvedOn', () => { + it('resolves an object with single property', () => { + const cfg = {} + const obj = { + foo: 'bar', + } + + setPluginResolvedOn(cfg, obj) + + expect(cfg).to.deep.eq({ + foo: { + value: 'bar', + from: 'plugin', + }, + }) + }) + + it('resolves an object with multiple properties', () => { + const cfg = {} + const obj = { + foo: 'bar', + baz: [1, 2, 3], + } + + setPluginResolvedOn(cfg, obj) + + expect(cfg).to.deep.eq({ + foo: { + value: 'bar', + from: 'plugin', + }, + baz: { + value: [1, 2, 3], + from: 'plugin', + }, + }) + }) + + it('resolves a nested object', () => { + // we need at least the structure + const cfg = { + foo: { + bar: 1, + }, + } + const obj = { + foo: { + bar: 42, + }, + } + + setPluginResolvedOn(cfg, obj) + + expect(cfg, 'foo.bar gets value').to.deep.eq({ + foo: { + bar: { + value: 42, + from: 'plugin', + }, + }, + }) + }) + + // https://github.com/cypress-io/cypress/issues/7959 + it('resolves a single object', () => { + const cfg = { + } + const obj = { + foo: { + bar: { + baz: 42, + }, + }, + } + + setPluginResolvedOn(cfg, obj) + + expect(cfg).to.deep.eq({ + foo: { + from: 'plugin', + value: { + bar: { + baz: 42, + }, + }, + }, + }) + }) + }) + + context('_.defaultsDeep', () => { + it('merges arrays', () => { + // sanity checks to confirm how Lodash merges arrays in defaultsDeep + const diffs = { + list: [1], + } + const cfg = { + list: [1, 2], + } + const merged = _.defaultsDeep({}, diffs, cfg) + + expect(merged, 'arrays are combined').to.deep.eq({ + list: [1, 2], + }) + }) + }) + + context('.setAbsolutePaths', () => { + it('is noop without projectRoot', () => { + expect(setAbsolutePaths({})).to.deep.eq({}) + }) + + it('does not mutate existing obj', () => { + const obj = {} + + expect(setAbsolutePaths(obj)).not.to.eq(obj) + }) + + it('ignores non special *folder properties', () => { + const obj = { + projectRoot: '/_test-output/path/to/project', + blehFolder: 'some/rando/path', + foo: 'bar', + baz: 'quux', + } + + expect(setAbsolutePaths(obj)).to.deep.eq(obj) + }) + + return ['fileServerFolder', 'fixturesFolder'].forEach((folder) => { + it(`converts relative ${folder} to absolute path`, () => { + const obj = { + projectRoot: '/_test-output/path/to/project', + } + + obj[folder] = 'foo/bar' + + const expected = { + projectRoot: '/_test-output/path/to/project', + } + + expected[folder] = '/_test-output/path/to/project/foo/bar' + + expect(setAbsolutePaths(obj)).to.deep.eq(expected) + }) + }) + }) + + context('.setNodeBinary', () => { + beforeEach(function () { + this.nodeVersion = process.versions.node + }) + + it('sets bundled Node ver if nodeVersion != system', function () { + const obj = setNodeBinary({ + nodeVersion: 'bundled', + }) + + expect(obj).to.deep.eq({ + nodeVersion: 'bundled', + resolvedNodeVersion: this.nodeVersion, + }) + }) + + it('sets cli Node ver if nodeVersion = system', function () { + const obj = setNodeBinary({ + nodeVersion: 'system', + }, '/foo/bar/node', '1.2.3') + + expect(obj).to.deep.eq({ + nodeVersion: 'system', + resolvedNodeVersion: '1.2.3', + resolvedNodePath: '/foo/bar/node', + }) + }) + + it('sets bundled Node ver and if nodeVersion = system and userNodePath undefined', function () { + const obj = setNodeBinary({ + nodeVersion: 'system', + }, undefined, '1.2.3') + + expect(obj).to.deep.eq({ + nodeVersion: 'system', + resolvedNodeVersion: this.nodeVersion, + }) + }) + + it('sets bundled Node ver and if nodeVersion = system and userNodeVersion undefined', function () { + const obj = setNodeBinary({ + nodeVersion: 'system', + }, '/foo/bar/node') + + expect(obj).to.deep.eq({ + nodeVersion: 'system', + resolvedNodeVersion: this.nodeVersion, + }) + }) + }) + + describe('relativeToProjectRoot', () => { + context('posix', () => { + it('returns path of file relative to projectRoot', () => { + const projectRoot = '/root/projects' + const supportFile = '/root/projects/cypress/support/e2e.js' + + expect(relativeToProjectRoot(projectRoot, supportFile)).to.eq('cypress/support/e2e.js') + }) + }) + + context('windows', () => { + it('returns path of file relative to projectRoot', () => { + const projectRoot = `\\root\\projects` + const supportFile = `\\root\\projects\\cypress\\support\\e2e.js` + + expect(relativeToProjectRoot(projectRoot, supportFile)).to.eq(`cypress\\support\\e2e.js`) + }) + }) + }) + + context('.setSupportFileAndFolder', () => { + it('does nothing if supportFile is falsey', () => { + const obj = { + projectRoot: '/_test-output/path/to/project', + } + + const getFilesByGlob = sinon.stub().returns(['path/to/file.ts']) + + return setSupportFileAndFolder(obj, getFilesByGlob) + .then((result) => { + expect(result).to.eql(obj) + }) + }) + + it('sets the full path to the supportFile and supportFolder if it exists', () => { + const projectRoot = process.cwd() + + const obj = setAbsolutePaths({ + projectRoot, + supportFile: 'test/project/utils.spec.ts', + }) + + const getFilesByGlob = sinon.stub().returns([path.join(projectRoot, obj.supportFile)]) + + return setSupportFileAndFolder(obj, getFilesByGlob) + .then((result) => { + expect(result).to.eql({ + projectRoot, + supportFile: `${projectRoot}/test/project/utils.spec.ts`, + supportFolder: `${projectRoot}/test/project`, + }) + }) + }) + + it('sets the supportFile to default e2e.js if it does not exist, support folder does not exist, and supportFile is the default', () => { + const projectRoot = Fixtures.projectPath('no-scaffolding') + + const obj = setAbsolutePaths({ + projectRoot, + supportFile: 'cypress/support/e2e.js', + }) + + const getFilesByGlob = sinon.stub().returns([path.join(projectRoot, obj.supportFile)]) + + return setSupportFileAndFolder(obj, getFilesByGlob) + .then((result) => { + expect(result).to.eql({ + projectRoot, + supportFile: `${projectRoot}/cypress/support/e2e.js`, + supportFolder: `${projectRoot}/cypress/support`, + }) + }) + }) + + it('finds support file in project path that contains glob syntax', () => { + const projectRoot = Fixtures.projectPath('project-with-(glob)-[chars]') + + const obj = setAbsolutePaths({ + projectRoot, + supportFile: 'cypress/support/e2e.js', + }) + + const getFilesByGlob = sinon.stub().returns([path.join(projectRoot, obj.supportFile)]) + + return setSupportFileAndFolder(obj, getFilesByGlob) + .then((result) => { + expect(result).to.eql({ + projectRoot, + supportFile: `${projectRoot}/cypress/support/e2e.js`, + supportFolder: `${projectRoot}/cypress/support`, + }) + }) + }) + + it('sets the supportFile to false if it does not exist, support folder exists, and supportFile is the default', () => { + const projectRoot = Fixtures.projectPath('empty-folders') + + const obj = setAbsolutePaths({ + projectRoot, + supportFile: false, + }) + + const getFilesByGlob = sinon.stub().returns(['path/to/file.ts']) + + return setSupportFileAndFolder(obj, getFilesByGlob) + .then((result) => { + expect(result).to.eql({ + projectRoot, + supportFile: false, + }) + }) + }) + + it('throws error if supportFile is not default and does not exist', () => { + const projectRoot = process.cwd() + + const obj = setAbsolutePaths({ + projectRoot, + supportFile: 'does/not/exist', + resolved: { + supportFile: { + value: 'does/not/exist', + from: 'default', + }, + }, + }) + + const getFilesByGlob = sinon.stub().returns([]) + + return setSupportFileAndFolder(obj, getFilesByGlob) + .catch((err) => { + expect(stripAnsi(err.message)).to.include('Your project does not contain a default supportFile') + }) + }) + + it('sets the supportFile to index.ts if it exists (without ts require hook)', () => { + const projectRoot = Fixtures.projectPath('ts-proj') + const supportFolder = `${projectRoot}/cypress/support` + const supportFilename = `${supportFolder}/index.ts` + + const e: Error & { code?: string } = new Error('Cannot resolve TS file by default') + + e.code = 'MODULE_NOT_FOUND' + sinon.stub(utils, 'resolveModule').withArgs(supportFilename).throws(e) + + const obj = setAbsolutePaths({ + projectRoot, + supportFile: 'cypress/support/index.ts', + }) + + const getFilesByGlob = sinon.stub().returns([path.join(projectRoot, obj.supportFile)]) + + return setSupportFileAndFolder(obj, getFilesByGlob) + .then((result) => { + debug('result is', result) + + expect(result).to.eql({ + projectRoot, + supportFolder, + supportFile: supportFilename, + }) + }) + }) + + it('uses custom TS supportFile if it exists (without ts require hook)', () => { + const projectRoot = Fixtures.projectPath('ts-proj-custom-names') + const supportFolder = `${projectRoot}/cypress` + const supportFilename = `${supportFolder}/support.ts` + + const e: Error & { code?: string } = new Error('Cannot resolve TS file by default') + + e.code = 'MODULE_NOT_FOUND' + sinon.stub(utils, 'resolveModule').withArgs(supportFilename).throws(e) + + const obj = setAbsolutePaths({ + projectRoot, + supportFile: 'cypress/support.ts', + }) + + const getFilesByGlob = sinon.stub().returns([path.join(projectRoot, obj.supportFile)]) + + return setSupportFileAndFolder(obj, getFilesByGlob) + .then((result) => { + debug('result is', result) + + expect(result).to.eql({ + projectRoot, + supportFolder, + supportFile: supportFilename, + }) + }) + }) + }) + + context('.mergeDefaults', () => { + beforeEach(function () { + this.getFilesByGlob = sinon.stub().returns(['path/to/file']) + + this.defaults = (prop, value, cfg: any = {}, options = {}) => { + cfg.projectRoot = '/foo/bar/' + + return mergeDefaults({ ...cfg, supportFile: cfg.supportFile ?? false }, options, {}, this.getFilesByGlob) + .then((mergedConfig) => { + expect(mergedConfig[prop]).to.deep.eq(value) + }) + } + }) + + it('slowTestThreshold=10000 for e2e', function () { + return this.defaults('slowTestThreshold', 10000, {}, { testingType: 'e2e' }) + }) + + it('slowTestThreshold=250 for component', function () { + return this.defaults('slowTestThreshold', 250, {}, { testingType: 'component' }) + }) + + it('port=null', function () { + return this.defaults('port', null) + }) + + it('projectId=null', function () { + return this.defaults('projectId', null) + }) + + it('autoOpen=false', function () { + return this.defaults('autoOpen', false) + }) + + it('browserUrl=http://localhost:2020/__/', function () { + return this.defaults('browserUrl', 'http://localhost:2020/__/', { port: 2020 }) + }) + + it('proxyUrl=http://localhost:2020', function () { + return this.defaults('proxyUrl', 'http://localhost:2020', { port: 2020 }) + }) + + it('namespace=__cypress', function () { + return this.defaults('namespace', '__cypress') + }) + + it('baseUrl=http://localhost:8000/app/', function () { + return this.defaults('baseUrl', 'http://localhost:8000/app/', { + baseUrl: 'http://localhost:8000/app///', + }) + }) + + it('baseUrl=http://localhost:8000/app/', function () { + return this.defaults('baseUrl', 'http://localhost:8000/app/', { + baseUrl: 'http://localhost:8000/app//', + }) + }) + + it('baseUrl=http://localhost:8000/app', function () { + return this.defaults('baseUrl', 'http://localhost:8000/app', { + baseUrl: 'http://localhost:8000/app', + }) + }) + + it('baseUrl=http://localhost:8000/', function () { + return this.defaults('baseUrl', 'http://localhost:8000/', { + baseUrl: 'http://localhost:8000//', + }) + }) + + it('baseUrl=http://localhost:8000/', function () { + return this.defaults('baseUrl', 'http://localhost:8000/', { + baseUrl: 'http://localhost:8000/', + }) + }) + + it('baseUrl=http://localhost:8000', function () { + return this.defaults('baseUrl', 'http://localhost:8000', { + baseUrl: 'http://localhost:8000', + }) + }) + + it('viewportWidth=1000', function () { + return this.defaults('viewportWidth', 1000) + }) + + it('viewportHeight=660', function () { + return this.defaults('viewportHeight', 660) + }) + + it('userAgent=null', function () { + return this.defaults('userAgent', null) + }) + + it('baseUrl=null', function () { + return this.defaults('baseUrl', null) + }) + + it('defaultCommandTimeout=4000', function () { + return this.defaults('defaultCommandTimeout', 4000) + }) + + it('pageLoadTimeout=60000', function () { + return this.defaults('pageLoadTimeout', 60000) + }) + + it('requestTimeout=5000', function () { + return this.defaults('requestTimeout', 5000) + }) + + it('responseTimeout=30000', function () { + return this.defaults('responseTimeout', 30000) + }) + + it('execTimeout=60000', function () { + return this.defaults('execTimeout', 60000) + }) + + it('waitForAnimations=true', function () { + return this.defaults('waitForAnimations', true) + }) + + it('scrollBehavior=start', function () { + return this.defaults('scrollBehavior', 'top') + }) + + it('animationDistanceThreshold=5', function () { + return this.defaults('animationDistanceThreshold', 5) + }) + + it('video=true', function () { + return this.defaults('video', true) + }) + + it('videoCompression=32', function () { + return this.defaults('videoCompression', 32) + }) + + it('videoUploadOnPasses=true', function () { + return this.defaults('videoUploadOnPasses', true) + }) + + it('trashAssetsBeforeRuns=32', function () { + return this.defaults('trashAssetsBeforeRuns', true) + }) + + it('morgan=true', function () { + return this.defaults('morgan', true) + }) + + it('isTextTerminal=false', function () { + return this.defaults('isTextTerminal', false) + }) + + it('socketId=null', function () { + return this.defaults('socketId', null) + }) + + it('reporter=spec', function () { + return this.defaults('reporter', 'spec') + }) + + it('watchForFileChanges=true', function () { + return this.defaults('watchForFileChanges', true) + }) + + it('numTestsKeptInMemory=50', function () { + return this.defaults('numTestsKeptInMemory', 50) + }) + + it('modifyObstructiveCode=true', function () { + return this.defaults('modifyObstructiveCode', true) + }) + + it('supportFile=false', function () { + return this.defaults('supportFile', false, { supportFile: false }) + }) + + it('blockHosts=null', function () { + return this.defaults('blockHosts', null) + }) + + it('blockHosts=[a,b]', function () { + return this.defaults('blockHosts', ['a', 'b'], { + blockHosts: ['a', 'b'], + }) + }) + + it('blockHosts=a|b', function () { + return this.defaults('blockHosts', ['a', 'b'], { + blockHosts: ['a', 'b'], + }) + }) + + it('hosts=null', function () { + return this.defaults('hosts', null) + }) + + it('hosts={}', function () { + return this.defaults('hosts', { + foo: 'bar', + baz: 'quux', + }, { + hosts: { + foo: 'bar', + baz: 'quux', + }, + }) + }) + + it('resets numTestsKeptInMemory to 0 when runMode', function () { + return mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { isTextTerminal: true }, {}, this.getFilesByGlob) + .then((cfg) => { + expect(cfg.numTestsKeptInMemory).to.eq(0) + }) + }) + + it('resets watchForFileChanges to false when runMode', function () { + return mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { isTextTerminal: true }, {}, this.getFilesByGlob) + .then((cfg) => { + expect(cfg.watchForFileChanges).to.be.false + }) + }) + + it('can override morgan in options', function () { + return mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { morgan: false }, {}, this.getFilesByGlob) + .then((cfg) => { + expect(cfg.morgan).to.be.false + }) + }) + + it('can override isTextTerminal in options', function () { + return mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { isTextTerminal: true }, {}, this.getFilesByGlob) + .then((cfg) => { + expect(cfg.isTextTerminal).to.be.true + }) + }) + + it('can override socketId in options', function () { + return mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { socketId: '1234' }, {}, this.getFilesByGlob) + .then((cfg) => { + expect(cfg.socketId).to.eq('1234') + }) + }) + + it('deletes envFile', function () { + const obj = { + projectRoot: '/foo/bar/', + supportFile: false, + env: { + foo: 'bar', + version: '0.5.2', + }, + envFile: { + bar: 'baz', + version: '1.0.1', + }, + } + + return mergeDefaults(obj, {}, {}, this.getFilesByGlob) + .then((cfg) => { + expect(cfg.env).to.deep.eq({ + foo: 'bar', + bar: 'baz', + version: '1.0.1', + }) + + expect(cfg.cypressEnv).to.eq(process.env['CYPRESS_INTERNAL_ENV']) + + expect(cfg).not.to.have.property('envFile') + }) + }) + + it('merges env into @env', function () { + const obj = { + projectRoot: '/foo/bar/', + supportFile: false, + env: { + host: 'localhost', + user: 'brian', + version: '0.12.2', + }, + } + + const options = { + env: { + version: '0.13.1', + foo: 'bar', + }, + } + + return mergeDefaults(obj, options, {}, this.getFilesByGlob) + .then((cfg) => { + expect(cfg.env).to.deep.eq({ + host: 'localhost', + user: 'brian', + version: '0.13.1', + foo: 'bar', + }) + }) + }) + + // @see https://github.com/cypress-io/cypress/issues/6892 + it('warns if experimentalGetCookiesSameSite is passed', async function () { + const warning = sinon.spy(errors, 'warning') + + await this.defaults('experimentalGetCookiesSameSite', true, { + experimentalGetCookiesSameSite: true, + }) + + expect(warning).to.be.calledWith('EXPERIMENTAL_SAMESITE_REMOVED') + }) + + it('warns if experimentalSessionSupport is passed', async function () { + const warning = sinon.spy(errors, 'warning') + + await this.defaults('experimentalSessionSupport', true, { + experimentalSessionSupport: true, + }) + + expect(warning).to.be.calledWith('EXPERIMENTAL_SESSION_SUPPORT_REMOVED') + }) + + it('warns if experimentalShadowDomSupport is passed', async function () { + const warning = sinon.spy(errors, 'warning') + + await this.defaults('experimentalShadowDomSupport', true, { + experimentalShadowDomSupport: true, + }) + + expect(warning).to.be.calledWith('EXPERIMENTAL_SHADOW_DOM_REMOVED') + }) + + it('warns if experimentalRunEvents is passed', async function () { + const warning = sinon.spy(errors, 'warning') + + await this.defaults('experimentalRunEvents', true, { + experimentalRunEvents: true, + }) + + expect(warning).to.be.calledWith('EXPERIMENTAL_RUN_EVENTS_REMOVED') + }) + + it('warns if experimentalStudio is passed', async function () { + const warning = sinon.spy(errors, 'warning') + + await this.defaults('experimentalStudio', true, { + experimentalStudio: true, + }) + + expect(warning).to.be.calledWith('EXPERIMENTAL_STUDIO_REMOVED') + }) + + // @see https://github.com/cypress-io/cypress/pull/9185 + it('warns if experimentalNetworkStubbing is passed', async function () { + const warning = sinon.spy(errors, 'warning') + + await this.defaults('experimentalNetworkStubbing', true, { + experimentalNetworkStubbing: true, + }) + + expect(warning).to.be.calledWith('EXPERIMENTAL_NETWORK_STUBBING_REMOVED') + }) + + it('warns if firefoxGcInterval is passed', async function () { + const warning = sinon.spy(errors, 'warning') + + await this.defaults('firefoxGcInterval', true, { + firefoxGcInterval: true, + }) + + expect(warning).to.be.calledWith('FIREFOX_GC_INTERVAL_REMOVED') + }) + + describe('.resolved', () => { + it('sets reporter and port to cli', () => { + const obj = { + projectRoot: '/foo/bar', + supportFile: false, + } + + const options = { + reporter: 'json', + port: 1234, + } + + const getFilesByGlob = sinon.stub().returns(['path/to/file.ts']) + + return mergeDefaults(obj, options, {}, getFilesByGlob) + .then((cfg) => { + expect(cfg.resolved).to.deep.eq({ + animationDistanceThreshold: { value: 5, from: 'default' }, + arch: { value: os.arch(), from: 'default' }, + baseUrl: { value: null, from: 'default' }, + blockHosts: { value: null, from: 'default' }, + browsers: { value: [], from: 'default' }, + chromeWebSecurity: { value: true, from: 'default' }, + clientCertificates: { value: [], from: 'default' }, + defaultCommandTimeout: { value: 4000, from: 'default' }, + downloadsFolder: { value: 'cypress/downloads', from: 'default' }, + env: {}, + execTimeout: { value: 60000, from: 'default' }, + experimentalModifyObstructiveThirdPartyCode: { value: false, from: 'default' }, + experimentalFetchPolyfill: { value: false, from: 'default' }, + experimentalInteractiveRunEvents: { value: false, from: 'default' }, + experimentalSessionAndOrigin: { value: false, from: 'default' }, + experimentalSingleTabRunMode: { value: false, from: 'default' }, + experimentalSourceRewriting: { value: false, from: 'default' }, + fileServerFolder: { value: '', from: 'default' }, + fixturesFolder: { value: 'cypress/fixtures', from: 'default' }, + hosts: { value: null, from: 'default' }, + excludeSpecPattern: { value: '*.hot-update.js', from: 'default' }, + includeShadowDom: { value: false, from: 'default' }, + isInteractive: { value: true, from: 'default' }, + keystrokeDelay: { value: 0, from: 'default' }, + modifyObstructiveCode: { value: true, from: 'default' }, + nodeVersion: { value: undefined, from: 'default' }, + numTestsKeptInMemory: { value: 50, from: 'default' }, + pageLoadTimeout: { value: 60000, from: 'default' }, + platform: { value: os.platform(), from: 'default' }, + port: { value: 1234, from: 'cli' }, + projectId: { value: null, from: 'default' }, + redirectionLimit: { value: 20, from: 'default' }, + reporter: { value: 'json', from: 'cli' }, + resolvedNodePath: { value: null, from: 'default' }, + resolvedNodeVersion: { value: null, from: 'default' }, + reporterOptions: { value: null, from: 'default' }, + requestTimeout: { value: 5000, from: 'default' }, + responseTimeout: { value: 30000, from: 'default' }, + retries: { value: { runMode: 0, openMode: 0 }, from: 'default' }, + screenshotOnRunFailure: { value: true, from: 'default' }, + screenshotsFolder: { value: 'cypress/screenshots', from: 'default' }, + specPattern: { value: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}', from: 'default' }, + slowTestThreshold: { value: 10000, from: 'default' }, + supportFile: { value: false, from: 'config' }, + supportFolder: { value: false, from: 'default' }, + taskTimeout: { value: 60000, from: 'default' }, + testIsolation: { value: 'legacy', from: 'default' }, + trashAssetsBeforeRuns: { value: true, from: 'default' }, + userAgent: { value: null, from: 'default' }, + video: { value: true, from: 'default' }, + videoCompression: { value: 32, from: 'default' }, + videosFolder: { value: 'cypress/videos', from: 'default' }, + videoUploadOnPasses: { value: true, from: 'default' }, + viewportHeight: { value: 660, from: 'default' }, + viewportWidth: { value: 1000, from: 'default' }, + waitForAnimations: { value: true, from: 'default' }, + scrollBehavior: { value: 'top', from: 'default' }, + watchForFileChanges: { value: true, from: 'default' }, + }) + }) + }) + + it('sets config, envFile and env', () => { + sinon.stub(utils, 'getProcessEnvVars').returns({ + quux: 'quux', + RECORD_KEY: 'foobarbazquux', + PROJECT_ID: 'projectId123', + }) + + const obj = { + projectRoot: '/foo/bar', + supportFile: false, + baseUrl: 'http://localhost:8080', + port: 2020, + env: { + foo: 'foo', + }, + envFile: { + bar: 'bar', + }, + } + + const options = { + env: { + baz: 'baz', + }, + } + + const getFilesByGlob = sinon.stub().returns(['path/to/file.ts']) + + return mergeDefaults(obj, options, {}, getFilesByGlob) + .then((cfg) => { + expect(cfg.resolved).to.deep.eq({ + arch: { value: os.arch(), from: 'default' }, + animationDistanceThreshold: { value: 5, from: 'default' }, + baseUrl: { value: 'http://localhost:8080', from: 'config' }, + blockHosts: { value: null, from: 'default' }, + browsers: { value: [], from: 'default' }, + chromeWebSecurity: { value: true, from: 'default' }, + clientCertificates: { value: [], from: 'default' }, + defaultCommandTimeout: { value: 4000, from: 'default' }, + downloadsFolder: { value: 'cypress/downloads', from: 'default' }, + execTimeout: { value: 60000, from: 'default' }, + experimentalModifyObstructiveThirdPartyCode: { value: false, from: 'default' }, + experimentalFetchPolyfill: { value: false, from: 'default' }, + experimentalInteractiveRunEvents: { value: false, from: 'default' }, + experimentalSessionAndOrigin: { value: false, from: 'default' }, + experimentalSingleTabRunMode: { value: false, from: 'default' }, + experimentalSourceRewriting: { value: false, from: 'default' }, + env: { + foo: { + value: 'foo', + from: 'config', + }, + bar: { + value: 'bar', + from: 'envFile', + }, + baz: { + value: 'baz', + from: 'cli', + }, + quux: { + value: 'quux', + from: 'env', + }, + RECORD_KEY: { + value: 'fooba...zquux', + from: 'env', + }, + }, + fileServerFolder: { value: '', from: 'default' }, + fixturesFolder: { value: 'cypress/fixtures', from: 'default' }, + hosts: { value: null, from: 'default' }, + excludeSpecPattern: { value: '*.hot-update.js', from: 'default' }, + includeShadowDom: { value: false, from: 'default' }, + isInteractive: { value: true, from: 'default' }, + keystrokeDelay: { value: 0, from: 'default' }, + modifyObstructiveCode: { value: true, from: 'default' }, + nodeVersion: { value: undefined, from: 'default' }, + numTestsKeptInMemory: { value: 50, from: 'default' }, + pageLoadTimeout: { value: 60000, from: 'default' }, + platform: { value: os.platform(), from: 'default' }, + port: { value: 2020, from: 'config' }, + projectId: { value: 'projectId123', from: 'env' }, + redirectionLimit: { value: 20, from: 'default' }, + reporter: { value: 'spec', from: 'default' }, + resolvedNodePath: { value: null, from: 'default' }, + resolvedNodeVersion: { value: null, from: 'default' }, + reporterOptions: { value: null, from: 'default' }, + requestTimeout: { value: 5000, from: 'default' }, + responseTimeout: { value: 30000, from: 'default' }, + retries: { value: { runMode: 0, openMode: 0 }, from: 'default' }, + screenshotOnRunFailure: { value: true, from: 'default' }, + screenshotsFolder: { value: 'cypress/screenshots', from: 'default' }, + slowTestThreshold: { value: 10000, from: 'default' }, + specPattern: { value: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}', from: 'default' }, + supportFile: { value: false, from: 'config' }, + supportFolder: { value: false, from: 'default' }, + taskTimeout: { value: 60000, from: 'default' }, + testIsolation: { value: 'legacy', from: 'default' }, + trashAssetsBeforeRuns: { value: true, from: 'default' }, + userAgent: { value: null, from: 'default' }, + video: { value: true, from: 'default' }, + videoCompression: { value: 32, from: 'default' }, + videosFolder: { value: 'cypress/videos', from: 'default' }, + videoUploadOnPasses: { value: true, from: 'default' }, + viewportHeight: { value: 660, from: 'default' }, + viewportWidth: { value: 1000, from: 'default' }, + waitForAnimations: { value: true, from: 'default' }, + scrollBehavior: { value: 'top', from: 'default' }, + watchForFileChanges: { value: true, from: 'default' }, + }) + }) + }) + + it('sets testIsolation=strict by default when experimentalSessionAndOrigin=true and e2e testing', () => { + sinon.stub(utils, 'getProcessEnvVars').returns({}) + + const obj = { + projectRoot: '/foo/bar', + supportFile: false, + baseUrl: 'http://localhost:8080', + experimentalSessionAndOrigin: true, + } + + const options = { + testingType: 'e2e', + } + + const getFilesByGlob = sinon.stub().returns(['path/to/file.ts']) + + return mergeDefaults(obj, options, {}, getFilesByGlob) + .then((cfg) => { + expect(cfg.resolved).to.have.property('experimentalSessionAndOrigin') + expect(cfg.resolved.experimentalSessionAndOrigin).to.deep.eq({ value: true, from: 'config' }) + expect(cfg.resolved).to.have.property('testIsolation') + expect(cfg.resolved.testIsolation).to.deep.eq({ value: 'strict', from: 'default' }) + }) + }) + + it('honors user config for testIsolation when experimentalSessionAndOrigin=true and e2e testing', () => { + sinon.stub(utils, 'getProcessEnvVars').returns({}) + + const obj = { + projectRoot: '/foo/bar', + supportFile: false, + baseUrl: 'http://localhost:8080', + experimentalSessionAndOrigin: true, + testIsolation: 'legacy', + } + + const options = { + testingType: 'e2e', + } + + const getFilesByGlob = sinon.stub().returns(['path/to/file.ts']) + + return mergeDefaults(obj, options, {}, getFilesByGlob) + .then((cfg) => { + expect(cfg.resolved).to.have.property('experimentalSessionAndOrigin') + expect(cfg.resolved.experimentalSessionAndOrigin).to.deep.eq({ value: true, from: 'config' }) + expect(cfg.resolved).to.have.property('testIsolation') + expect(cfg.resolved.testIsolation).to.deep.eq({ value: 'legacy', from: 'config' }) + }) + }) + }) + }) +}) diff --git a/packages/config/test/utils.spec.ts b/packages/config/test/utils.spec.ts new file mode 100644 index 000000000000..3f19939654ab --- /dev/null +++ b/packages/config/test/utils.spec.ts @@ -0,0 +1,166 @@ +import { expect } from 'chai' +import { + hideKeys, + setUrls, + coerce, + isResolvedConfigPropDefault, +} from '../src/utils' +import { + utils as projectUtils, +} from '../src/project/utils' + +describe('config/src/utils', () => { + describe('hideKeys', () => { + it('removes middle part of the string', () => { + const hidden = hideKeys('12345-xxxx-abcde') + + expect(hidden).to.equal('12345...abcde') + }) + + it('returns undefined for missing key', () => { + expect(hideKeys()).to.be.undefined + }) + + // https://github.com/cypress-io/cypress/issues/14571 + it('returns undefined for non-string argument', () => { + expect(hideKeys(true)).to.be.undefined + expect(hideKeys(1234)).to.be.undefined + }) + }) + + context('.setUrls', () => { + it('does not mutate existing obj', () => { + const obj = {} + + expect(setUrls(obj)).not.to.eq(obj) + }) + + it('uses baseUrl when set', () => { + const obj = { + port: 65432, + baseUrl: 'https://www.google.com', + clientRoute: '/__/', + } + + const urls = setUrls(obj) + + expect(urls.browserUrl).to.eq('https://www.google.com/__/') + expect(urls.proxyUrl).to.eq('http://localhost:65432') + }) + + it('strips baseUrl to host when set', () => { + const obj = { + port: 65432, + baseUrl: 'http://localhost:9999/app/?foo=bar#index.html', + clientRoute: '/__/', + } + + const urls = setUrls(obj) + + expect(urls.browserUrl).to.eq('http://localhost:9999/__/') + expect(urls.proxyUrl).to.eq('http://localhost:65432') + }) + }) + + context('coerce', () => { + beforeEach(function () { + this.env = process.env + }) + + afterEach(function () { + process.env = this.env + }) + + it('coerces string', () => { + expect(coerce('foo')).to.eq('foo') + }) + + it('coerces string from process.env', () => { + process.env['CYPRESS_STRING'] = 'bar' + const cypressEnvVar = projectUtils.getProcessEnvVars(process.env) + + expect(coerce(cypressEnvVar)).to.deep.include({ STRING: 'bar' }) + }) + + it('coerces number', () => { + expect(coerce('123')).to.eq(123) + }) + + // NOTE: When exporting shell variables, they are saved in `process.env` as strings, hence why + // all `process.env` variables are assigned as strings in these unit tests + it('coerces number from process.env', () => { + process.env['CYPRESS_NUMBER'] = '8000' + const cypressEnvVar = projectUtils.getProcessEnvVars(process.env) + + expect(coerce(cypressEnvVar)).to.deep.include({ NUMBER: 8000 }) + }) + + it('coerces boolean', () => { + expect(coerce('true')).to.be.true + }) + + it('coerces boolean from process.env', () => { + process.env['CYPRESS_BOOLEAN'] = 'false' + const cypressEnvVar = projectUtils.getProcessEnvVars(process.env) + + expect(coerce(cypressEnvVar)).to.deep.include({ BOOLEAN: false }) + }) + + // https://github.com/cypress-io/cypress/issues/8818 + it('coerces JSON string', () => { + expect(coerce('[{"type": "foo", "value": "bar"}, {"type": "fizz", "value": "buzz"}]')).to.deep.equal( + [{ 'type': 'foo', 'value': 'bar' }, { 'type': 'fizz', 'value': 'buzz' }], + ) + }) + + // https://github.com/cypress-io/cypress/issues/8818 + it('coerces JSON string from process.env', () => { + process.env['CYPRESS_stringified_json'] = '[{"type": "foo", "value": "bar"}, {"type": "fizz", "value": "buzz"}]' + const cypressEnvVar = projectUtils.getProcessEnvVars(process.env) + const coercedCypressEnvVar = coerce(cypressEnvVar) + + expect(coercedCypressEnvVar).to.have.keys('stringified_json') + expect(coercedCypressEnvVar['stringified_json']).to.deep.equal([{ 'type': 'foo', 'value': 'bar' }, { 'type': 'fizz', 'value': 'buzz' }]) + }) + + it('coerces array', () => { + expect(coerce('[foo,bar]')).to.have.members(['foo', 'bar']) + }) + + it('coerces array from process.env', () => { + process.env['CYPRESS_ARRAY'] = '[google.com,yahoo.com]' + const cypressEnvVar = projectUtils.getProcessEnvVars(process.env) + + const coercedCypressEnvVar = coerce(cypressEnvVar) + + expect(coercedCypressEnvVar).to.have.keys('ARRAY') + expect(coercedCypressEnvVar['ARRAY']).to.have.members(['google.com', 'yahoo.com']) + }) + + it('defaults value with multiple types to string', () => { + expect(coerce('123foo456')).to.eq('123foo456') + }) + }) + + context('.isResolvedConfigPropDefault', () => { + it('returns true if value is default value', () => { + const options = { + resolved: { + baseUrl: { from: 'default' }, + }, + } + + expect(isResolvedConfigPropDefault(options, 'baseUrl')).to.be.true + }) + + it('returns false if value is not default value', () => { + const options = { + resolved: { + baseUrl: { from: 'cli' }, + }, + } + + expect(isResolvedConfigPropDefault(options, 'baseUrl')).to.be.false + }) + }) +}) diff --git a/packages/data-context/src/DataContext.ts b/packages/data-context/src/DataContext.ts index 1cb4dd4be1f8..301768987922 100644 --- a/packages/data-context/src/DataContext.ts +++ b/packages/data-context/src/DataContext.ts @@ -36,7 +36,7 @@ import type { App as ElectronApp } from 'electron' import { VersionsDataSource } from './sources/VersionsDataSource' import type { SocketIONamespace, SocketIOServer } from '@packages/socket' import { globalPubSub } from '.' -import { InjectedConfigApi, ProjectLifecycleManager } from './data/ProjectLifecycleManager' +import { ProjectLifecycleManager } from './data/ProjectLifecycleManager' import type { CypressError } from '@packages/errors' import { ErrorDataSource } from './sources/ErrorDataSource' import { GraphQLDataSource } from './sources/GraphQLDataSource' @@ -67,7 +67,6 @@ export interface DataContextConfig { appApi: AppApiShape localSettingsApi: LocalSettingsApiShape authApi: AuthApiShape - configApi: InjectedConfigApi projectApi: ProjectApiShape electronApi: ElectronApiShape browserApi: BrowserApiShape @@ -322,7 +321,6 @@ export class DataContext { appApi: this._config.appApi, authApi: this._config.authApi, browserApi: this._config.browserApi, - configApi: this._config.configApi, projectApi: this._config.projectApi, electronApi: this._config.electronApi, localSettingsApi: this._config.localSettingsApi, diff --git a/packages/data-context/src/data/ProjectConfigManager.ts b/packages/data-context/src/data/ProjectConfigManager.ts index 0e51e92fbb70..258ff7209fe9 100644 --- a/packages/data-context/src/data/ProjectConfigManager.ts +++ b/packages/data-context/src/data/ProjectConfigManager.ts @@ -6,7 +6,14 @@ import debugLib from 'debug' import path from 'path' import _ from 'lodash' import chokidar from 'chokidar' -import { validate as validateConfig, validateNoBreakingConfigLaunchpad, validateNoBreakingConfigRoot, validateNoBreakingTestingTypeConfig } from '@packages/config' +import { + validate as validateConfig, + validateNoBreakingConfigLaunchpad, + validateNoBreakingConfigRoot, + validateNoBreakingTestingTypeConfig, + setupFullConfigWithDefaults, + updateWithPluginValues, +} from '@packages/config' import { CypressEnv } from './CypressEnv' import { autoBindDebug } from '../util/autoBindDebug' import type { EventRegistrar } from './EventRegistrar' @@ -310,7 +317,7 @@ export class ProjectConfigManager { const cypressEnv = await this.loadCypressEnvFile() const fullConfig = await this.buildBaseFullConfig(loadConfigReply.initialConfig, cypressEnv, this.options.ctx.modeOptions) - const finalConfig = this._cachedFullConfig = this.options.ctx._apis.configApi.updateWithPluginValues(fullConfig, result.setupConfig ?? {}, this._testingType ?? 'e2e') + const finalConfig = this._cachedFullConfig = updateWithPluginValues(fullConfig, result.setupConfig ?? {}, this._testingType ?? 'e2e') // Check if the config file has a before:browser:launch task, and if it's the case // we should restart the browser if it is open @@ -474,7 +481,7 @@ export class ProjectConfigManager { configFileContents = { ...configFileContents, ...testingTypeOverrides, ...optionsOverrides } // TODO: Convert this to be synchronous, it's just FS checks - let fullConfig = await this.options.ctx._apis.configApi.setupFullConfigWithDefaults({ + let fullConfig = await setupFullConfigWithDefaults({ cliConfig: options.config ?? {}, projectName: path.basename(this.options.projectRoot), projectRoot: this.options.projectRoot, @@ -485,7 +492,8 @@ export class ProjectConfigManager { testingType: this._testingType, configFile: path.basename(this.configFilePath), }, - }) + configFile: this.options.ctx.lifecycleManager.configFile, + }, this.options.ctx.file.getFilesByGlob) if (withBrowsers) { const browsers = await this.options.ctx.browser.machineBrowsers() diff --git a/packages/data-context/test/unit/helper.ts b/packages/data-context/test/unit/helper.ts index aba9be71f5cd..3d3e94cfca46 100644 --- a/packages/data-context/test/unit/helper.ts +++ b/packages/data-context/test/unit/helper.ts @@ -9,7 +9,6 @@ import { graphqlSchema } from '@packages/graphql/src/schema' import { remoteSchemaWrapped as schemaCloud } from '@packages/graphql/src/stitching/remoteSchemaWrapped' import type { BrowserApiShape } from '../../src/sources/BrowserDataSource' import type { AppApiShape, AuthApiShape, ElectronApiShape, LocalSettingsApiShape, ProjectApiShape } from '../../src/actions' -import { InjectedConfigApi } from '../../src/data' import sinon from 'sinon' import { execute, parse } from 'graphql' import { getOperationName } from '@urql/core' @@ -50,7 +49,6 @@ export function createTestDataContext (mode: DataContextConfig['mode'] = 'run', logIn: sinon.stub().throws('not stubbed'), resetAuthState: sinon.stub(), } as unknown as AuthApiShape, - configApi: {} as InjectedConfigApi, projectApi: { closeActiveProject: sinon.stub(), insertProjectToCache: sinon.stub().resolves(), diff --git a/packages/driver/package.json b/packages/driver/package.json index e7d222c041e5..8099cb4ebc65 100644 --- a/packages/driver/package.json +++ b/packages/driver/package.json @@ -33,7 +33,6 @@ "@types/jquery.scrollto": "1.4.29", "@types/mocha": "^8.0.3", "@types/sinonjs__fake-timers": "8.1.1", - "@types/underscore.string": "0.0.38", "angular": "1.8.0", "basic-auth": "2.0.1", "blob-util": "2.0.2", diff --git a/packages/network/lib/uri.ts b/packages/network/lib/uri.ts index e7e8d83f7b18..9e598013c367 100644 --- a/packages/network/lib/uri.ts +++ b/packages/network/lib/uri.ts @@ -13,21 +13,23 @@ import url, { URL } from 'url' const DEFAULT_PROTOCOL_PORTS = { 'https:': '443', 'http:': '80', -} +} as const + +type Protocols = keyof typeof DEFAULT_PROTOCOL_PORTS -const DEFAULT_PORTS = _.values(DEFAULT_PROTOCOL_PORTS) +const DEFAULT_PORTS = _.values(DEFAULT_PROTOCOL_PORTS) as string[] -const portIsDefault = (port) => { +const portIsDefault = (port: string | null) => { return port && DEFAULT_PORTS.includes(port) } -const parseClone = (urlObject) => { +const parseClone = (urlObject: any) => { return url.parse(_.clone(urlObject)) } export const parse = url.parse -export function stripProtocolAndDefaultPorts (urlToCheck) { +export function stripProtocolAndDefaultPorts (urlToCheck: string) { // grab host which is 'hostname:port' only const { host, hostname, port } = url.parse(urlToCheck) @@ -41,7 +43,7 @@ export function stripProtocolAndDefaultPorts (urlToCheck) { return host } -export function removePort (urlObject) { +export function removePort (urlObject: any) { const parsed = parseClone(urlObject) // set host to undefined else url.format(...) will ignore the port property @@ -55,7 +57,7 @@ export function removePort (urlObject) { return parsed } -export function removeDefaultPort (urlToCheck) { +export function removeDefaultPort (urlToCheck: any) { let parsed = parseClone(urlToCheck) if (portIsDefault(parsed.port)) { @@ -65,7 +67,7 @@ export function removeDefaultPort (urlToCheck) { return parsed } -export function addDefaultPort (urlToCheck) { +export function addDefaultPort (urlToCheck: any) { const parsed = parseClone(urlToCheck) if (!parsed.port) { @@ -74,7 +76,7 @@ export function addDefaultPort (urlToCheck) { /* @ts-ignore */ delete parsed.host if (parsed.protocol) { - parsed.port = DEFAULT_PROTOCOL_PORTS[parsed.protocol] + parsed.port = DEFAULT_PROTOCOL_PORTS[parsed.protocol as Protocols] } else { /* @ts-ignore */ delete parsed.port @@ -84,7 +86,7 @@ export function addDefaultPort (urlToCheck) { return parsed } -export function getPath (urlToCheck) { +export function getPath (urlToCheck: string) { return url.parse(urlToCheck).path } @@ -103,3 +105,15 @@ export function isLocalhost (url: URL) { || localhostIPRegex.test(url.hostname) ) } + +export function origin (urlStr: string) { + const parsed = url.parse(urlStr) + + parsed.hash = null + parsed.search = null + parsed.query = null + parsed.path = null + parsed.pathname = null + + return url.format(parsed) +} diff --git a/packages/network/test/unit/uri_spec.ts b/packages/network/test/unit/uri_spec.ts index 3d8fe82c9568..3f648f60fc2e 100644 --- a/packages/network/test/unit/uri_spec.ts +++ b/packages/network/test/unit/uri_spec.ts @@ -37,4 +37,23 @@ describe('lib/uri', () => { expect(uri.isLocalhost(new URL('https:foobar.com'))).to.be.false }) }) + + context('.origin', () => { + it('strips everything but the remote origin', () => { + expect( + uri.origin('http://localhost:9999/foo/bar?baz=quux#/index.html'), + 'http://localhost:9999', + ) + + expect( + uri.origin('https://www.google.com/'), + 'https://www.google.com', + ) + + expect( + uri.origin('https://app.foobar.co.uk:1234/a=b'), + 'https://app.foobar.co.uk:1234', + ) + }) + }) }) diff --git a/packages/server/lib/config.ts b/packages/server/lib/config.ts index 238d51d5dcfd..0a31a6beb673 100644 --- a/packages/server/lib/config.ts +++ b/packages/server/lib/config.ts @@ -1,610 +1,12 @@ -import Bluebird from 'bluebird' -import Debug from 'debug' import _ from 'lodash' -import path from 'path' -import deepDiff from 'return-deep-diff' -import type { ResolvedFromConfig, ResolvedConfigurationOptionSource, TestingType } from '@packages/types' +import type { ResolvedFromConfig } from '@packages/types' import * as configUtils from '@packages/config' -import * as errors from './errors' -import { getProcessEnvVars, CYPRESS_SPECIAL_ENV_VARS } from './util/config' -import { fs } from './util/fs' -import keys from './util/keys' -import origin from './util/origin' -import pathHelpers from './util/path_helpers' -import type { ConfigValidationFailureInfo, CypressError } from '@packages/errors' +export const setupFullConfigWithDefaults = configUtils.setupFullConfigWithDefaults -import { getCtx } from './makeDataContext' +export const updateWithPluginValues = configUtils.updateWithPluginValues -const debug = Debug('cypress:server:config') - -const folders = _(configUtils.options).filter({ isFolder: true }).map('name').value() - -const convertRelativeToAbsolutePaths = (projectRoot, obj) => { - return _.reduce(folders, (memo, folder) => { - const val = obj[folder] - - if ((val != null) && (val !== false)) { - memo[folder] = path.resolve(projectRoot, val) - } - - return memo - } - , {}) -} - -const hideSpecialVals = function (val, key) { - if (_.includes(CYPRESS_SPECIAL_ENV_VARS, key)) { - return keys.hide(val) - } - - return val -} - -// an object with a few utility methods for easy stubbing from unit tests -export const utils = { - resolveModule (name) { - return require.resolve(name) - }, - - // returns: - // false - if the file should not be set - // string - found filename - // null - if there is an error finding the file - discoverModuleFile (options) { - debug('discover module file %o', options) - const { filename } = options - - // they have it explicitly set, so it should be there - return fs.pathExists(filename) - .then((found) => { - if (found) { - debug('file exists, assuming it will load') - - return filename - } - - debug('could not find %o', { filename }) - - return null - }) - }, -} - -export function isValidCypressInternalEnvValue (value) { - // names of config environments, see "config/app.yml" - const names = ['development', 'test', 'staging', 'production'] - - return _.includes(names, value) -} - -export function setupFullConfigWithDefaults (obj: Record = {}) { - debug('setting config object %o', obj) - let { projectRoot, projectName, config, envFile, options, cliConfig } = obj - - // just force config to be an object so we dont have to do as much - // work in our tests - if (config == null) { - config = {} - } - - debug('config is %o', config) - - // flatten the object's properties into the master config object - config.envFile = envFile - config.projectRoot = projectRoot - config.projectName = projectName - - return mergeDefaults(config, options, cliConfig) -} - -export function mergeDefaults ( - config: Record = {}, - options: Record = {}, - cliConfig: Record = {}, -) { - const resolved = {} - const { testingType } = options - - config.rawJson = _.cloneDeep(config) - - _.extend(config, _.pick(options, 'configFile', 'morgan', 'isTextTerminal', 'socketId', 'report', 'browsers')) - debug('merged config with options, got %o', config) - - _ - .chain(configUtils.allowed({ ...cliConfig, ...options })) - .omit('env') - .omit('browsers') - .each((val: any, key) => { - // If users pass in testing-type specific keys (eg, specPattern), - // we want to merge this with what we've read from the config file, - // rather than override it entirely. - if (typeof config[key] === 'object' && typeof val === 'object') { - if (Object.keys(val).length) { - resolved[key] = 'cli' - config[key] = { ...config[key], ...val } - } - } else { - resolved[key] = 'cli' - config[key] = val - } - }).value() - - let url = config.baseUrl - - if (url) { - // replace multiple slashes at the end of string to single slash - // so http://localhost/// will be http://localhost/ - // https://regexr.com/48rvt - config.baseUrl = url.replace(/\/\/+$/, '/') - } - - const defaultsForRuntime = configUtils.getDefaultValues(options) - - _.defaultsDeep(config, defaultsForRuntime) - - let additionalIgnorePattern = config.additionalIgnorePattern - - if (testingType === 'component' && config.e2e && config.e2e.specPattern) { - additionalIgnorePattern = config.e2e.specPattern - } - - config = { - ...config, - ...config[testingType], - additionalIgnorePattern, - } - - // split out our own app wide env from user env variables - // and delete envFile - config.env = parseEnv(config, { ...cliConfig.env, ...options.env }, resolved) - - config.cypressEnv = process.env.CYPRESS_INTERNAL_ENV - debug('using CYPRESS_INTERNAL_ENV %s', config.cypressEnv) - if (!isValidCypressInternalEnvValue(config.cypressEnv)) { - throw errors.throwErr('INVALID_CYPRESS_INTERNAL_ENV', config.cypressEnv) - } - - delete config.envFile - - // when headless - if (config.isTextTerminal && !process.env.CYPRESS_INTERNAL_FORCE_FILEWATCH) { - // dont ever watch for file changes - config.watchForFileChanges = false - - // and forcibly reset numTestsKeptInMemory - // to zero - config.numTestsKeptInMemory = 0 - } - - config = setResolvedConfigValues(config, defaultsForRuntime, resolved) - - if (config.port) { - config = setUrls(config) - } - - // validate config again here so that we catch configuration errors coming - // from the CLI overrides or env var overrides - configUtils.validate(_.omit(config, 'browsers'), (validationResult: ConfigValidationFailureInfo | string) => { - // return errors.throwErr('CONFIG_VALIDATION_ERROR', errMsg) - if (_.isString(validationResult)) { - return errors.throwErr('CONFIG_VALIDATION_MSG_ERROR', null, null, validationResult) - } - - return errors.throwErr('CONFIG_VALIDATION_ERROR', null, null, validationResult) - }) - - config = setAbsolutePaths(config) - - config = setNodeBinary(config, options.userNodePath, options.userNodeVersion) - - debug('validate that there is no breaking config options before setupNodeEvents') - - function makeConfigError (cyError: CypressError) { - cyError.name = `Obsolete option used in config object` - - return cyError - } - - configUtils.validateNoBreakingConfig(config[testingType], errors.warning, (err, options) => { - throw makeConfigError(errors.get(err, { ...options, name: `${testingType}.${options.name}` })) - }, testingType) - - configUtils.validateNoBreakingConfig(config, errors.warning, (err, ...args) => { - throw makeConfigError(errors.get(err, ...args)) - }, testingType) - - // TODO: https://github.com/cypress-io/cypress/issues/23093 - // testIsolation should equal 'strict' by default when experimentalSessionAndOrigin=true - // Once experimentalSessionAndOrigin is made GA, remove this logic and update the defaultValue - // to be be 'strict' - if (testingType === 'e2e' && config.experimentalSessionAndOrigin) { - if (config.rawJson.testIsolation) { - config.resolved.testIsolation.from = 'config' - } else { - config.testIsolation = 'strict' - config.resolved.testIsolation.value = 'strict' - config.resolved.testIsolation.from === 'default' - } - } - - // We need to remove the nested propertied by testing type because it has been - // flattened/compacted based on the current testing type that is selected - // making the config only available with the properties that are valid, - // also, having the correct values that can be used in the setupNodeEvents - delete config['e2e'] - delete config['component'] - delete config['resolved']['e2e'] - delete config['resolved']['component'] - - return setSupportFileAndFolder(config) -} - -export function setResolvedConfigValues (config, defaults, resolved) { - const obj = _.clone(config) - - obj.resolved = resolveConfigValues(config, defaults, resolved) - debug('resolved config is %o', obj.resolved.browsers) - - return obj -} - -// Given an object "resolvedObj" and a list of overrides in "obj" -// marks all properties from "obj" inside "resolvedObj" using -// {value: obj.val, from: "plugin"} -export function setPluginResolvedOn (resolvedObj: Record, obj: Record) { - return _.each(obj, (val, key) => { - if (_.isObject(val) && !_.isArray(val) && resolvedObj[key]) { - // recurse setting overrides - // inside of objected - return setPluginResolvedOn(resolvedObj[key], val) - } - - const valueFrom: ResolvedFromConfig = { - value: val, - from: 'plugin', - } - - resolvedObj[key] = valueFrom - }) -} - -export function updateWithPluginValues (cfg, overrides, testingType: TestingType) { - if (!overrides) { - overrides = {} - } - - debug('updateWithPluginValues %o', { cfg, overrides }) - - // make sure every option returned from the plugins file - // passes our validation functions - configUtils.validate(overrides, (validationResult: ConfigValidationFailureInfo | string) => { - let configFile = getCtx().lifecycleManager.configFile - - if (_.isString(validationResult)) { - return errors.throwErr('CONFIG_VALIDATION_MSG_ERROR', 'configFile', configFile, validationResult) - } - - return errors.throwErr('CONFIG_VALIDATION_ERROR', 'configFile', configFile, validationResult) - }) - - debug('validate that there is no breaking config options added by setupNodeEvents') - - function makeSetupError (cyError: CypressError) { - cyError.name = `Error running ${testingType}.setupNodeEvents()` - - return cyError - } - - configUtils.validateNoBreakingConfig(overrides, errors.warning, (err, options) => { - throw makeSetupError(errors.get(err, options)) - }, testingType) - - configUtils.validateNoBreakingConfig(overrides[testingType], errors.warning, (err, options) => { - throw makeSetupError(errors.get(err, { - ...options, - name: `${testingType}.${options.name}`, - })) - }, testingType) - - const originalResolvedBrowsers = _.cloneDeep(cfg?.resolved?.browsers) ?? { - value: cfg.browsers, - from: 'default', - } as ResolvedFromConfig - - const diffs = deepDiff(cfg, overrides, true) - - debug('config diffs %o', diffs) - - const userBrowserList = diffs && diffs.browsers && _.cloneDeep(diffs.browsers) - - if (userBrowserList) { - debug('user browser list %o', userBrowserList) - } - - // for each override go through - // and change the resolved values of cfg - // to point to the plugin - if (diffs) { - debug('resolved config before diffs %o', cfg.resolved) - setPluginResolvedOn(cfg.resolved, diffs) - debug('resolved config object %o', cfg.resolved) - } - - // merge cfg into overrides - const merged = _.defaultsDeep(diffs, cfg) - - debug('merged config object %o', merged) - - // the above _.defaultsDeep combines arrays, - // if diffs.browsers = [1] and cfg.browsers = [1, 2] - // then the merged result merged.browsers = [1, 2] - // which is NOT what we want - if (Array.isArray(userBrowserList) && userBrowserList.length) { - merged.browsers = userBrowserList - merged.resolved.browsers.value = userBrowserList - } - - if (overrides.browsers === null) { - // null breaks everything when merging lists - debug('replacing null browsers with original list %o', originalResolvedBrowsers) - merged.browsers = cfg.browsers - if (originalResolvedBrowsers) { - merged.resolved.browsers = originalResolvedBrowsers - } - } - - debug('merged plugins config %o', merged) - - return merged -} - -// combines the default configuration object with values specified in the -// configuration file like "cypress.{ts|js}". Values in configuration file -// overwrite the defaults. -export function resolveConfigValues (config, defaults, resolved = {}) { - // pick out only known configuration keys - return _ - .chain(config) - .pick(configUtils.getPublicConfigKeys()) - .mapValues((val, key) => { - let r - const source = (s: ResolvedConfigurationOptionSource): ResolvedFromConfig => { - return { - value: val, - from: s, - } - } - - r = resolved[key] - - if (r) { - if (_.isObject(r)) { - return r - } - - return source(r) - } - - if (!(!_.isEqual(config[key], defaults[key]) && key !== 'browsers')) { - // "browsers" list is special, since it is dynamic by default - // and can only be overwritten via plugins file - return source('default') - } - - return source('config') - }).value() -} - -// instead of the built-in Node process, specify a path to 3rd party Node -export const setNodeBinary = (obj, userNodePath, userNodeVersion) => { - // if execPath isn't found we weren't executed from the CLI and should used the bundled node version. - if (userNodePath && userNodeVersion && obj.nodeVersion !== 'bundled') { - obj.resolvedNodePath = userNodePath - obj.resolvedNodeVersion = userNodeVersion - - return obj - } - - obj.resolvedNodeVersion = process.versions.node - - return obj -} - -export function relativeToProjectRoot (projectRoot: string, file: string) { - if (!file.startsWith(projectRoot)) { - return file - } - - // captures leading slash(es), both forward slash and back slash - const leadingSlashRe = /^[\/|\\]*(?![\/|\\])/ - - return file.replace(projectRoot, '').replace(leadingSlashRe, '') -} - -// async function -export async function setSupportFileAndFolder (obj) { - if (!obj.supportFile) { - return Bluebird.resolve(obj) - } - - obj = _.clone(obj) - - const ctx = getCtx() - - const supportFilesByGlob = await ctx.file.getFilesByGlob(obj.projectRoot, obj.supportFile) - - if (supportFilesByGlob.length > 1) { - return errors.throwErr('MULTIPLE_SUPPORT_FILES_FOUND', obj.supportFile, supportFilesByGlob) - } - - if (supportFilesByGlob.length === 0) { - if (obj.resolved.supportFile.from === 'default') { - return errors.throwErr('DEFAULT_SUPPORT_FILE_NOT_FOUND', relativeToProjectRoot(obj.projectRoot, obj.supportFile)) - } - - return errors.throwErr('SUPPORT_FILE_NOT_FOUND', relativeToProjectRoot(obj.projectRoot, obj.supportFile)) - } - - // TODO move this logic to find support file into util/path_helpers - const sf = supportFilesByGlob[0] - - debug(`setting support file ${sf}`) - debug(`for project root ${obj.projectRoot}`) - - return Bluebird - .try(() => { - // resolve full path with extension - obj.supportFile = utils.resolveModule(sf) - - return debug('resolved support file %s', obj.supportFile) - }).then(() => { - if (!pathHelpers.checkIfResolveChangedRootFolder(obj.supportFile, sf)) { - return - } - - debug('require.resolve switched support folder from %s to %s', sf, obj.supportFile) - // this means the path was probably symlinked, like - // /tmp/foo -> /private/tmp/foo - // which can confuse the rest of the code - // switch it back to "normal" file - const supportFileName = path.basename(obj.supportFile) - const base = sf.endsWith(supportFileName) ? path.dirname(sf) : sf - - obj.supportFile = path.join(base, supportFileName) - - return fs.pathExists(obj.supportFile) - .then((found) => { - if (!found) { - errors.throwErr('SUPPORT_FILE_NOT_FOUND', relativeToProjectRoot(obj.projectRoot, obj.supportFile)) - } - - return debug('switching to found file %s', obj.supportFile) - }) - }).catch({ code: 'MODULE_NOT_FOUND' }, () => { - debug('support JS module %s does not load', sf) - - return utils.discoverModuleFile({ - filename: sf, - projectRoot: obj.projectRoot, - }) - .then((result) => { - if (result === null) { - return errors.throwErr('SUPPORT_FILE_NOT_FOUND', relativeToProjectRoot(obj.projectRoot, sf)) - } - - debug('setting support file to %o', { result }) - obj.supportFile = result - - return obj - }) - }) - .then(() => { - if (obj.supportFile) { - // set config.supportFolder to its directory - obj.supportFolder = path.dirname(obj.supportFile) - debug(`set support folder ${obj.supportFolder}`) - } - - return obj - }) -} - -export function setAbsolutePaths (obj) { - let pr - - obj = _.clone(obj) - - // if we have a projectRoot - pr = obj.projectRoot - - if (pr) { - // reset fileServerFolder to be absolute - // obj.fileServerFolder = path.resolve(pr, obj.fileServerFolder) - - // and do the same for all the rest - _.extend(obj, convertRelativeToAbsolutePaths(pr, obj)) - } - - return obj -} - -export function setUrls (obj) { - obj = _.clone(obj) - - // TODO: rename this to be proxyServer - const proxyUrl = `http://localhost:${obj.port}` - - const rootUrl = obj.baseUrl ? - origin(obj.baseUrl) - : - proxyUrl - - _.extend(obj, { - proxyUrl, - browserUrl: rootUrl + obj.clientRoute, - reporterUrl: rootUrl + obj.reporterRoute, - xhrUrl: obj.namespace + obj.xhrRoute, - }) - - return obj -} - -export function parseEnv (cfg: Record, cliEnvs: Record, resolved: Record = {}) { - const envVars = (resolved.env = {}) - - const resolveFrom = (from, obj = {}) => { - return _.each(obj, (val, key) => { - return envVars[key] = { - value: val, - from, - } - }) - } - - const configEnv = cfg.env != null ? cfg.env : {} - const envFile = cfg.envFile != null ? cfg.envFile : {} - let processEnvs = getProcessEnvVars(process.env) || {} - - cliEnvs = cliEnvs != null ? cliEnvs : {} - - const configFromEnv = _.reduce(processEnvs, (memo: string[], val, key) => { - const cfgKey = configUtils.matchesConfigKey(key) - - if (cfgKey) { - // only change the value if it hasn't been - // set by the CLI. override default + config - if (resolved[cfgKey] !== 'cli') { - cfg[cfgKey] = val - resolved[cfgKey] = { - value: val, - from: 'env', - } as ResolvedFromConfig - } - - memo.push(key) - } - - return memo - } - , []) - - processEnvs = _.chain(processEnvs) - .omit(configFromEnv) - .mapValues(hideSpecialVals) - .value() - - resolveFrom('config', configEnv) - resolveFrom('envFile', envFile) - resolveFrom('env', processEnvs) - resolveFrom('cli', cliEnvs) - - // configEnvs is from cypress.config.{js,ts,mjs,cjs} - // envFile is from cypress.env.json - // processEnvs is from process env vars - // cliEnvs is from CLI arguments - return _.extend(configEnv, envFile, processEnvs, cliEnvs) -} +export const setUrls = configUtils.setUrls export function getResolvedRuntimeConfig (config, runtimeConfig) { const resolvedRuntimeFields = _.mapValues(runtimeConfig, (v): ResolvedFromConfig => ({ value: v, from: 'runtime' })) diff --git a/packages/server/lib/makeDataContext.ts b/packages/server/lib/makeDataContext.ts index ad723c8e46b1..c054682dadfb 100644 --- a/packages/server/lib/makeDataContext.ts +++ b/packages/server/lib/makeDataContext.ts @@ -1,7 +1,5 @@ import { DataContext, getCtx, clearCtx, setCtx } from '@packages/data-context' import electron, { OpenDialogOptions, SaveDialogOptions, BrowserWindow } from 'electron' -import pkg from '@packages/root' -import * as configUtils from '@packages/config' import { isListening } from './util/ensure-url' import { isMainWindowFocused, focusMainWindow } from './gui/windows' @@ -19,7 +17,6 @@ import type { import browserUtils from './browsers/utils' import auth from './gui/auth' import user from './user' -import * as config from './config' import { openProject } from './open_project' import cache from './cache' import { graphqlSchema } from '@packages/graphql/src/schema' @@ -60,13 +57,6 @@ export function makeDataContext (options: MakeDataContextOptions): DataContext { return openProject.relaunchBrowser ? openProject.relaunchBrowser() : null }, }, - configApi: { - allowedConfig: configUtils.allowed, - cypressVersion: pkg.version, - validateConfig: configUtils.validate, - updateWithPluginValues: config.updateWithPluginValues, - setupFullConfigWithDefaults: config.setupFullConfigWithDefaults, - }, appApi: { appData, }, diff --git a/packages/server/lib/modes/record.js b/packages/server/lib/modes/record.js index 48a4681e431b..cffa11894511 100644 --- a/packages/server/lib/modes/record.js +++ b/packages/server/lib/modes/record.js @@ -9,6 +9,8 @@ const Promise = require('bluebird') const isForkPr = require('is-fork-pr') const commitInfo = require('@cypress/commit-info') +const { hideKeys } = require('@packages/config') + const api = require('../api') const exception = require('../exception') const errors = require('../errors') @@ -16,7 +18,6 @@ const capture = require('../capture') const upload = require('../upload') const Config = require('../config') const env = require('../util/env') -const keys = require('../util/keys') const terminal = require('../util/terminal') const ciProvider = require('../util/ci_provider') const testsUtils = require('../util/tests_utils') @@ -387,7 +388,7 @@ const createRun = Promise.method((options = {}) => { switch (err.statusCode) { case 401: - recordKey = keys.hide(recordKey) + recordKey = hideKeys(recordKey) if (!recordKey) { // make sure the key is defined, otherwise the error // printing logic substitutes the default value {} diff --git a/packages/server/lib/remote_states.ts b/packages/server/lib/remote_states.ts index 45ed0cfc4706..e79aa067ef6a 100644 --- a/packages/server/lib/remote_states.ts +++ b/packages/server/lib/remote_states.ts @@ -1,5 +1,4 @@ -import { cors } from '@packages/network' -import origin from './util/origin' +import { cors, uri } from '@packages/network' import Debug from 'debug' import _ from 'lodash' import type EventEmitter from 'events' @@ -99,7 +98,7 @@ export class RemoteStates { let state if (_.isString(urlOrState)) { - const remoteOrigin = origin(urlOrState) + const remoteOrigin = uri.origin(urlOrState) const remoteProps = cors.parseUrlIntoDomainTldPort(remoteOrigin) if ((urlOrState === '') || !fullyQualifiedRe.test(urlOrState)) { diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index bced0d7f906c..36179af622f7 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -7,7 +7,7 @@ const { fs } = require('./util/fs') const cwd = require('./cwd') const debug = require('debug')('cypress:server:scaffold') const errors = require('./errors') -const { isDefault } = require('./util/config') +const { isResolvedConfigPropDefault } = require('@packages/config') const getExampleSpecsFullPaths = cypressEx.getPathToExamples() const getExampleFolderFullPaths = cypressEx.getPathToExampleFolders() @@ -74,7 +74,7 @@ module.exports = { // skip if user has explicitly set e2eFolder // or if user has set up component testing - if (!isDefault(config, 'e2eFolder') || componentTestingEnabled(config)) { + if (!isResolvedConfigPropDefault(config, 'e2eFolder') || componentTestingEnabled(config)) { return Promise.resolve() } @@ -94,7 +94,7 @@ module.exports = { debug(`fixture folder ${folder}`) // skip if user has explicitly set fixturesFolder - if (!config.fixturesFolder || !isDefault(config, 'fixturesFolder')) { + if (!config.fixturesFolder || !isResolvedConfigPropDefault(config, 'fixturesFolder')) { return Promise.resolve() } @@ -108,7 +108,7 @@ module.exports = { plugins (folder, config) { debug(`plugins folder ${folder}`) // skip if user has explicitly set pluginsFile - if (!config.pluginsFile || !isDefault(config, 'pluginsFile')) { + if (!config.pluginsFile || !isResolvedConfigPropDefault(config, 'pluginsFile')) { return Promise.resolve() } diff --git a/packages/server/lib/util/args.js b/packages/server/lib/util/args.js index db05fe0b5a46..007ff4e7a458 100644 --- a/packages/server/lib/util/args.js +++ b/packages/server/lib/util/args.js @@ -4,9 +4,8 @@ const is = require('check-more-types') const path = require('path') const debug = require('debug')('cypress:server:args') const minimist = require('minimist') -const { getBreakingRootKeys, getPublicConfigKeys } = require('@packages/config') +const { getBreakingRootKeys, getPublicConfigKeys, coerce } = require('@packages/config') -const coerceUtil = require('./coerce') const proxyUtil = require('./proxy') const errors = require('../errors') @@ -157,7 +156,7 @@ const JSONOrCoerce = (str) => { } // nupe :-( - return coerceUtil.coerce(str) + return coerce(str) } const sanitizeAndConvertNestedArgs = (str, argName) => { @@ -389,7 +388,7 @@ module.exports = { // bypassed the cli cwd: process.cwd(), }) - .mapValues(coerceUtil.coerce) + .mapValues(coerce) .value() debug('argv parsed: %o', options) diff --git a/packages/server/lib/util/config.ts b/packages/server/lib/util/config.ts deleted file mode 100644 index 0bb4c8e7eec5..000000000000 --- a/packages/server/lib/util/config.ts +++ /dev/null @@ -1,45 +0,0 @@ -import _ from 'lodash' -import { coerce } from './coerce' - -export const CYPRESS_ENV_PREFIX = 'CYPRESS_' - -export const CYPRESS_ENV_PREFIX_LENGTH = 'CYPRESS_'.length - -export const CYPRESS_RESERVED_ENV_VARS = [ - 'CYPRESS_INTERNAL_ENV', -] - -export const CYPRESS_SPECIAL_ENV_VARS = [ - 'RECORD_KEY', -] - -export const isDefault = (config: Record, prop: string) => { - return config.resolved[prop].from === 'default' -} - -export const getProcessEnvVars = (obj: NodeJS.ProcessEnv) => { - return _.reduce(obj, (memo, value, key) => { - if (!value) { - return memo - } - - if (isCypressEnvLike(key)) { - memo[removeEnvPrefix(key)] = coerce(value) - } - - return memo - } - , {}) -} - -const isCypressEnvLike = (key) => { - return _.chain(key) - .invoke('toUpperCase') - .startsWith(CYPRESS_ENV_PREFIX) - .value() && - !_.includes(CYPRESS_RESERVED_ENV_VARS, key) -} - -const removeEnvPrefix = (key: string) => { - return key.slice(CYPRESS_ENV_PREFIX_LENGTH) -} diff --git a/packages/server/lib/util/keys.js b/packages/server/lib/util/keys.js deleted file mode 100644 index abdeb243b190..000000000000 --- a/packages/server/lib/util/keys.js +++ /dev/null @@ -1,20 +0,0 @@ -const hide = (token) => { - if (!token) { - return - } - - if (typeof token !== 'string') { - // maybe somehow we passes key=true? - // https://github.com/cypress-io/cypress/issues/14571 - return - } - - return [ - token.slice(0, 5), - token.slice(-5), - ].join('...') -} - -module.exports = { - hide, -} diff --git a/packages/server/lib/util/origin.js b/packages/server/lib/util/origin.js deleted file mode 100644 index 465aca61f760..000000000000 --- a/packages/server/lib/util/origin.js +++ /dev/null @@ -1,14 +0,0 @@ -// TODO: move this into lib/util/uri.js -const url = require('url') - -module.exports = function (urlStr) { - const parsed = url.parse(urlStr) - - parsed.hash = null - parsed.search = null - parsed.query = null - parsed.path = null - parsed.pathname = null - - return url.format(parsed) -} diff --git a/packages/server/lib/util/path_helpers.js b/packages/server/lib/util/path_helpers.js deleted file mode 100644 index aa516154c96f..000000000000 --- a/packages/server/lib/util/path_helpers.js +++ /dev/null @@ -1,38 +0,0 @@ -const path = require('path') -const { fs } = require('./fs') - -// require.resolve walks the symlinks, which can really change -// the results. For example -// /tmp/foo is symlink to /private/tmp/foo on Mac -// thus resolving /tmp/foo to find /tmp/foo/index.js -// can return /private/tmp/foo/index.js -// which can really confuse the rest of the code. -// Detect this switch by checking if the resolution of absolute -// paths moved the prefix -// -// Good case: no switcheroo, return false -// /foo/bar -> /foo/bar/index.js -// Bad case: return true -// /tmp/foo/bar -> /private/tmp/foo/bar/index.js -const checkIfResolveChangedRootFolder = (resolved, initial) => { - return path.isAbsolute(resolved) && - path.isAbsolute(initial) && - !resolved.startsWith(initial) -} - -// real folder path found could be different due to symlinks -// For example, folder /tmp/foo on Mac is really /private/tmp/foo -const getRealFolderPath = (folder) => { - // TODO check if folder is a non-empty string - if (!folder) { - throw new Error('Expected folder') - } - - return fs.realpathAsync(folder) -} - -module.exports = { - checkIfResolveChangedRootFolder, - - getRealFolderPath, -} diff --git a/packages/server/package.json b/packages/server/package.json index 6e0dbd0a8431..96e807e6ba97 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -102,7 +102,6 @@ "randomstring": "1.1.5", "recast": "0.20.4", "resolve": "1.17.0", - "return-deep-diff": "0.4.0", "sanitize-filename": "1.6.3", "semver": "7.3.2", "send": "0.17.1", diff --git a/packages/server/test/integration/http_requests_spec.js b/packages/server/test/integration/http_requests_spec.js index 2be0f59575a3..0eafcba81c01 100644 --- a/packages/server/test/integration/http_requests_spec.js +++ b/packages/server/test/integration/http_requests_spec.js @@ -107,7 +107,7 @@ describe('Routes', () => { // get all the config defaults // and allow us to override them // for each test - return config.setupFullConfigWithDefaults(obj) + return config.setupFullConfigWithDefaults(obj, getCtx().file.getFilesByGlob) .then((cfg) => { // use a jar for each test // but reset it automatically diff --git a/packages/server/test/integration/server_spec.js b/packages/server/test/integration/server_spec.js index 10b29cefbeca..9aeeb1fedab2 100644 --- a/packages/server/test/integration/server_spec.js +++ b/packages/server/test/integration/server_spec.js @@ -11,6 +11,7 @@ const { ServerE2E } = require(`../../lib/server-e2e`) const { SocketE2E } = require(`../../lib/socket-e2e`) const Fixtures = require('@tooling/system-tests') const { createRoutes } = require(`../../lib/routes`) +const { getCtx } = require('../../lib/makeDataContext') const s3StaticHtmlUrl = 'https://s3.amazonaws.com/internal-test-runner-assets.cypress.io/index.html' @@ -46,7 +47,7 @@ describe('Server', () => { // get all the config defaults // and allow us to override them // for each test - return config.setupFullConfigWithDefaults(obj) + return config.setupFullConfigWithDefaults(obj, getCtx().file.getFilesByGlob) .then((cfg) => { // use a jar for each test // but reset it automatically diff --git a/packages/server/test/performance/proxy_performance_spec.js b/packages/server/test/performance/proxy_performance_spec.js index e8e95d20b3f8..b9ad5f6a4bcc 100644 --- a/packages/server/test/performance/proxy_performance_spec.js +++ b/packages/server/test/performance/proxy_performance_spec.js @@ -1,6 +1,6 @@ require('../spec_helper') -const { makeDataContext, setCtx } = require('../../lib/makeDataContext') +const { makeDataContext, setCtx, getCtx } = require('../../lib/makeDataContext') setCtx(makeDataContext({})) @@ -334,6 +334,10 @@ describe('Proxy Performance', function () { }) before(function () { + setCtx(makeDataContext({})) + + const getFilesByGlob = getCtx().file.getFilesByGlob + return CA.create() .then((ca) => { return ca.generateServerCertificateKeys('localhost') @@ -351,7 +355,7 @@ describe('Proxy Performance', function () { config: { supportFile: false, }, - }).then((config) => { + }, getFilesByGlob).then((config) => { config.port = CY_PROXY_PORT // turn off morgan diff --git a/packages/server/test/unit/config_spec.js b/packages/server/test/unit/config_spec.js index 513afd0f03e7..4cdf35762f80 100644 --- a/packages/server/test/unit/config_spec.js +++ b/packages/server/test/unit/config_spec.js @@ -1,18 +1,11 @@ require('../spec_helper') const _ = require('lodash') -const debug = require('debug')('test') const stripAnsi = require('strip-ansi') const { stripIndent } = require('common-tags') const Fixtures = require('@tooling/system-tests') const { getCtx } = require('@packages/data-context') -const config = require(`../../lib/config`) -const errors = require(`../../lib/errors`) -const configUtil = require(`../../lib/util/config`) - -const os = require('node:os') - describe('lib/config', () => { before(function () { this.env = process.env @@ -26,40 +19,6 @@ describe('lib/config', () => { process.env = this.env }) - context('environment name check', () => { - it('throws an error for unknown CYPRESS_INTERNAL_ENV', async () => { - sinon.stub(errors, 'throwErr').withArgs('INVALID_CYPRESS_INTERNAL_ENV', 'foo-bar') - process.env.CYPRESS_INTERNAL_ENV = 'foo-bar' - const cfg = { - projectRoot: '/foo/bar/', - supportFile: false, - } - const options = {} - - try { - await config.mergeDefaults(cfg, options) - } catch { - // - } - - expect(errors.throwErr).have.been.calledOnce - }) - - it('allows production CYPRESS_INTERNAL_ENV', async () => { - sinon.stub(errors, 'throwErr') - process.env.CYPRESS_INTERNAL_ENV = 'production' - const cfg = { - projectRoot: '/foo/bar/', - supportFile: false, - } - const options = {} - - await config.mergeDefaults(cfg, options) - - expect(errors.throwErr).not.to.be.called - }) - }) - context('.get', () => { beforeEach(async function () { this.ctx = getCtx() @@ -1020,1352 +979,4 @@ describe('lib/config', () => { }) }) }) - - context('.resolveConfigValues', () => { - beforeEach(function () { - this.expected = function (obj) { - const merged = config.resolveConfigValues(obj.config, obj.defaults, obj.resolved) - - expect(merged).to.deep.eq(obj.final) - } - }) - - it('sets baseUrl to default', function () { - return this.expected({ - config: { baseUrl: null }, - defaults: { baseUrl: null }, - resolved: {}, - final: { - baseUrl: { - value: null, - from: 'default', - }, - }, - }) - }) - - it('sets baseUrl to config', function () { - return this.expected({ - config: { baseUrl: 'localhost' }, - defaults: { baseUrl: null }, - resolved: {}, - final: { - baseUrl: { - value: 'localhost', - from: 'config', - }, - }, - }) - }) - - it('does not change existing resolved values', function () { - return this.expected({ - config: { baseUrl: 'localhost' }, - defaults: { baseUrl: null }, - resolved: { baseUrl: 'cli' }, - final: { - baseUrl: { - value: 'localhost', - from: 'cli', - }, - }, - }) - }) - - it('ignores values not found in configKeys', function () { - return this.expected({ - config: { baseUrl: 'localhost', foo: 'bar' }, - defaults: { baseUrl: null }, - resolved: { baseUrl: 'cli' }, - final: { - baseUrl: { - value: 'localhost', - from: 'cli', - }, - }, - }) - }) - }) - - context('.mergeDefaults', () => { - beforeEach(function () { - this.defaults = (prop, value, cfg = {}, options = {}) => { - cfg.projectRoot = '/foo/bar/' - - return config.mergeDefaults({ ...cfg, supportFile: cfg.supportFile ?? false }, options) - .then((mergedConfig) => { - expect(mergedConfig[prop]).to.deep.eq(value) - }) - } - }) - - it('slowTestThreshold=10000 for e2e', function () { - return this.defaults('slowTestThreshold', 10000, {}, { testingType: 'e2e' }) - }) - - it('slowTestThreshold=250 for component', function () { - return this.defaults('slowTestThreshold', 250, {}, { testingType: 'component' }) - }) - - it('port=null', function () { - return this.defaults('port', null) - }) - - it('projectId=null', function () { - return this.defaults('projectId', null) - }) - - it('autoOpen=false', function () { - return this.defaults('autoOpen', false) - }) - - it('browserUrl=http://localhost:2020/__/', function () { - return this.defaults('browserUrl', 'http://localhost:2020/__/', { port: 2020 }) - }) - - it('proxyUrl=http://localhost:2020', function () { - return this.defaults('proxyUrl', 'http://localhost:2020', { port: 2020 }) - }) - - it('namespace=__cypress', function () { - return this.defaults('namespace', '__cypress') - }) - - it('baseUrl=http://localhost:8000/app/', function () { - return this.defaults('baseUrl', 'http://localhost:8000/app/', { - baseUrl: 'http://localhost:8000/app///', - }) - }) - - it('baseUrl=http://localhost:8000/app/', function () { - return this.defaults('baseUrl', 'http://localhost:8000/app/', { - baseUrl: 'http://localhost:8000/app//', - }) - }) - - it('baseUrl=http://localhost:8000/app', function () { - return this.defaults('baseUrl', 'http://localhost:8000/app', { - baseUrl: 'http://localhost:8000/app', - }) - }) - - it('baseUrl=http://localhost:8000/', function () { - return this.defaults('baseUrl', 'http://localhost:8000/', { - baseUrl: 'http://localhost:8000//', - }) - }) - - it('baseUrl=http://localhost:8000/', function () { - return this.defaults('baseUrl', 'http://localhost:8000/', { - baseUrl: 'http://localhost:8000/', - }) - }) - - it('baseUrl=http://localhost:8000', function () { - return this.defaults('baseUrl', 'http://localhost:8000', { - baseUrl: 'http://localhost:8000', - }) - }) - - it('viewportWidth=1000', function () { - return this.defaults('viewportWidth', 1000) - }) - - it('viewportHeight=660', function () { - return this.defaults('viewportHeight', 660) - }) - - it('userAgent=null', function () { - return this.defaults('userAgent', null) - }) - - it('baseUrl=null', function () { - return this.defaults('baseUrl', null) - }) - - it('defaultCommandTimeout=4000', function () { - return this.defaults('defaultCommandTimeout', 4000) - }) - - it('pageLoadTimeout=60000', function () { - return this.defaults('pageLoadTimeout', 60000) - }) - - it('requestTimeout=5000', function () { - return this.defaults('requestTimeout', 5000) - }) - - it('responseTimeout=30000', function () { - return this.defaults('responseTimeout', 30000) - }) - - it('execTimeout=60000', function () { - return this.defaults('execTimeout', 60000) - }) - - it('waitForAnimations=true', function () { - return this.defaults('waitForAnimations', true) - }) - - it('scrollBehavior=start', function () { - return this.defaults('scrollBehavior', 'top') - }) - - it('animationDistanceThreshold=5', function () { - return this.defaults('animationDistanceThreshold', 5) - }) - - it('video=true', function () { - return this.defaults('video', true) - }) - - it('videoCompression=32', function () { - return this.defaults('videoCompression', 32) - }) - - it('videoUploadOnPasses=true', function () { - return this.defaults('videoUploadOnPasses', true) - }) - - it('trashAssetsBeforeRuns=32', function () { - return this.defaults('trashAssetsBeforeRuns', true) - }) - - it('morgan=true', function () { - return this.defaults('morgan', true) - }) - - it('isTextTerminal=false', function () { - return this.defaults('isTextTerminal', false) - }) - - it('socketId=null', function () { - return this.defaults('socketId', null) - }) - - it('reporter=spec', function () { - return this.defaults('reporter', 'spec') - }) - - it('watchForFileChanges=true', function () { - return this.defaults('watchForFileChanges', true) - }) - - it('numTestsKeptInMemory=50', function () { - return this.defaults('numTestsKeptInMemory', 50) - }) - - it('modifyObstructiveCode=true', function () { - return this.defaults('modifyObstructiveCode', true) - }) - - it('supportFile=false', function () { - return this.defaults('supportFile', false, { supportFile: false }) - }) - - it('blockHosts=null', function () { - return this.defaults('blockHosts', null) - }) - - it('blockHosts=[a,b]', function () { - return this.defaults('blockHosts', ['a', 'b'], { - blockHosts: ['a', 'b'], - }) - }) - - it('blockHosts=a|b', function () { - return this.defaults('blockHosts', ['a', 'b'], { - blockHosts: ['a', 'b'], - }) - }) - - it('hosts=null', function () { - return this.defaults('hosts', null) - }) - - it('hosts={}', function () { - return this.defaults('hosts', { - foo: 'bar', - baz: 'quux', - }, { - hosts: { - foo: 'bar', - baz: 'quux', - }, - }) - }) - - it('resets numTestsKeptInMemory to 0 when runMode', () => { - return config.mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { isTextTerminal: true }) - .then((cfg) => { - expect(cfg.numTestsKeptInMemory).to.eq(0) - }) - }) - - it('resets watchForFileChanges to false when runMode', () => { - return config.mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { isTextTerminal: true }) - .then((cfg) => { - expect(cfg.watchForFileChanges).to.be.false - }) - }) - - it('can override morgan in options', () => { - return config.mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { morgan: false }) - .then((cfg) => { - expect(cfg.morgan).to.be.false - }) - }) - - it('can override isTextTerminal in options', () => { - return config.mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { isTextTerminal: true }) - .then((cfg) => { - expect(cfg.isTextTerminal).to.be.true - }) - }) - - it('can override socketId in options', () => { - return config.mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { socketId: '1234' }) - .then((cfg) => { - expect(cfg.socketId).to.eq('1234') - }) - }) - - it('deletes envFile', () => { - const obj = { - projectRoot: '/foo/bar/', - supportFile: false, - env: { - foo: 'bar', - version: '0.5.2', - }, - envFile: { - bar: 'baz', - version: '1.0.1', - }, - } - - return config.mergeDefaults(obj) - .then((cfg) => { - expect(cfg.env).to.deep.eq({ - foo: 'bar', - bar: 'baz', - version: '1.0.1', - }) - - expect(cfg.cypressEnv).to.eq(process.env['CYPRESS_INTERNAL_ENV']) - - expect(cfg).not.to.have.property('envFile') - }) - }) - - it('merges env into @config.env', () => { - const obj = { - projectRoot: '/foo/bar/', - supportFile: false, - env: { - host: 'localhost', - user: 'brian', - version: '0.12.2', - }, - } - - const options = { - env: { - version: '0.13.1', - foo: 'bar', - }, - } - - return config.mergeDefaults(obj, options) - .then((cfg) => { - expect(cfg.env).to.deep.eq({ - host: 'localhost', - user: 'brian', - version: '0.13.1', - foo: 'bar', - }) - }) - }) - - // @see https://github.com/cypress-io/cypress/issues/6892 - it('warns if experimentalGetCookiesSameSite is passed', async function () { - const warning = sinon.spy(errors, 'warning') - - await this.defaults('experimentalGetCookiesSameSite', true, { - experimentalGetCookiesSameSite: true, - }) - - expect(warning).to.be.calledWith('EXPERIMENTAL_SAMESITE_REMOVED') - }) - - it('warns if experimentalSessionSupport is passed', async function () { - const warning = sinon.spy(errors, 'warning') - - await this.defaults('experimentalSessionSupport', true, { - experimentalSessionSupport: true, - }) - - expect(warning).to.be.calledWith('EXPERIMENTAL_SESSION_SUPPORT_REMOVED') - }) - - it('warns if experimentalShadowDomSupport is passed', async function () { - const warning = sinon.spy(errors, 'warning') - - await this.defaults('experimentalShadowDomSupport', true, { - experimentalShadowDomSupport: true, - }) - - expect(warning).to.be.calledWith('EXPERIMENTAL_SHADOW_DOM_REMOVED') - }) - - it('warns if experimentalRunEvents is passed', async function () { - const warning = sinon.spy(errors, 'warning') - - await this.defaults('experimentalRunEvents', true, { - experimentalRunEvents: true, - }) - - expect(warning).to.be.calledWith('EXPERIMENTAL_RUN_EVENTS_REMOVED') - }) - - it('warns if experimentalStudio is passed', async function () { - const warning = sinon.spy(errors, 'warning') - - await this.defaults('experimentalStudio', true, { - experimentalStudio: true, - }) - - expect(warning).to.be.calledWith('EXPERIMENTAL_STUDIO_REMOVED') - }) - - // @see https://github.com/cypress-io/cypress/pull/9185 - it('warns if experimentalNetworkStubbing is passed', async function () { - const warning = sinon.spy(errors, 'warning') - - await this.defaults('experimentalNetworkStubbing', true, { - experimentalNetworkStubbing: true, - }) - - expect(warning).to.be.calledWith('EXPERIMENTAL_NETWORK_STUBBING_REMOVED') - }) - - it('warns if firefoxGcInterval is passed', async function () { - const warning = sinon.spy(errors, 'warning') - - await this.defaults('firefoxGcInterval', true, { - firefoxGcInterval: true, - }) - - expect(warning).to.be.calledWith('FIREFOX_GC_INTERVAL_REMOVED') - }) - - describe('.resolved', () => { - it('sets reporter and port to cli', () => { - const obj = { - projectRoot: '/foo/bar', - supportFile: false, - } - - const options = { - reporter: 'json', - port: 1234, - } - - return config.mergeDefaults(obj, options) - .then((cfg) => { - expect(cfg.resolved).to.deep.eq({ - animationDistanceThreshold: { value: 5, from: 'default' }, - arch: { value: os.arch(), from: 'default' }, - baseUrl: { value: null, from: 'default' }, - blockHosts: { value: null, from: 'default' }, - browsers: { value: [], from: 'default' }, - chromeWebSecurity: { value: true, from: 'default' }, - clientCertificates: { value: [], from: 'default' }, - defaultCommandTimeout: { value: 4000, from: 'default' }, - downloadsFolder: { value: 'cypress/downloads', from: 'default' }, - env: {}, - execTimeout: { value: 60000, from: 'default' }, - experimentalModifyObstructiveThirdPartyCode: { value: false, from: 'default' }, - experimentalFetchPolyfill: { value: false, from: 'default' }, - experimentalInteractiveRunEvents: { value: false, from: 'default' }, - experimentalSingleTabRunMode: { value: false, from: 'default' }, - experimentalSessionAndOrigin: { value: false, from: 'default' }, - experimentalSourceRewriting: { value: false, from: 'default' }, - fileServerFolder: { value: '', from: 'default' }, - fixturesFolder: { value: 'cypress/fixtures', from: 'default' }, - hosts: { value: null, from: 'default' }, - excludeSpecPattern: { value: '*.hot-update.js', from: 'default' }, - includeShadowDom: { value: false, from: 'default' }, - isInteractive: { value: true, from: 'default' }, - keystrokeDelay: { value: 0, from: 'default' }, - modifyObstructiveCode: { value: true, from: 'default' }, - nodeVersion: { value: undefined, from: 'default' }, - numTestsKeptInMemory: { value: 50, from: 'default' }, - pageLoadTimeout: { value: 60000, from: 'default' }, - platform: { value: os.platform(), from: 'default' }, - port: { value: 1234, from: 'cli' }, - projectId: { value: null, from: 'default' }, - redirectionLimit: { value: 20, from: 'default' }, - reporter: { value: 'json', from: 'cli' }, - resolvedNodePath: { value: null, from: 'default' }, - resolvedNodeVersion: { value: null, from: 'default' }, - reporterOptions: { value: null, from: 'default' }, - requestTimeout: { value: 5000, from: 'default' }, - responseTimeout: { value: 30000, from: 'default' }, - retries: { value: { runMode: 0, openMode: 0 }, from: 'default' }, - screenshotOnRunFailure: { value: true, from: 'default' }, - screenshotsFolder: { value: 'cypress/screenshots', from: 'default' }, - specPattern: { value: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}', from: 'default' }, - slowTestThreshold: { value: 10000, from: 'default' }, - supportFile: { value: false, from: 'config' }, - supportFolder: { value: false, from: 'default' }, - taskTimeout: { value: 60000, from: 'default' }, - testIsolation: { value: 'legacy', from: 'default' }, - trashAssetsBeforeRuns: { value: true, from: 'default' }, - userAgent: { value: null, from: 'default' }, - video: { value: true, from: 'default' }, - videoCompression: { value: 32, from: 'default' }, - videosFolder: { value: 'cypress/videos', from: 'default' }, - videoUploadOnPasses: { value: true, from: 'default' }, - viewportHeight: { value: 660, from: 'default' }, - viewportWidth: { value: 1000, from: 'default' }, - waitForAnimations: { value: true, from: 'default' }, - scrollBehavior: { value: 'top', from: 'default' }, - watchForFileChanges: { value: true, from: 'default' }, - }) - }) - }) - - it('sets config, envFile and env', () => { - sinon.stub(configUtil, 'getProcessEnvVars').returns({ - quux: 'quux', - RECORD_KEY: 'foobarbazquux', - PROJECT_ID: 'projectId123', - }) - - const obj = { - projectRoot: '/foo/bar', - supportFile: false, - baseUrl: 'http://localhost:8080', - port: 2020, - env: { - foo: 'foo', - }, - envFile: { - bar: 'bar', - }, - } - - const options = { - env: { - baz: 'baz', - }, - } - - return config.mergeDefaults(obj, options) - .then((cfg) => { - expect(cfg.resolved).to.deep.eq({ - arch: { value: os.arch(), from: 'default' }, - animationDistanceThreshold: { value: 5, from: 'default' }, - baseUrl: { value: 'http://localhost:8080', from: 'config' }, - blockHosts: { value: null, from: 'default' }, - browsers: { value: [], from: 'default' }, - chromeWebSecurity: { value: true, from: 'default' }, - clientCertificates: { value: [], from: 'default' }, - defaultCommandTimeout: { value: 4000, from: 'default' }, - downloadsFolder: { value: 'cypress/downloads', from: 'default' }, - execTimeout: { value: 60000, from: 'default' }, - experimentalModifyObstructiveThirdPartyCode: { value: false, from: 'default' }, - experimentalFetchPolyfill: { value: false, from: 'default' }, - experimentalInteractiveRunEvents: { value: false, from: 'default' }, - experimentalSingleTabRunMode: { value: false, from: 'default' }, - experimentalSessionAndOrigin: { value: false, from: 'default' }, - experimentalSourceRewriting: { value: false, from: 'default' }, - env: { - foo: { - value: 'foo', - from: 'config', - }, - bar: { - value: 'bar', - from: 'envFile', - }, - baz: { - value: 'baz', - from: 'cli', - }, - quux: { - value: 'quux', - from: 'env', - }, - RECORD_KEY: { - value: 'fooba...zquux', - from: 'env', - }, - }, - fileServerFolder: { value: '', from: 'default' }, - fixturesFolder: { value: 'cypress/fixtures', from: 'default' }, - hosts: { value: null, from: 'default' }, - excludeSpecPattern: { value: '*.hot-update.js', from: 'default' }, - includeShadowDom: { value: false, from: 'default' }, - isInteractive: { value: true, from: 'default' }, - keystrokeDelay: { value: 0, from: 'default' }, - modifyObstructiveCode: { value: true, from: 'default' }, - nodeVersion: { value: undefined, from: 'default' }, - numTestsKeptInMemory: { value: 50, from: 'default' }, - pageLoadTimeout: { value: 60000, from: 'default' }, - platform: { value: os.platform(), from: 'default' }, - port: { value: 2020, from: 'config' }, - projectId: { value: 'projectId123', from: 'env' }, - redirectionLimit: { value: 20, from: 'default' }, - reporter: { value: 'spec', from: 'default' }, - resolvedNodePath: { value: null, from: 'default' }, - resolvedNodeVersion: { value: null, from: 'default' }, - reporterOptions: { value: null, from: 'default' }, - requestTimeout: { value: 5000, from: 'default' }, - responseTimeout: { value: 30000, from: 'default' }, - retries: { value: { runMode: 0, openMode: 0 }, from: 'default' }, - screenshotOnRunFailure: { value: true, from: 'default' }, - screenshotsFolder: { value: 'cypress/screenshots', from: 'default' }, - slowTestThreshold: { value: 10000, from: 'default' }, - specPattern: { value: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}', from: 'default' }, - supportFile: { value: false, from: 'config' }, - supportFolder: { value: false, from: 'default' }, - taskTimeout: { value: 60000, from: 'default' }, - testIsolation: { value: 'legacy', from: 'default' }, - trashAssetsBeforeRuns: { value: true, from: 'default' }, - userAgent: { value: null, from: 'default' }, - video: { value: true, from: 'default' }, - videoCompression: { value: 32, from: 'default' }, - videosFolder: { value: 'cypress/videos', from: 'default' }, - videoUploadOnPasses: { value: true, from: 'default' }, - viewportHeight: { value: 660, from: 'default' }, - viewportWidth: { value: 1000, from: 'default' }, - waitForAnimations: { value: true, from: 'default' }, - scrollBehavior: { value: 'top', from: 'default' }, - watchForFileChanges: { value: true, from: 'default' }, - }) - }) - }) - - it('sets testIsolation=strict by default when experimentalSessionAndOrigin=true and e2e testing', () => { - sinon.stub(configUtil, 'getProcessEnvVars').returns({}) - - const obj = { - projectRoot: '/foo/bar', - supportFile: false, - baseUrl: 'http://localhost:8080', - experimentalSessionAndOrigin: true, - } - - const options = { - testingType: 'e2e', - } - - return config.mergeDefaults(obj, options) - .then((cfg) => { - expect(cfg.resolved).to.have.property('experimentalSessionAndOrigin') - expect(cfg.resolved.experimentalSessionAndOrigin).to.deep.eq({ value: true, from: 'config' }) - expect(cfg.resolved).to.have.property('testIsolation') - expect(cfg.resolved.testIsolation).to.deep.eq({ value: 'strict', from: 'default' }) - }) - }) - - it('honors user config for testIsolation when experimentalSessionAndOrigin=true and e2e testing', () => { - sinon.stub(configUtil, 'getProcessEnvVars').returns({}) - - const obj = { - projectRoot: '/foo/bar', - supportFile: false, - baseUrl: 'http://localhost:8080', - experimentalSessionAndOrigin: true, - testIsolation: 'legacy', - } - - const options = { - testingType: 'e2e', - } - - return config.mergeDefaults(obj, options) - .then((cfg) => { - expect(cfg.resolved).to.have.property('experimentalSessionAndOrigin') - expect(cfg.resolved.experimentalSessionAndOrigin).to.deep.eq({ value: true, from: 'config' }) - expect(cfg.resolved).to.have.property('testIsolation') - expect(cfg.resolved.testIsolation).to.deep.eq({ value: 'legacy', from: 'config' }) - }) - }) - }) - }) - - context('.setPluginResolvedOn', () => { - it('resolves an object with single property', () => { - const cfg = {} - const obj = { - foo: 'bar', - } - - config.setPluginResolvedOn(cfg, obj) - - expect(cfg).to.deep.eq({ - foo: { - value: 'bar', - from: 'plugin', - }, - }) - }) - - it('resolves an object with multiple properties', () => { - const cfg = {} - const obj = { - foo: 'bar', - baz: [1, 2, 3], - } - - config.setPluginResolvedOn(cfg, obj) - - expect(cfg).to.deep.eq({ - foo: { - value: 'bar', - from: 'plugin', - }, - baz: { - value: [1, 2, 3], - from: 'plugin', - }, - }) - }) - - it('resolves a nested object', () => { - // we need at least the structure - const cfg = { - foo: { - bar: 1, - }, - } - const obj = { - foo: { - bar: 42, - }, - } - - config.setPluginResolvedOn(cfg, obj) - - expect(cfg, 'foo.bar gets value').to.deep.eq({ - foo: { - bar: { - value: 42, - from: 'plugin', - }, - }, - }) - }) - - // https://github.com/cypress-io/cypress/issues/7959 - it('resolves a single object', () => { - const cfg = { - } - const obj = { - foo: { - bar: { - baz: 42, - }, - }, - } - - config.setPluginResolvedOn(cfg, obj) - - expect(cfg).to.deep.eq({ - foo: { - from: 'plugin', - value: { - bar: { - baz: 42, - }, - }, - }, - }) - }) - }) - - context('_.defaultsDeep', () => { - it('merges arrays', () => { - // sanity checks to confirm how Lodash merges arrays in defaultsDeep - const diffs = { - list: [1], - } - const cfg = { - list: [1, 2], - } - const merged = _.defaultsDeep({}, diffs, cfg) - - expect(merged, 'arrays are combined').to.deep.eq({ - list: [1, 2], - }) - }) - }) - - context('.updateWithPluginValues', () => { - it('is noop when no overrides', () => { - expect(config.updateWithPluginValues({ foo: 'bar' }, null)).to.deep.eq({ - foo: 'bar', - }) - }) - - it('is noop with empty overrides', () => { - expect(config.updateWithPluginValues({ foo: 'bar' }, {})).to.deep.eq({ - foo: 'bar', - }) - }) - - it('updates resolved config values and returns config with overrides', () => { - const cfg = { - foo: 'bar', - baz: 'quux', - quux: 'foo', - lol: 1234, - env: { - a: 'a', - b: 'b', - }, - // previously resolved values - resolved: { - foo: { value: 'bar', from: 'default' }, - baz: { value: 'quux', from: 'cli' }, - quux: { value: 'foo', from: 'default' }, - lol: { value: 1234, from: 'env' }, - env: { - a: { value: 'a', from: 'config' }, - b: { value: 'b', from: 'config' }, - }, - }, - } - - const overrides = { - baz: 'baz', - quux: ['bar', 'quux'], - env: { - b: 'bb', - c: 'c', - }, - } - - expect(config.updateWithPluginValues(cfg, overrides)).to.deep.eq({ - foo: 'bar', - baz: 'baz', - lol: 1234, - quux: ['bar', 'quux'], - env: { - a: 'a', - b: 'bb', - c: 'c', - }, - resolved: { - foo: { value: 'bar', from: 'default' }, - baz: { value: 'baz', from: 'plugin' }, - quux: { value: ['bar', 'quux'], from: 'plugin' }, - lol: { value: 1234, from: 'env' }, - env: { - a: { value: 'a', from: 'config' }, - b: { value: 'bb', from: 'plugin' }, - c: { value: 'c', from: 'plugin' }, - }, - }, - }) - }) - - it('keeps the list of browsers if the plugins returns empty object', () => { - const browser = { - name: 'fake browser name', - family: 'chromium', - displayName: 'My browser', - version: 'x.y.z', - path: '/path/to/browser', - majorVersion: 'x', - } - - const cfg = { - browsers: [browser], - resolved: { - browsers: { - value: [browser], - from: 'default', - }, - }, - } - - const overrides = {} - - expect(config.updateWithPluginValues(cfg, overrides)).to.deep.eq({ - browsers: [browser], - resolved: { - browsers: { - value: [browser], - from: 'default', - }, - }, - }) - }) - - it('catches browsers=null returned from plugins', () => { - const browser = { - name: 'fake browser name', - family: 'chromium', - displayName: 'My browser', - version: 'x.y.z', - path: '/path/to/browser', - majorVersion: 'x', - } - - const cfg = { - projectRoot: '/foo/bar', - browsers: [browser], - resolved: { - browsers: { - value: [browser], - from: 'default', - }, - }, - } - - const overrides = { - browsers: null, - } - - sinon.stub(errors, 'throwErr') - config.updateWithPluginValues(cfg, overrides) - - expect(errors.throwErr).to.have.been.calledWith('CONFIG_VALIDATION_MSG_ERROR') - }) - - it('allows user to filter browsers', () => { - const browserOne = { - name: 'fake browser name', - family: 'chromium', - displayName: 'My browser', - version: 'x.y.z', - path: '/path/to/browser', - majorVersion: 'x', - } - const browserTwo = { - name: 'fake electron', - family: 'chromium', - displayName: 'Electron', - version: 'x.y.z', - // Electron browser is built-in, no external path - path: '', - majorVersion: 'x', - } - - const cfg = { - browsers: [browserOne, browserTwo], - resolved: { - browsers: { - value: [browserOne, browserTwo], - from: 'default', - }, - }, - } - - const overrides = { - browsers: [browserTwo], - } - - const updated = config.updateWithPluginValues(cfg, overrides) - - expect(updated.resolved, 'resolved values').to.deep.eq({ - browsers: { - value: [browserTwo], - from: 'plugin', - }, - }) - - expect(updated, 'all values').to.deep.eq({ - browsers: [browserTwo], - resolved: { - browsers: { - value: [browserTwo], - from: 'plugin', - }, - }, - }) - }) - }) - - context('.parseEnv', () => { - it('merges together env from config, env from file, env from process, and env from CLI', () => { - sinon.stub(configUtil, 'getProcessEnvVars').returns({ - version: '0.12.1', - user: 'bob', - }) - - const obj = { - env: { - version: '0.10.9', - project: 'todos', - host: 'localhost', - baz: 'quux', - }, - - envFile: { - host: 'http://localhost:8888', - user: 'brian', - foo: 'bar', - }, - } - - const envCLI = { - version: '0.14.0', - project: 'pie', - } - - expect(config.parseEnv(obj, envCLI)).to.deep.eq({ - version: '0.14.0', - project: 'pie', - host: 'http://localhost:8888', - user: 'bob', - foo: 'bar', - baz: 'quux', - }) - }) - }) - - context('.getProcessEnvVars', () => { - ['cypress_', 'CYPRESS_'].forEach((key) => { - it(`reduces key: ${key}`, () => { - const obj = { - cypress_host: 'http://localhost:8888', - foo: 'bar', - env: '123', - } - - obj[`${key}version`] = '0.12.0' - - expect(configUtil.getProcessEnvVars(obj)).to.deep.eq({ - host: 'http://localhost:8888', - version: '0.12.0', - }) - }) - }) - - it('does not merge reserved environment variables', () => { - const obj = { - CYPRESS_INTERNAL_ENV: 'production', - CYPRESS_FOO: 'bar', - CYPRESS_CRASH_REPORTS: '0', - CYPRESS_PROJECT_ID: 'abc123', - } - - expect(configUtil.getProcessEnvVars(obj)).to.deep.eq({ - FOO: 'bar', - PROJECT_ID: 'abc123', - CRASH_REPORTS: 0, - }) - }) - }) - - context('.setUrls', () => { - it('does not mutate existing obj', () => { - const obj = {} - - expect(config.setUrls(obj)).not.to.eq(obj) - }) - - it('uses baseUrl when set', () => { - const obj = { - port: 65432, - baseUrl: 'https://www.google.com', - clientRoute: '/__/', - } - - const urls = config.setUrls(obj) - - expect(urls.browserUrl).to.eq('https://www.google.com/__/') - - expect(urls.proxyUrl).to.eq('http://localhost:65432') - }) - - it('strips baseUrl to host when set', () => { - const obj = { - port: 65432, - baseUrl: 'http://localhost:9999/app/?foo=bar#index.html', - clientRoute: '/__/', - } - - const urls = config.setUrls(obj) - - expect(urls.browserUrl).to.eq('http://localhost:9999/__/') - - expect(urls.proxyUrl).to.eq('http://localhost:65432') - }) - }) - - context('.setSupportFileAndFolder', () => { - it('does nothing if supportFile is falsey', () => { - const obj = { - projectRoot: '/_test-output/path/to/project', - } - - return config.setSupportFileAndFolder(obj) - .then((result) => { - expect(result).to.eql(obj) - }) - }) - - it('sets the full path to the supportFile and supportFolder if it exists', () => { - const projectRoot = process.cwd() - - const obj = config.setAbsolutePaths({ - projectRoot, - supportFile: 'test/unit/config_spec.js', - }) - - return config.setSupportFileAndFolder(obj) - .then((result) => { - expect(result).to.eql({ - projectRoot, - supportFile: `${projectRoot}/test/unit/config_spec.js`, - supportFolder: `${projectRoot}/test/unit`, - }) - }) - }) - - it('sets the supportFile to default e2e.js if it does not exist, support folder does not exist, and supportFile is the default', () => { - const projectRoot = Fixtures.projectPath('no-scaffolding') - - const obj = config.setAbsolutePaths({ - projectRoot, - supportFile: 'cypress/support/e2e.js', - }) - - return config.setSupportFileAndFolder(obj) - .then((result) => { - expect(result).to.eql({ - projectRoot, - supportFile: `${projectRoot}/cypress/support/e2e.js`, - supportFolder: `${projectRoot}/cypress/support`, - }) - }) - }) - - it('finds support file in project path that contains glob syntax', () => { - const projectRoot = Fixtures.projectPath('project-with-(glob)-[chars]') - - const obj = config.setAbsolutePaths({ - projectRoot, - supportFile: 'cypress/support/e2e.js', - }) - - return config.setSupportFileAndFolder(obj) - .then((result) => { - expect(result).to.eql({ - projectRoot, - supportFile: `${projectRoot}/cypress/support/e2e.js`, - supportFolder: `${projectRoot}/cypress/support`, - }) - }) - }) - - it('sets the supportFile to false if it does not exist, support folder exists, and supportFile is the default', () => { - const projectRoot = Fixtures.projectPath('empty-folders') - - const obj = config.setAbsolutePaths({ - projectRoot, - supportFile: false, - }) - - return config.setSupportFileAndFolder(obj) - .then((result) => { - expect(result).to.eql({ - projectRoot, - supportFile: false, - }) - }) - }) - - it('throws error if supportFile is not default and does not exist', () => { - const projectRoot = process.cwd() - - const obj = config.setAbsolutePaths({ - projectRoot, - supportFile: 'does/not/exist', - resolved: { - supportFile: { - value: 'does/not/exist', - from: 'default', - }, - }, - }) - - return config.setSupportFileAndFolder(obj) - .catch((err) => { - expect(stripAnsi(err.message)).to.include('Your project does not contain a default supportFile') - }) - }) - - it('sets the supportFile to index.ts if it exists (without ts require hook)', () => { - const projectRoot = Fixtures.projectPath('ts-proj') - const supportFolder = `${projectRoot}/cypress/support` - const supportFilename = `${supportFolder}/index.ts` - - const e = new Error('Cannot resolve TS file by default') - - e.code = 'MODULE_NOT_FOUND' - sinon.stub(config.utils, 'resolveModule').withArgs(supportFilename).throws(e) - - const obj = config.setAbsolutePaths({ - projectRoot, - supportFile: 'cypress/support/index.ts', - }) - - return config.setSupportFileAndFolder(obj) - .then((result) => { - debug('result is', result) - - expect(result).to.eql({ - projectRoot, - supportFolder, - supportFile: supportFilename, - }) - }) - }) - - it('uses custom TS supportFile if it exists (without ts require hook)', () => { - const projectRoot = Fixtures.projectPath('ts-proj-custom-names') - const supportFolder = `${projectRoot}/cypress` - const supportFilename = `${supportFolder}/support.ts` - - const e = new Error('Cannot resolve TS file by default') - - e.code = 'MODULE_NOT_FOUND' - sinon.stub(config.utils, 'resolveModule').withArgs(supportFilename).throws(e) - - const obj = config.setAbsolutePaths({ - projectRoot, - supportFile: 'cypress/support.ts', - }) - - return config.setSupportFileAndFolder(obj) - .then((result) => { - debug('result is', result) - - expect(result).to.eql({ - projectRoot, - supportFolder, - supportFile: supportFilename, - }) - }) - }) - }) - - context('.setAbsolutePaths', () => { - it('is noop without projectRoot', () => { - expect(config.setAbsolutePaths({})).to.deep.eq({}) - }) - - it('does not mutate existing obj', () => { - const obj = {} - - expect(config.setAbsolutePaths(obj)).not.to.eq(obj) - }) - - it('ignores non special *folder properties', () => { - const obj = { - projectRoot: '/_test-output/path/to/project', - blehFolder: 'some/rando/path', - foo: 'bar', - baz: 'quux', - } - - expect(config.setAbsolutePaths(obj)).to.deep.eq(obj) - }) - - return ['fileServerFolder', 'fixturesFolder'].forEach((folder) => { - it(`converts relative ${folder} to absolute path`, () => { - const obj = { - projectRoot: '/_test-output/path/to/project', - } - - obj[folder] = 'foo/bar' - - const expected = { - projectRoot: '/_test-output/path/to/project', - } - - expected[folder] = '/_test-output/path/to/project/foo/bar' - - expect(config.setAbsolutePaths(obj)).to.deep.eq(expected) - }) - }) - }) - - context('.setNodeBinary', () => { - beforeEach(function () { - this.nodeVersion = process.versions.node - }) - - it('sets bundled Node ver if nodeVersion != system', function () { - const obj = config.setNodeBinary({ - nodeVersion: 'bundled', - }) - - expect(obj).to.deep.eq({ - nodeVersion: 'bundled', - resolvedNodeVersion: this.nodeVersion, - }) - }) - - it('sets cli Node ver if nodeVersion = system', function () { - const obj = config.setNodeBinary({ - nodeVersion: 'system', - }, '/foo/bar/node', '1.2.3') - - expect(obj).to.deep.eq({ - nodeVersion: 'system', - resolvedNodeVersion: '1.2.3', - resolvedNodePath: '/foo/bar/node', - }) - }) - - it('sets bundled Node ver and if nodeVersion = system and userNodePath undefined', function () { - const obj = config.setNodeBinary({ - nodeVersion: 'system', - }, undefined, '1.2.3') - - expect(obj).to.deep.eq({ - nodeVersion: 'system', - resolvedNodeVersion: this.nodeVersion, - }) - }) - - it('sets bundled Node ver and if nodeVersion = system and userNodeVersion undefined', function () { - const obj = config.setNodeBinary({ - nodeVersion: 'system', - }, '/foo/bar/node') - - expect(obj).to.deep.eq({ - nodeVersion: 'system', - resolvedNodeVersion: this.nodeVersion, - }) - }) - }) - - describe('relativeToProjectRoot', () => { - context('posix', () => { - it('returns path of file relative to projectRoot', () => { - const projectRoot = '/root/projects' - const supportFile = '/root/projects/cypress/support/e2e.js' - - expect(config.relativeToProjectRoot(projectRoot, supportFile)).to.eq('cypress/support/e2e.js') - }) - }) - - context('windows', () => { - it('returns path of file relative to projectRoot', () => { - const projectRoot = `\\root\\projects` - const supportFile = `\\root\\projects\\cypress\\support\\e2e.js` - - expect(config.relativeToProjectRoot(projectRoot, supportFile)).to.eq(`cypress\\support\\e2e.js`) - }) - }) - }) }) diff --git a/packages/server/test/unit/project_spec.js b/packages/server/test/unit/project_spec.js index b6f750ad9b30..ae77d612909c 100644 --- a/packages/server/test/unit/project_spec.js +++ b/packages/server/test/unit/project_spec.js @@ -45,7 +45,7 @@ describe.skip('lib/project-base', () => { .then((obj = {}) => { ({ projectId: this.projectId } = obj) - return config.setupFullConfigWithDefaults({ projectName: 'project', projectRoot: '/foo/bar' }) + return config.setupFullConfigWithDefaults({ projectName: 'project', projectRoot: '/foo/bar' }, getCtx().file.getFilesByGlob) .then((config1) => { this.config = config1 this.project = new ProjectBase({ projectRoot: this.todosPath, testingType: 'e2e' }) diff --git a/packages/server/test/unit/server_spec.js b/packages/server/test/unit/server_spec.js index 5dc8fe48eeb9..4cffec331cb6 100644 --- a/packages/server/test/unit/server_spec.js +++ b/packages/server/test/unit/server_spec.js @@ -10,6 +10,7 @@ const { ServerE2E } = require(`../../lib/server-e2e`) const { SocketE2E } = require(`../../lib/socket-e2e`) const fileServer = require(`../../lib/file_server`) const ensureUrl = require(`../../lib/util/ensure-url`) +const { getCtx } = require('@packages/data-context') const morganFn = function () {} @@ -21,7 +22,7 @@ describe('lib/server', () => { beforeEach(function () { this.server = new ServerE2E() - return config.setupFullConfigWithDefaults({ projectRoot: '/foo/bar/', config: { supportFile: false } }) + return config.setupFullConfigWithDefaults({ projectRoot: '/foo/bar/', config: { supportFile: false } }, getCtx().file.getFilesByGlob) .then((cfg) => { this.config = cfg }) @@ -50,7 +51,7 @@ describe.skip('lib/server', () => { sinon.stub(fileServer, 'create').returns(this.fileServer) - return config.setupFullConfigWithDefaults({ projectRoot: '/foo/bar/' }) + return config.setupFullConfigWithDefaults({ projectRoot: '/foo/bar/' }, getCtx().file.getFilesByGlob) .then((cfg) => { this.config = cfg this.server = new ServerE2E() diff --git a/packages/server/test/unit/util/coerce_spec.js b/packages/server/test/unit/util/coerce_spec.js deleted file mode 100644 index 46115718358c..000000000000 --- a/packages/server/test/unit/util/coerce_spec.js +++ /dev/null @@ -1,86 +0,0 @@ -require('../../spec_helper') - -const { coerce } = require(`../../../lib/util/coerce`) -const { getProcessEnvVars } = require(`../../../lib/util/config`) - -describe('lib/util/coerce', () => { - beforeEach(function () { - this.env = process.env - }) - - afterEach(function () { - process.env = this.env - }) - - context('coerce', () => { - it('coerces string', () => { - expect(coerce('foo')).to.eq('foo') - }) - - it('coerces string from process.env', () => { - process.env['CYPRESS_STRING'] = 'bar' - const cypressEnvVar = getProcessEnvVars(process.env) - - expect(coerce(cypressEnvVar)).to.deep.include({ STRING: 'bar' }) - }) - - it('coerces number', () => { - expect(coerce('123')).to.eq(123) - }) - - // NOTE: When exporting shell variables, they are saved in `process.env` as strings, hence why - // all `process.env` variables are assigned as strings in these unit tests - it('coerces number from process.env', () => { - process.env['CYPRESS_NUMBER'] = '8000' - const cypressEnvVar = getProcessEnvVars(process.env) - - expect(coerce(cypressEnvVar)).to.deep.include({ NUMBER: 8000 }) - }) - - it('coerces boolean', () => { - expect(coerce('true')).to.be.true - }) - - it('coerces boolean from process.env', () => { - process.env['CYPRESS_BOOLEAN'] = 'false' - const cypressEnvVar = getProcessEnvVars(process.env) - - expect(coerce(cypressEnvVar)).to.deep.include({ BOOLEAN: false }) - }) - - // https://github.com/cypress-io/cypress/issues/8818 - it('coerces JSON string', () => { - expect(coerce('[{"type": "foo", "value": "bar"}, {"type": "fizz", "value": "buzz"}]')).to.deep.equal( - [{ 'type': 'foo', 'value': 'bar' }, { 'type': 'fizz', 'value': 'buzz' }], - ) - }) - - // https://github.com/cypress-io/cypress/issues/8818 - it('coerces JSON string from process.env', () => { - process.env['CYPRESS_stringified_json'] = '[{"type": "foo", "value": "bar"}, {"type": "fizz", "value": "buzz"}]' - const cypressEnvVar = getProcessEnvVars(process.env) - const coercedCypressEnvVar = coerce(cypressEnvVar) - - expect(coercedCypressEnvVar).to.have.keys('stringified_json') - expect(coercedCypressEnvVar['stringified_json']).to.deep.equal([{ 'type': 'foo', 'value': 'bar' }, { 'type': 'fizz', 'value': 'buzz' }]) - }) - - it('coerces array', () => { - expect(coerce('[foo,bar]')).to.have.members(['foo', 'bar']) - }) - - it('coerces array from process.env', () => { - process.env['CYPRESS_ARRAY'] = '[google.com,yahoo.com]' - const cypressEnvVar = getProcessEnvVars(process.env) - - const coercedCypressEnvVar = coerce(cypressEnvVar) - - expect(coercedCypressEnvVar).to.have.keys('ARRAY') - expect(coercedCypressEnvVar['ARRAY']).to.have.members(['google.com', 'yahoo.com']) - }) - - it('defaults value with multiple types to string', () => { - expect(coerce('123foo456')).to.eq('123foo456') - }) - }) -}) diff --git a/packages/server/test/unit/util/config_spec.js b/packages/server/test/unit/util/config_spec.js deleted file mode 100644 index 589d67238901..000000000000 --- a/packages/server/test/unit/util/config_spec.js +++ /dev/null @@ -1,48 +0,0 @@ -require('../../spec_helper') - -const configUtil = require(`../../../lib/util/config`) - -describe('lib/util/config', () => { - context('.isDefault', () => { - it('returns true if value is default value', () => { - const options = { - resolved: { - baseUrl: { from: 'default' }, - }, - } - - expect(configUtil.isDefault(options, 'baseUrl')).to.be.true - }) - - it('returns false if value is not default value', () => { - const options = { - resolved: { - baseUrl: { from: 'cli' }, - }, - } - - expect(configUtil.isDefault(options, 'baseUrl')).to.be.false - }) - }) - - context('.getProcessEnvVars', () => { - it('returns process envs prefixed with cypress', () => { - const envs = { - CYPRESS_BASE_URL: 'value', - RANDOM_ENV: 'ignored', - } - - expect(configUtil.getProcessEnvVars(envs)).to.deep.eq({ - BASE_URL: 'value', - }) - }) - - it('does not return CYPRESS_RESERVED_ENV_VARS', () => { - const envs = { - CYPRESS_INTERNAL_ENV: 'value', - } - - expect(configUtil.getProcessEnvVars(envs)).to.deep.eq({}) - }) - }) -}) diff --git a/packages/server/test/unit/util/keys_spec.ts b/packages/server/test/unit/util/keys_spec.ts deleted file mode 100644 index 7851be19b9e6..000000000000 --- a/packages/server/test/unit/util/keys_spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { hide } from '../../../lib/util/keys' -import { expect } from 'chai' - -describe('util/keys', () => { - it('removes middle part of the string', () => { - const hidden = hide('12345-xxxx-abcde') - - expect(hidden).to.equal('12345...abcde') - }) - - it('returns undefined for missing key', () => { - expect(hide()).to.be.undefined - }) - - // https://github.com/cypress-io/cypress/issues/14571 - it('returns undefined for non-string argument', () => { - expect(hide(true)).to.be.undefined - expect(hide(1234)).to.be.undefined - }) -}) diff --git a/packages/server/test/unit/util/origin_spec.js b/packages/server/test/unit/util/origin_spec.js deleted file mode 100644 index 3084434f9752..000000000000 --- a/packages/server/test/unit/util/origin_spec.js +++ /dev/null @@ -1,18 +0,0 @@ -require('../../spec_helper') - -const origin = require(`../../../lib/util/origin`) - -describe('lib/util/origin', () => { - beforeEach(function () { - this.expects = (url, expected) => { - expect(origin(url)).to.eq(expected) - } - }) - - it('strips everything but the remote origin', function () { - this.expects('http://localhost:9999/foo/bar?baz=quux#/index.html', 'http://localhost:9999') - this.expects('https://www.google.com/', 'https://www.google.com') - - return this.expects('https://app.foobar.co.uk:1234/a=b', 'https://app.foobar.co.uk:1234') - }) -}) diff --git a/packages/server/test/unit/util/path_helpers_spec.js b/packages/server/test/unit/util/path_helpers_spec.js deleted file mode 100644 index 86ec2485c3de..000000000000 --- a/packages/server/test/unit/util/path_helpers_spec.js +++ /dev/null @@ -1,21 +0,0 @@ -require('../../spec_helper') - -const path_helpers = require(`../../../lib/util/path_helpers`) - -describe('lib/util/path_helpers', () => { - context('checkIfResolveChangedRootFolder', () => { - const check = path_helpers.checkIfResolveChangedRootFolder - - it('ignores non-absolute paths', () => { - expect(check('foo/index.js', 'foo')).to.be.false - }) - - it('handles paths that do not switch', () => { - expect(check('/foo/index.js', '/foo')).to.be.false - }) - - it('detects path switch', () => { - expect(check('/private/foo/index.js', '/foo')).to.be.true - }) - }) -}) diff --git a/packages/ts/tsconfig.json b/packages/ts/tsconfig.json index 0c982dae1855..7e7e3baee408 100644 --- a/packages/ts/tsconfig.json +++ b/packages/ts/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "ES2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ - "lib": ["es2018", "ES2020.Promise"], /* Specify library files to be included in the compilation: */ + "lib": ["es2018", "ES2020.Promise", "ES2021.String"], /* Specify library files to be included in the compilation: */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/patches/return-deep-diff+0.4.0.patch b/patches/return-deep-diff+0.4.0.patch new file mode 100644 index 000000000000..cb614a6939b3 --- /dev/null +++ b/patches/return-deep-diff+0.4.0.patch @@ -0,0 +1,7 @@ +diff --git a/node_modules/return-deep-diff/index.d.ts b/node_modules/return-deep-diff/index.d.ts +new file mode 100644 +index 0000000..53711dd +--- /dev/null ++++ b/node_modules/return-deep-diff/index.d.ts +@@ -0,0 +1 @@ ++export default function deepDiff(obj1: Record, obj2: Record, keepNewKeys?: boolean): Record From 03182625cfdefad0e94217c03d9fadbc0886e70e Mon Sep 17 00:00:00 2001 From: Adam Stone Date: Thu, 18 Aug 2022 11:00:29 -0400 Subject: [PATCH 08/45] feat: Enable create from Vue component for projects with custom spec patterns (#23298) --- .../cypress/e2e/create-from-component.cy.ts | 112 ++++++++++++++++++ packages/app/cypress/e2e/specs.cy.ts | 92 -------------- packages/app/src/specs/CreateSpecModal.cy.tsx | 4 - packages/app/src/specs/CreateSpecModal.vue | 3 +- .../src/specs/DefaultSpecPatternNoContent.vue | 2 +- .../src/specs/generators/EmptyGenerator.vue | 7 +- .../component/ComponentGenerator.tsx | 6 +- .../component/ComponentGeneratorStepOne.vue | 2 - packages/app/src/specs/generators/index.ts | 4 +- packages/app/src/specs/generators/types.ts | 2 +- .../src/actions/ProjectActions.ts | 16 +-- .../data-context/src/codegen/spec-options.ts | 78 +++++++----- .../templates/vue-component/vue-component.ejs | 2 +- .../src/sources/ProjectDataSource.ts | 63 +++------- .../src/sources/migration/utils.ts | 57 +++++++++ .../test/unit/codegen/code-generator.spec.ts | 6 +- .../test/unit/codegen/spec-options.spec.ts | 105 ++++++++++++++-- .../unit/sources/ProjectDataSource.spec.ts | 48 ++++---- packages/graphql/schemas/schema.graphql | 2 +- .../schemaTypes/objectTypes/gql-Mutation.ts | 3 +- .../cypress-custom-spec-pattern.config.js | 9 ++ 21 files changed, 392 insertions(+), 231 deletions(-) create mode 100644 packages/app/cypress/e2e/create-from-component.cy.ts create mode 100644 system-tests/projects/no-specs-vue-2/cypress-custom-spec-pattern.config.js diff --git a/packages/app/cypress/e2e/create-from-component.cy.ts b/packages/app/cypress/e2e/create-from-component.cy.ts new file mode 100644 index 000000000000..5216f35ce907 --- /dev/null +++ b/packages/app/cypress/e2e/create-from-component.cy.ts @@ -0,0 +1,112 @@ +import defaultMessages from '@packages/frontend-shared/src/locales/en-US.json' +import { getPathForPlatform } from '../../src/paths' + +function validateCreateFromComponentCard (beforeEachFn: () => void, expectedSpecPath: string) { + beforeEach(beforeEachFn) + + it('Shows create from component card for Vue projects with default spec patterns', () => { + cy.get('@ComponentCard') + .within(() => { + cy.findByRole('button', { + name: 'Create from component', + }).should('be.visible') + .and('not.be.disabled') + }) + }) + + it('Can be closed with the x button', () => { + cy.get('@ComponentCard').click() + + cy.findByRole('button', { name: 'Close' }).as('DialogCloseButton') + + cy.get('@DialogCloseButton').click() + cy.findByRole('dialog', { + name: 'Choose a component', + }).should('not.exist') + }) + + it('Lists Vue components in the project', () => { + cy.get('@ComponentCard').click() + + cy.findByText('2 Matches').should('be.visible') + + cy.findByText('App').should('be.visible') + cy.findByText('HelloWorld').should('be.visible') + }) + + it('Allows for the user to search through their components', () => { + cy.get('@ComponentCard').click() + + cy.findByText('*.vue').should('be.visible') + cy.findByText('2 Matches').should('be.visible') + cy.findByLabelText('file-name-input').type('HelloWorld') + + cy.findByText('HelloWorld').should('be.visible') + cy.findByText('1 of 2 Matches').should('be.visible') + cy.findByText('App').should('not.exist') + }) + + it('shows success modal when component spec is created', () => { + cy.get('@ComponentCard').click() + + cy.findByText('HelloWorld').should('be.visible').click() + + cy.findByRole('dialog', { + name: defaultMessages.createSpec.successPage.header, + }).as('SuccessDialog').within(() => { + cy.contains(getPathForPlatform(expectedSpecPath)).should('be.visible') + cy.findByRole('button', { name: 'Close' }).should('be.visible') + + cy.findByRole('link', { name: 'Okay, run the spec' }) + .should('have.attr', 'href', `#/specs/runner?file=${expectedSpecPath}`) + + cy.findByRole('button', { name: 'Create another spec' }).click() + }) + + // 'Create from component' card appears again when the user selects "create another spec" + cy.findByText('Create from component').should('be.visible') + }) + + it('runs generated spec', () => { + cy.get('@ComponentCard').click() + + cy.findByText('HelloWorld').should('be.visible').click() + + cy.findByRole('dialog', { + name: defaultMessages.createSpec.successPage.header, + }).as('SuccessDialog').within(() => { + cy.contains(getPathForPlatform(expectedSpecPath)).should('be.visible') + cy.findByRole('button', { name: 'Close' }).should('be.visible') + + cy.findByRole('link', { name: 'Okay, run the spec' }) + .should('have.attr', 'href', `#/specs/runner?file=${expectedSpecPath}`).click() + }) + + cy.findByText('').should('be.visible') + }) +} + +describe('Create from component card', () => { + context('project with default spec pattern', () => { + validateCreateFromComponentCard(() => { + cy.scaffoldProject('no-specs-vue-2') + cy.openProject('no-specs-vue-2') + cy.startAppServer('component') + cy.visitApp() + + cy.findAllByTestId('card').eq(0).as('ComponentCard') + }, 'src/components/HelloWorld.cy.js') + }) + + context('project with custom spec pattern', () => { + validateCreateFromComponentCard(() => { + cy.scaffoldProject('no-specs-vue-2') + cy.openProject('no-specs-vue-2', ['--config-file', 'cypress-custom-spec-pattern.config.js']) + cy.startAppServer('component') + cy.visitApp() + + cy.findByText('New Spec').click() + cy.findAllByTestId('card').eq(0).as('ComponentCard') + }, 'src/specs-folder/HelloWorld.cy.js') + }) +}) diff --git a/packages/app/cypress/e2e/specs.cy.ts b/packages/app/cypress/e2e/specs.cy.ts index 97c5aa101c38..33397bbbd222 100644 --- a/packages/app/cypress/e2e/specs.cy.ts +++ b/packages/app/cypress/e2e/specs.cy.ts @@ -640,98 +640,6 @@ describe('App: Specs', () => { }) }) - context('Create from component card', () => { - beforeEach(() => { - cy.scaffoldProject('no-specs-vue-2') - cy.openProject('no-specs-vue-2') - cy.startAppServer('component') - cy.visitApp() - - cy.findAllByTestId('card').eq(0).as('ComponentCard') - }) - - it('Shows create from component card for Vue projects with default spec patterns', () => { - cy.get('@ComponentCard') - .within(() => { - cy.findByRole('button', { - name: 'Create from component', - }).should('be.visible') - .and('not.be.disabled') - }) - }) - - it('Can be closed with the x button', () => { - cy.get('@ComponentCard').click() - - cy.findByRole('button', { name: 'Close' }).as('DialogCloseButton') - - cy.get('@DialogCloseButton').click() - cy.findByRole('dialog', { - name: 'Choose a component', - }).should('not.exist') - }) - - it('Lists Vue components in the project', () => { - cy.get('@ComponentCard').click() - - cy.findByText('2 Matches').should('be.visible') - - cy.findByText('App').should('be.visible') - cy.findByText('HelloWorld').should('be.visible') - }) - - it('Allows for the user to search through their components', () => { - cy.get('@ComponentCard').click() - - cy.findByText('*.vue').should('be.visible') - cy.findByText('2 Matches').should('be.visible') - cy.findByLabelText('file-name-input').type('HelloWorld') - - cy.findByText('HelloWorld').should('be.visible') - cy.findByText('1 of 2 Matches').should('be.visible') - cy.findByText('App').should('not.exist') - }) - - it('shows success modal when component spec is created', () => { - cy.get('@ComponentCard').click() - - cy.findByText('HelloWorld').should('be.visible').click() - - cy.findByRole('dialog', { - name: defaultMessages.createSpec.successPage.header, - }).as('SuccessDialog').within(() => { - cy.contains(getPathForPlatform('src/components/HelloWorld.cy.js')).should('be.visible') - cy.findByRole('button', { name: 'Close' }).should('be.visible') - - cy.findByRole('link', { name: 'Okay, run the spec' }) - .should('have.attr', 'href', `#/specs/runner?file=src/components/HelloWorld.cy.js`) - - cy.findByRole('button', { name: 'Create another spec' }).click() - }) - - // 'Create from component' card appears again when the user selects "create another spec" - cy.findByText('Create from component').should('be.visible') - }) - - it('runs generated spec', () => { - cy.get('@ComponentCard').click() - - cy.findByText('HelloWorld').should('be.visible').click() - - cy.findByRole('dialog', { - name: defaultMessages.createSpec.successPage.header, - }).as('SuccessDialog').within(() => { - cy.contains(getPathForPlatform('src/components/HelloWorld.cy.js')).should('be.visible') - cy.findByRole('button', { name: 'Close' }).should('be.visible') - - cy.findByRole('link', { name: 'Okay, run the spec' }) - .should('have.attr', 'href', `#/specs/runner?file=src/components/HelloWorld.cy.js`).click() - }) - - cy.findByText('').should('be.visible') - }) - }) - context('project with custom spec pattern', () => { beforeEach(() => { cy.scaffoldProject('no-specs-custom-pattern') diff --git a/packages/app/src/specs/CreateSpecModal.cy.tsx b/packages/app/src/specs/CreateSpecModal.cy.tsx index f2f79b26cc6f..4d094591881f 100644 --- a/packages/app/src/specs/CreateSpecModal.cy.tsx +++ b/packages/app/src/specs/CreateSpecModal.cy.tsx @@ -34,7 +34,6 @@ describe('', () => { specPattern: '**/*.cy.{js,jsx,ts,tsx}', }, }], - isDefaultSpecPattern: true, specs: [], fileExtensionToUse: 'js', defaultSpecFileName: 'cypress/e2e/ComponentName.cy.js', @@ -130,7 +129,6 @@ describe('Modal Text Input', () => { specPattern: '**/*.cy.{js,jsx,ts,tsx}', }, }], - isDefaultSpecPattern: true, specs: [], fileExtensionToUse: 'js', defaultSpecFileName: 'cypress/e2e/ComponentName.cy.js', @@ -179,7 +177,6 @@ describe('Modal Text Input', () => { specPattern: '**/*.cy.{js,jsx,ts,tsx}', }, }], - isDefaultSpecPattern: true, specs: [], fileExtensionToUse: 'js', defaultSpecFileName: 'this/path/does/not/produce/regex/match-', @@ -232,7 +229,6 @@ describe('playground', () => { specPattern: '**/*.cy.{js,jsx,ts,tsx}', }, }], - isDefaultSpecPattern: true, specs: [], fileExtensionToUse: 'js', defaultSpecFileName: 'cypress/e2e/ComponentName.cy.js', diff --git a/packages/app/src/specs/CreateSpecModal.vue b/packages/app/src/specs/CreateSpecModal.vue index 13e8479934b6..a7abc4146365 100644 --- a/packages/app/src/specs/CreateSpecModal.vue +++ b/packages/app/src/specs/CreateSpecModal.vue @@ -77,7 +77,6 @@ fragment CreateSpecModal on Query { id fileExtensionToUse defaultSpecFileName - isDefaultSpecPattern ...ComponentGeneratorStepOne_codeGenGlob ...EmptyGenerator } @@ -107,7 +106,7 @@ const specFileName = computed(() => { return getPathForPlatform(props.gql.currentProject?.defaultSpecFileName || '') }) -const filteredGenerators = getFilteredGeneratorList(props.gql.currentProject, props.gql.currentProject?.isDefaultSpecPattern) +const filteredGenerators = getFilteredGeneratorList(props.gql.currentProject) const singleGenerator = computed(() => filteredGenerators.value.length === 1 ? filteredGenerators.value[0] : null) diff --git a/packages/app/src/specs/DefaultSpecPatternNoContent.vue b/packages/app/src/specs/DefaultSpecPatternNoContent.vue index 3f0569ea04a3..d8e2372b9e3e 100644 --- a/packages/app/src/specs/DefaultSpecPatternNoContent.vue +++ b/packages/app/src/specs/DefaultSpecPatternNoContent.vue @@ -63,7 +63,7 @@ const props = defineProps<{ gql: CreateSpecContentFragment }>() -const filteredGenerators = getFilteredGeneratorList(props.gql.currentProject, true) +const filteredGenerators = getFilteredGeneratorList(props.gql.currentProject) const emit = defineEmits<{ (e: 'showCreateSpecModal', id: string): void diff --git a/packages/app/src/specs/generators/EmptyGenerator.vue b/packages/app/src/specs/generators/EmptyGenerator.vue index a90b8b443946..180f1517f748 100644 --- a/packages/app/src/specs/generators/EmptyGenerator.vue +++ b/packages/app/src/specs/generators/EmptyGenerator.vue @@ -146,7 +146,6 @@ const props = defineProps<{ gql: EmptyGeneratorFragment type: 'e2e' | 'component' | 'componentEmpty' specFileName: string - erroredCodegenCandidate?: string /** is there any other generator available when clicking "Back" */ otherGenerators: boolean }>() @@ -168,8 +167,8 @@ mutation EmptyGenerator_MatchSpecFile($specFile: String!) { ` gql` -mutation EmptyGenerator_generateSpec($codeGenCandidate: String!, $type: CodeGenType!, $erroredCodegenCandidate: String) { - generateSpecFromSource(codeGenCandidate: $codeGenCandidate, type: $type, erroredCodegenCandidate: $erroredCodegenCandidate) { +mutation EmptyGenerator_generateSpec($codeGenCandidate: String!, $type: CodeGenType!) { + generateSpecFromSource(codeGenCandidate: $codeGenCandidate, type: $type) { ...GeneratorSuccess } }` @@ -230,7 +229,7 @@ const createSpec = async () => { return } - const { data } = await writeFile.executeMutation({ codeGenCandidate: specFile.value, type: props.type, erroredCodegenCandidate: props.erroredCodegenCandidate ?? null }) + const { data } = await writeFile.executeMutation({ codeGenCandidate: specFile.value, type: props.type }) result.value = data?.generateSpecFromSource?.generatedSpecResult?.__typename === 'ScaffoldedFile' ? data?.generateSpecFromSource?.generatedSpecResult : null } diff --git a/packages/app/src/specs/generators/component/ComponentGenerator.tsx b/packages/app/src/specs/generators/component/ComponentGenerator.tsx index 91b3236bdff1..1937264008b9 100644 --- a/packages/app/src/specs/generators/component/ComponentGenerator.tsx +++ b/packages/app/src/specs/generators/component/ComponentGenerator.tsx @@ -6,11 +6,7 @@ import ComponentGeneratorCard from './ComponentGeneratorCard.vue' export const ComponentGenerator: SpecGenerator = { card: ComponentGeneratorCard, entry: ComponentGeneratorStepOne, - show: (currentProject, isDefaultSpecPattern) => { - if (!isDefaultSpecPattern) { - return false - } - + show: (currentProject) => { return currentProject?.codeGenGlobs?.component === '*.vue' }, matches: filters.matchesCT, diff --git a/packages/app/src/specs/generators/component/ComponentGeneratorStepOne.vue b/packages/app/src/specs/generators/component/ComponentGeneratorStepOne.vue index 5f67b556d3f1..84ea5f54e2c3 100644 --- a/packages/app/src/specs/generators/component/ComponentGeneratorStepOne.vue +++ b/packages/app/src/specs/generators/component/ComponentGeneratorStepOne.vue @@ -7,7 +7,6 @@ type="component" :other-generators="false" :spec-file-name="generatedSpecError.fileName" - :errored-codegen-candidate="generatedSpecError.erroredCodegenCandidate" @restart="cancelSpecNameCreation" @updateTitle="(value) => emits('update:title', value)" /> @@ -143,7 +142,6 @@ mutation ComponentGeneratorStepOne_generateSpec($codeGenCandidate: String!, $typ generatedSpecResult { ... on GeneratedSpecError { fileName - erroredCodegenCandidate } } } diff --git a/packages/app/src/specs/generators/index.ts b/packages/app/src/specs/generators/index.ts index 26bdd0013c30..6cf4061bc794 100644 --- a/packages/app/src/specs/generators/index.ts +++ b/packages/app/src/specs/generators/index.ts @@ -19,8 +19,8 @@ export const generatorList: SpecGenerator[] = [ EmptyGenerator, ] -export const getFilteredGeneratorList = (currentProject, isDefaultSpecPattern) => { - return computed(() => generatorList.filter((g) => g.matches(currentProject.currentTestingType) && (g.show === undefined ? true : g.show(currentProject, isDefaultSpecPattern)))) +export const getFilteredGeneratorList = (currentProject) => { + return computed(() => generatorList.filter((g) => g.matches(currentProject.currentTestingType) && (g.show === undefined ? true : g.show(currentProject)))) } export const generators = keyBy(generatorList, 'id') as Record diff --git a/packages/app/src/specs/generators/types.ts b/packages/app/src/specs/generators/types.ts index ebb70a715e33..e8e3978098b4 100644 --- a/packages/app/src/specs/generators/types.ts +++ b/packages/app/src/specs/generators/types.ts @@ -15,6 +15,6 @@ export interface SpecGenerator { card: Component entry: Component matches: (testingType?: TestingType | null) => boolean - show: (currentProject?: CurrentProject, isDefaultSpecPattern?: boolean) => boolean + show: (currentProject?: CurrentProject) => boolean id: GeneratorId } diff --git a/packages/data-context/src/actions/ProjectActions.ts b/packages/data-context/src/actions/ProjectActions.ts index ef57970327cd..a24a15309c24 100644 --- a/packages/data-context/src/actions/ProjectActions.ts +++ b/packages/data-context/src/actions/ProjectActions.ts @@ -336,15 +336,13 @@ export class ProjectActions { this.api.insertProjectPreferencesToCache(this.ctx.lifecycleManager.projectTitle, args) } - async codeGenSpec (codeGenCandidate: string, codeGenType: CodeGenType, erroredCodegenCandidate?: string | null): Promise { + async codeGenSpec (codeGenCandidate: string, codeGenType: CodeGenType): Promise { const project = this.ctx.currentProject - if (!project) { - throw Error(`Cannot create spec without currentProject.`) - } + assert(project, 'Cannot create spec without currentProject.') const getCodeGenPath = () => { - return codeGenType === 'e2e' || erroredCodegenCandidate + return codeGenType === 'e2e' ? this.ctx.path.join( project, codeGenCandidate, @@ -354,18 +352,22 @@ export class ProjectActions { const codeGenPath = getCodeGenPath() + const { specPattern = [] } = await this.ctx.project.specPatterns() + const newSpecCodeGenOptions = new SpecOptions({ codeGenPath, codeGenType, - erroredCodegenCandidate, framework: this.getWizardFrameworkFromConfig(), isDefaultSpecPattern: await this.ctx.project.getIsDefaultSpecPattern(), + specPattern, + currentProject: this.ctx.currentProject, + specs: this.ctx.project.specs, }) let codeGenOptions = await newSpecCodeGenOptions.getCodeGenOptions() const codeGenResults = await codeGenerator( - { templateDir: templates[codeGenOptions.templateKey], target: path.parse(codeGenPath).dir }, + { templateDir: templates[codeGenOptions.templateKey], target: codeGenOptions.overrideCodeGenDir || path.parse(codeGenPath).dir }, codeGenOptions, ) diff --git a/packages/data-context/src/codegen/spec-options.ts b/packages/data-context/src/codegen/spec-options.ts index c5c6226140b6..d0f0d14a85b0 100644 --- a/packages/data-context/src/codegen/spec-options.ts +++ b/packages/data-context/src/codegen/spec-options.ts @@ -3,14 +3,18 @@ import type { CodeGenType } from '@packages/graphql/src/gen/nxs.gen' import type { WizardFrontendFramework } from '@packages/scaffold-config' import fs from 'fs-extra' import path from 'path' +import { getDefaultSpecFileName } from '../sources/migration/utils' +import { toPosix } from '../util' +import type { FoundSpec } from '@packages/types' interface CodeGenOptions { codeGenPath: string codeGenType: CodeGenType isDefaultSpecPattern: boolean - erroredCodegenCandidate?: string | null - specFileExtension?: string + specPattern: string[] + currentProject: string | null framework?: WizardFrontendFramework + specs?: FoundSpec[] } // Spec file extensions that we will preserve when updating the file name @@ -26,14 +30,9 @@ type ComponentExtension = `.cy.${'js' | 'ts' | 'jsx' | 'tsx'}` type TemplateKey = 'e2e' | 'componentEmpty' | 'vueComponent' export class SpecOptions { private parsedPath: ParsedPath; - private parsedErroredCodegenCandidate?: ParsedPath constructor (private options: CodeGenOptions) { this.parsedPath = path.parse(options.codeGenPath) - - if (options.erroredCodegenCandidate) { - this.parsedErroredCodegenCandidate = path.parse(options.erroredCodegenCandidate) - } } async getCodeGenOptions () { @@ -45,6 +44,7 @@ export class SpecOptions { codeGenType: this.options.codeGenType, fileName: await this.buildFileName(), templateKey: this.options.codeGenType as TemplateKey, + overrideCodeGenDir: '', } } @@ -53,12 +53,13 @@ export class SpecOptions { throw new Error('Cannot generate a spec without a framework') } - // This only works for Vue projects with default spec patterns right now. If the framework is not Vue, we're generating an empty component test - if (this.options.framework.codeGenFramework !== 'vue' || !this.options.isDefaultSpecPattern) { + // This only works for Vue projects right now. If the framework is not Vue, we're generating an empty component test + if (this.options.framework.codeGenFramework !== 'vue') { return { codeGenType: this.options.codeGenType, fileName: await this.buildFileName(), templateKey: 'componentEmpty' as TemplateKey, + overrideCodeGenDir: '', } } @@ -67,29 +68,46 @@ export class SpecOptions { return frameworkOptions } - private relativePath () { - if (!this.parsedErroredCodegenCandidate?.base) { - return `./${this.parsedPath.base}` - } + private getRelativePathToComponent (specParsedPath?: ParsedPath) { + if (specParsedPath) { + const componentPathRelative = path.relative(specParsedPath.dir, this.parsedPath.dir) - const componentPathRelative = path.relative(this.parsedPath.dir, this.parsedErroredCodegenCandidate.dir) + const componentPath = path.join(componentPathRelative, this.parsedPath.base) - const componentPath = path.join(componentPathRelative, this.parsedErroredCodegenCandidate.base) + return toPosix(componentPath.startsWith('.') ? componentPath : `./${componentPath}`) + } - return componentPath.startsWith('.') ? componentPath : `./${componentPath}` + return `./${this.parsedPath.base}` } private async getFrameworkComponentOptions () { - const componentName = this.parsedErroredCodegenCandidate?.name ?? this.parsedPath.name + const componentName = this.parsedPath.name + + const extension = await this.getVueExtension() + + let parsedSpecPath: ParsedPath | undefined + + // If we have a custom spec pattern, write the spec to a path that matches the pattern instead of the component directory + if (!this.options.isDefaultSpecPattern) { + parsedSpecPath = path.parse(await getDefaultSpecFileName({ + currentProject: this.options.currentProject, + testingType: this.options.codeGenType === 'componentEmpty' || this.options.codeGenType === 'component' ? 'component' : 'e2e', + fileExtensionToUse: (extension === '.cy.ts' || extension === '.cy.tsx') ? 'ts' : 'js', + specPattern: this.options.specPattern, + name: componentName, + specs: this.options.specs })) + } - const componentPath = this.relativePath() + // The path to import the component from + const componentPath = this.getRelativePathToComponent(parsedSpecPath) return { codeGenType: this.options.codeGenType, componentName, componentPath, - fileName: await this.buildComponentSpecFilename(await this.getVueExtension()), + fileName: await this.buildComponentSpecFilename(extension, parsedSpecPath), templateKey: 'vueComponent' as TemplateKey, + overrideCodeGenDir: parsedSpecPath?.dir, } } @@ -111,24 +129,24 @@ export class SpecOptions { } } - private getSpecExtension = () => { - if (this.options.erroredCodegenCandidate) { - return '' - } - + private getSpecExtension = (filePath?: ParsedPath) => { const foundSpecExtension = expectedSpecExtensions.find((specExtension) => { - return this.parsedPath.base.endsWith(specExtension + this.parsedPath.ext) + return filePath ? filePath.base.endsWith(specExtension + filePath.ext) : + this.parsedPath.base.endsWith(specExtension + this.parsedPath.ext) }) return foundSpecExtension || '' } - private async buildComponentSpecFilename (specExt: string) { - const { dir, base, ext } = this.parsedPath - const cyWithExt = this.getSpecExtension() + specExt - const name = base.slice(0, -ext.length) + private buildComponentSpecFilename (specExt: string, filePath?: ParsedPath) { + const { dir, base, ext } = filePath || this.parsedPath + const cyWithExt = this.getSpecExtension(filePath) + ext - return this.getFinalFileName(dir, name, cyWithExt, path.join(dir, `${name}${cyWithExt}`)) + const name = base.slice(0, base.indexOf('.')) + + const finalExtension = filePath ? cyWithExt : specExt + + return this.getFinalFileName(dir, name, finalExtension, path.join(dir, `${name}${finalExtension}`)) } private async buildFileName () { diff --git a/packages/data-context/src/codegen/templates/vue-component/vue-component.ejs b/packages/data-context/src/codegen/templates/vue-component/vue-component.ejs index 48335fd9b5d4..1666e3edb517 100644 --- a/packages/data-context/src/codegen/templates/vue-component/vue-component.ejs +++ b/packages/data-context/src/codegen/templates/vue-component/vue-component.ejs @@ -2,7 +2,7 @@ fileName: <%= fileName %> --- -import <%- componentName %> from "<%- componentPath %>" +import <%- componentName %> from '<%- componentPath %>' describe('<<%=componentName%> />', () => { it('renders', () => { diff --git a/packages/data-context/src/sources/ProjectDataSource.ts b/packages/data-context/src/sources/ProjectDataSource.ts index 441dc4c17e2f..fab5fd97d693 100644 --- a/packages/data-context/src/sources/ProjectDataSource.ts +++ b/packages/data-context/src/sources/ProjectDataSource.ts @@ -21,6 +21,7 @@ import { toPosix } from '../util/file' import type { FilePartsShape } from '@packages/graphql/src/schemaTypes/objectTypes/gql-FileParts' import type { ProjectShape } from '../data' import type { FindSpecs } from '../actions' +import { getDefaultSpecFileName } from './migration/utils' export type SpecWithRelativeRoot = FoundSpec & { relativeToCommonRoot: string } @@ -134,7 +135,15 @@ export function getLongestCommonPrefixFromPaths (paths: string[]): string { return lcp.slice(0, endIndex).join(path.sep) } -export function getPathFromSpecPattern (specPattern: string, testingType: TestingType, fileExtensionToUse?: 'js' | 'ts') { +export function getPathFromSpecPattern ({ + specPattern, + testingType, + fileExtensionToUse, + name = '' }: +{ specPattern: string + testingType: TestingType + fileExtensionToUse?: 'js' | 'ts' + name?: string}) { function replaceWildCard (s: string, fallback: string) { return s.replace(/\*/g, fallback) } @@ -152,7 +161,7 @@ export function getPathFromSpecPattern (specPattern: string, testingType: Testin if (dirname.startsWith('**')) dirname = dirname.replace('**', 'cypress') const splittedDirname = dirname.split('/').filter((s) => s !== '**').map((x) => replaceWildCard(x, testingType)).join('/') - const fileName = replaceWildCard(parsedGlob.path.filename, testingType === 'e2e' ? 'spec' : 'ComponentName') + const fileName = replaceWildCard(parsedGlob.path.filename, name ? name : testingType === 'e2e' ? 'spec' : 'ComponentName') const extnameWithoutExt = parsedGlob.path.extname.replace(parsedGlob.path.ext, '') || `.cy.${fileExtensionToUse}` @@ -386,49 +395,15 @@ export class ProjectDataSource { } async defaultSpecFileName (): Promise { - const defaultFilename = `${this.ctx.coreData.currentTestingType === 'e2e' ? 'spec' : 'ComponentName'}.cy.${this.ctx.lifecycleManager.fileExtensionToUse}` - const defaultPathname = path.join('cypress', this.ctx.coreData.currentTestingType ?? 'e2e', defaultFilename) - - if (!this.ctx.currentProject || !this.ctx.coreData.currentTestingType) { - throw new Error('Failed to get default spec filename, missing currentProject/currentTestingType') - } - - try { - let specPatternSet: string | undefined - const { specPattern = [] } = await this.ctx.project.specPatterns() + const { specPattern = [] } = await this.ctx.project.specPatterns() - if (Array.isArray(specPattern)) { - specPatternSet = specPattern[0] - } - - // 1. If there is no spec pattern, use the default for this testing type. - if (!specPatternSet) { - return defaultPathname - } - - // 2. If the spec pattern is the default spec pattern, return the default for this testing type. - if (specPatternSet === defaultSpecPattern[this.ctx.coreData.currentTestingType]) { - return defaultPathname - } - - const pathFromSpecPattern = getPathFromSpecPattern(specPatternSet, this.ctx.coreData.currentTestingType, this.ctx.lifecycleManager.fileExtensionToUse) - const filename = pathFromSpecPattern ? path.basename(pathFromSpecPattern) : defaultFilename - - // 3. If there are existing specs, return the longest common path prefix between them, if it is non-empty. - const commonPrefixFromSpecs = getLongestCommonPrefixFromPaths(this.specs.map((spec) => spec.relative)) - - if (commonPrefixFromSpecs) return path.join(commonPrefixFromSpecs, filename) - - // 4. Otherwise, return a path that fulfills the spec pattern. - if (pathFromSpecPattern) return pathFromSpecPattern - - // 5. Return the default for this testing type if we cannot decide from the spec pattern. - return defaultPathname - } catch (err) { - debug('Error intelligently detecting default filename, using safe default %o', err) - - return defaultPathname - } + return getDefaultSpecFileName({ + currentProject: this.ctx.currentProject, + testingType: this.ctx.coreData.currentTestingType, + fileExtensionToUse: this.ctx.lifecycleManager.fileExtensionToUse, + specs: this.specs, + specPattern, + }) } async matchesSpecPattern (specFile: string): Promise { diff --git a/packages/data-context/src/sources/migration/utils.ts b/packages/data-context/src/sources/migration/utils.ts index 7afdfc79cf01..af89cbb39d65 100644 --- a/packages/data-context/src/sources/migration/utils.ts +++ b/packages/data-context/src/sources/migration/utils.ts @@ -1,4 +1,9 @@ +import { defaultSpecPattern } from '@packages/config' +import type { TestingType, FoundSpec } from '@packages/types' +import Debug from 'debug' import _ from 'lodash' +import path from 'path' +import { getPathFromSpecPattern, getLongestCommonPrefixFromPaths } from '../ProjectDataSource' export const isDefaultSupportFile = (supportFile: string) => { if (_.isNil(supportFile) || !_.isBoolean(supportFile) && supportFile.match(/(^|\.+\/)cypress\/support($|\/index($|\.(ts|js|coffee)$))/)) { @@ -7,3 +12,55 @@ export const isDefaultSupportFile = (supportFile: string) => { return false } + +export async function getDefaultSpecFileName ( + { currentProject, testingType, fileExtensionToUse, specPattern, specs = [], name }: + { currentProject: string | null, testingType: TestingType | null, fileExtensionToUse: 'js' | 'ts', specPattern: string[], specs?: FoundSpec[], name?: string }, +): Promise { + const debug = Debug('cypress:data-context:sources:migration:utils') + + const defaultFilename = `${name ? name : testingType === 'e2e' ? 'spec' : 'ComponentName'}.cy.${fileExtensionToUse}` + const defaultPathname = path.join('cypress', testingType ?? 'e2e', defaultFilename) + + if (!currentProject || !testingType) { + debug('currentProject or testingType undefined. Error intelligently detecting default filename, using safe default %o', defaultPathname) + + return defaultPathname + } + + try { + let specPatternSet: string | undefined + + if (Array.isArray(specPattern)) { + specPatternSet = specPattern[0] + } + + // 1. If there is no spec pattern, use the default for this testing type. + if (!specPatternSet) { + return defaultPathname + } + + // 2. If the spec pattern is the default spec pattern, return the default for this testing type. + if (specPatternSet === defaultSpecPattern[testingType]) { + return defaultPathname + } + + const pathFromSpecPattern = getPathFromSpecPattern({ specPattern: specPatternSet, testingType, fileExtensionToUse, name }) + const filename = pathFromSpecPattern ? path.basename(pathFromSpecPattern) : defaultFilename + + // 3. If there are existing specs, return the longest common path prefix between them, if it is non-empty. + const commonPrefixFromSpecs = getLongestCommonPrefixFromPaths(specs.map((spec) => spec.relative)) + + if (commonPrefixFromSpecs) return path.join(commonPrefixFromSpecs, filename) + + // 4. Otherwise, return a path that fulfills the spec pattern. + if (pathFromSpecPattern) return pathFromSpecPattern + + // 5. Return the default for this testing type if we cannot decide from the spec pattern. + return defaultPathname + } catch (err) { + debug('Error intelligently detecting default filename, using safe default %o', err) + + return defaultPathname + } +} diff --git a/packages/data-context/test/unit/codegen/code-generator.spec.ts b/packages/data-context/test/unit/codegen/code-generator.spec.ts index dcf1b1a8aeba..b9d8c0bacfdf 100644 --- a/packages/data-context/test/unit/codegen/code-generator.spec.ts +++ b/packages/data-context/test/unit/codegen/code-generator.spec.ts @@ -11,6 +11,7 @@ import { SpecOptions } from '../../../src/codegen/spec-options' import templates from '../../../src/codegen/templates' import { createTestDataContext } from '../helper' import { WIZARD_FRAMEWORKS } from '@packages/scaffold-config' +import { defaultSpecPattern } from '@packages/config' const tmpPath = path.join(__dirname, 'tmp/test-code-gen') @@ -205,7 +206,7 @@ describe('code-generator', () => { type: 'text', status: 'add', file: fileAbsolute, - content: dedent`import ${codeGenArgs.componentName} from "${codeGenArgs.componentPath}" + content: dedent`import ${codeGenArgs.componentName} from '${codeGenArgs.componentPath}' describe('<${codeGenArgs.componentName} />', () => { it('renders', () => { @@ -257,11 +258,12 @@ describe('code-generator', () => { } const newSpecCodeGenOptions = new SpecOptions({ + currentProject: 'path/to/myProject', codeGenPath: path.join(__dirname, 'files', 'react', 'Button.jsx'), codeGenType: 'component', - specFileExtension: '.cy', framework: WIZARD_FRAMEWORKS[1], isDefaultSpecPattern: true, + specPattern: [defaultSpecPattern.component], }) let codeGenOptions = await newSpecCodeGenOptions.getCodeGenOptions() diff --git a/packages/data-context/test/unit/codegen/spec-options.spec.ts b/packages/data-context/test/unit/codegen/spec-options.spec.ts index a15c9543b66c..15fac55bc7ce 100644 --- a/packages/data-context/test/unit/codegen/spec-options.spec.ts +++ b/packages/data-context/test/unit/codegen/spec-options.spec.ts @@ -1,7 +1,9 @@ +import { defaultSpecPattern } from '@packages/config' import { WIZARD_FRAMEWORKS } from '@packages/scaffold-config' import { expect } from 'chai' import fs from 'fs-extra' import path from 'path' +import sinon from 'sinon' import { DataContext } from '../../../src' import { SpecOptions, expectedSpecExtensions } from '../../../src/codegen/spec-options' import { createTestDataContext } from '../helper' @@ -30,9 +32,11 @@ describe('spec-options', () => { for (const specExtension of expectedSpecExtensions) { it(`generates options for names with extension ${specExtension}`, async () => { const testSpecOptions = new SpecOptions({ + currentProject: 'path/to/myProject', codeGenPath: `${tmpPath}/TestName${specExtension}.js`, codeGenType: 'e2e', isDefaultSpecPattern: true, + specPattern: [defaultSpecPattern.e2e], }) const result = await testSpecOptions.getCodeGenOptions() @@ -44,9 +48,11 @@ describe('spec-options', () => { it('generates options for file name without spec extension', async () => { const testSpecOptions = new SpecOptions({ + currentProject: 'path/to/myProject', codeGenPath: `${tmpPath}/TestName.js`, codeGenType: 'e2e', isDefaultSpecPattern: true, + specPattern: [defaultSpecPattern.e2e], }) const result = await testSpecOptions.getCodeGenOptions() @@ -57,9 +63,11 @@ describe('spec-options', () => { it('generates options for file name with multiple extensions', async () => { const testSpecOptions = new SpecOptions({ + currentProject: 'path/to/myProject', codeGenPath: `${tmpPath}/TestName.foo.bar.js`, codeGenType: 'e2e', isDefaultSpecPattern: true, + specPattern: [defaultSpecPattern.e2e], }) const result = await testSpecOptions.getCodeGenOptions() @@ -67,18 +75,93 @@ describe('spec-options', () => { expect(result.codeGenType).to.eq('e2e') expect(result.fileName).to.eq(`TestName.foo.bar.js`) }) + }) - it('generates options with given codeGenType', async () => { - const testSpecOptions = new SpecOptions({ - codeGenPath: `${tmpPath}/TestName.js`, - codeGenType: 'component', - isDefaultSpecPattern: true, - framework: WIZARD_FRAMEWORKS[1], + context('create from Vue component', () => { + afterEach(function () { + sinon.restore() + }) + + context('default spec pattern', () => { + it('generates options for generating a Vue component spec', async () => { + const testSpecOptions = new SpecOptions({ + currentProject: 'path/to/myProject', + codeGenPath: `${tmpPath}/MyComponent.vue`, + codeGenType: 'component', + isDefaultSpecPattern: true, + framework: WIZARD_FRAMEWORKS[1], + specPattern: [defaultSpecPattern.component], + }) + + const result = await testSpecOptions.getCodeGenOptions() + + expect(result.codeGenType).to.eq('component') + expect(result.fileName).to.eq('MyComponent.cy.js') }) - const result = await testSpecOptions.getCodeGenOptions() + it('creates copy file if spec already exists', async () => { + sinon.stub(fs, 'access').onFirstCall().resolves().onSecondCall().rejects() + + const testSpecOptions = new SpecOptions({ + currentProject: 'path/to/myProject', + codeGenPath: `${tmpPath}/MyComponent.vue`, + codeGenType: 'component', + isDefaultSpecPattern: true, + framework: WIZARD_FRAMEWORKS[1], + specPattern: [defaultSpecPattern.component], + }) + + const result = await testSpecOptions.getCodeGenOptions() + + expect(result.codeGenType).to.eq('component') + expect(result.fileName).to.eq('MyComponent-copy-1.cy.js') + }) + }) - expect(result.codeGenType).to.eq('component') + context('custom spec pattern', () => { + [{ testName: 'src/specs-folder/*.cy.{js,jsx}', componentPath: 'ComponentName.vue', specs: [], pattern: 'src/specs-folder/*.cy.{js,jsx}', expectedPath: 'src/specs-folder/ComponentName.cy.js' }, + { testName: 'src/**/*.{spec,cy}.{js,jsx,ts,tsx}', componentPath: 'MyComponent.vue', specs: [], pattern: 'src/**/*.{spec,cy}.{js,jsx,ts,tsx}', expectedPath: 'src/MyComponent.spec.ts', isTypescriptComponent: true }, + { testName: '**/*.test.js', componentPath: 'src/Foo.vue', specs: [], pattern: '**/*.test.js', expectedPath: 'cypress/Foo.test.js' }, + { testName: 'src/**/*.js', componentPath: 'src/Foo.vue', specs: [], pattern: 'src/**/*.js', expectedPath: 'src/Foo.js' }, + { testName: '**/*.js no specs', componentPath: 'src/Foo.vue', specs: [], pattern: '**/*.js', expectedPath: 'cypress/Foo.js' }, + { testName: '**/*.js existing spec', componentPath: 'src/Foo.vue', + specs: [{ specType: 'component' as Cypress.CypressSpecType, name: 'src/Bar.cy.js', baseName: 'Bar.cy.js', fileName: 'Bar', relative: 'src/Bar.cy.js', absolute: `${tmpPath}/src/Bar.cy.js`, fileExtension: '.js', specFileExtension: '.cy.js' }], + pattern: '**/*.js', expectedPath: 'src/Foo.js' }, + { testName: '**/*.js spec already exists', componentPath: 'src/Foo.vue', + specs: [{ specType: 'component' as Cypress.CypressSpecType, name: 'src/Foo.cy.js', baseName: 'Foo.cy.js', fileName: 'Foo', relative: 'src/Foo.cy.js', absolute: `${tmpPath}/src/Foo.cy.js`, fileExtension: '.js', specFileExtension: '.cy.js' }], + pattern: '**/*.cy.js', expectedPath: 'src/Foo-copy-1.cy.js', makeCopy: true }] + .forEach(({ testName, componentPath, specs, pattern, expectedPath, makeCopy, isTypescriptComponent }) => { + it(testName, async () => { + // This stub simulates the spec file already existing the first time we try, which should cause a copy to be created + if (makeCopy) { + sinon.stub(fs, 'access').onFirstCall().resolves().onSecondCall().rejects() + } + + // This stub simulates that the component we are generating a spec from is using Typescript. + if (isTypescriptComponent) { + // @ts-ignore + sinon.stub(fs, 'readFile').resolves('lang="ts"') + } + + const currentProject = 'path/to/myProject' + const specPattern = [pattern] + + const testSpecOptions = new SpecOptions({ + currentProject, + codeGenPath: `${tmpPath}/${componentPath}`, + codeGenType: 'component', + isDefaultSpecPattern: false, + framework: WIZARD_FRAMEWORKS[1], + specPattern, + specs, + }) + + const result = await testSpecOptions.getCodeGenOptions() + + expect(result.codeGenType).to.eq('component') + expect(`${result.overrideCodeGenDir}/${result.fileName}`).to.eq(expectedPath) + }) + }) }) }) @@ -86,9 +169,11 @@ describe('spec-options', () => { for (const specExtension of expectedSpecExtensions) { it(`generates options for file name with extension ${specExtension}`, async () => { const testSpecOptions = new SpecOptions({ + currentProject: 'path/to/myProject', codeGenPath: `${tmpPath}/TestName${specExtension}.js`, codeGenType: 'e2e', isDefaultSpecPattern: true, + specPattern: [defaultSpecPattern.e2e], }) await fs.outputFile(`${tmpPath}/TestName${specExtension}.js`, '// foo') @@ -110,9 +195,11 @@ describe('spec-options', () => { it('generates options for file name without spec extension', async () => { const testSpecOptions = new SpecOptions({ + currentProject: 'path/to/myProject', codeGenPath: `${tmpPath}/TestName.js`, codeGenType: 'e2e', isDefaultSpecPattern: true, + specPattern: [defaultSpecPattern.e2e], }) await fs.outputFile(`${tmpPath}/TestName.js`, '// foo') @@ -133,9 +220,11 @@ describe('spec-options', () => { it('generates options for file name with multiple extensions', async () => { const testSpecOptions = new SpecOptions({ + currentProject: 'path/to/myProject', codeGenPath: `${tmpPath}/TestName.foo.bar.js`, codeGenType: 'e2e', isDefaultSpecPattern: true, + specPattern: [defaultSpecPattern.e2e], }) await fs.outputFile(`${tmpPath}/TestName.foo.bar.js`, '// foo') diff --git a/packages/data-context/test/unit/sources/ProjectDataSource.spec.ts b/packages/data-context/test/unit/sources/ProjectDataSource.spec.ts index 0e903254dabc..ed7dfc16eb22 100644 --- a/packages/data-context/test/unit/sources/ProjectDataSource.spec.ts +++ b/packages/data-context/test/unit/sources/ProjectDataSource.spec.ts @@ -300,31 +300,31 @@ describe('getPathFromSpecPattern', () => { context('dirname', () => { it('returns pattern without change if it is do not a glob', () => { const specPattern = 'cypress/e2e/foo.spec.ts' - const defaultFileName = getPathFromSpecPattern(specPattern, 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern, testingType: 'e2e' }) expect(defaultFileName).to.eq(specPattern) }) it('remove ** from glob if it is not in the beginning', () => { - const defaultFileName = getPathFromSpecPattern('cypress/**/foo.spec.ts', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'cypress/**/foo.spec.ts', testingType: 'e2e' }) expect(defaultFileName).to.eq('cypress/foo.spec.ts') }) it('replace ** for cypress if it starts with **', () => { - const defaultFileName = getPathFromSpecPattern('**/e2e/foo.spec.ts', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: '**/e2e/foo.spec.ts', testingType: 'e2e' }) expect(defaultFileName).to.eq('cypress/e2e/foo.spec.ts') }) it('replace ** for cypress if it starts with ** and omit extra **', () => { - const defaultFileName = getPathFromSpecPattern('**/**/foo.spec.ts', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: '**/**/foo.spec.ts', testingType: 'e2e' }) expect(defaultFileName).to.eq('cypress/foo.spec.ts') }) it('selects first option if there are multiples possibilities of values', () => { - const defaultFileName = getPathFromSpecPattern('{cypress,tests}/{integration,e2e}/foo.spec.ts', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: '{cypress,tests}/{integration,e2e}/foo.spec.ts', testingType: 'e2e' }) expect(defaultFileName).to.eq('cypress/integration/foo.spec.ts') }) @@ -332,13 +332,13 @@ describe('getPathFromSpecPattern', () => { context('filename', () => { it('replace * for filename', () => { - const defaultFileName = getPathFromSpecPattern('cypress/e2e/*.spec.ts', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'cypress/e2e/*.spec.ts', testingType: 'e2e' }) expect(defaultFileName).to.eq('cypress/e2e/spec.spec.ts') }) it('selects first option if there are multiples possibilities of values', () => { - const defaultFileName = getPathFromSpecPattern('cypress/e2e/{foo,filename}.spec.ts', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'cypress/e2e/{foo,filename}.spec.ts', testingType: 'e2e' }) expect(defaultFileName).to.eq('cypress/e2e/foo.spec.ts') }) @@ -346,13 +346,13 @@ describe('getPathFromSpecPattern', () => { context('test extension', () => { it('replace * for filename', () => { - const defaultFileName = getPathFromSpecPattern('cypress/e2e/filename.*.ts', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'cypress/e2e/filename.*.ts', testingType: 'e2e' }) expect(defaultFileName).to.eq('cypress/e2e/filename.cy.ts') }) it('selects first option if there are multiples possibilities of values', () => { - const defaultFileName = getPathFromSpecPattern('cypress/e2e/filename.{spec,cy}.ts', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'cypress/e2e/filename.{spec,cy}.ts', testingType: 'e2e' }) expect(defaultFileName).to.eq('cypress/e2e/filename.spec.ts') }) @@ -360,25 +360,25 @@ describe('getPathFromSpecPattern', () => { context('lang extension', () => { it('if project use TS, set TS as extension if it exists in the glob', () => { - const defaultFileName = getPathFromSpecPattern('cypress/e2e/filename.cy.ts', 'e2e', 'ts') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'cypress/e2e/filename.cy.ts', testingType: 'e2e', fileExtensionToUse: 'ts' }) expect(defaultFileName).to.eq('cypress/e2e/filename.cy.ts') }) it('if project use TS, set TS as extension if it exists in the options of extensions', () => { - const defaultFileName = getPathFromSpecPattern('cypress/e2e/filename.cy.{js,ts,tsx}', 'e2e', 'ts') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'cypress/e2e/filename.cy.{js,ts,tsx}', testingType: 'e2e', fileExtensionToUse: 'ts' }) expect(defaultFileName).to.eq('cypress/e2e/filename.cy.ts') }) it('if project use TS, do not set TS as extension if it do not exists in the options of extensions', () => { - const defaultFileName = getPathFromSpecPattern('cypress/e2e/filename.cy.{js,jsx}', 'e2e', 'ts') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'cypress/e2e/filename.cy.{js,jsx}', testingType: 'e2e', fileExtensionToUse: 'ts' }) expect(defaultFileName).to.eq('cypress/e2e/filename.cy.js') }) it('selects first option if there are multiples possibilities of values', () => { - const defaultFileName = getPathFromSpecPattern('cypress/e2e/filename.cy.{ts,js}', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'cypress/e2e/filename.cy.{ts,js}', testingType: 'e2e' }) expect(defaultFileName).to.eq('cypress/e2e/filename.cy.ts') }) @@ -386,43 +386,43 @@ describe('getPathFromSpecPattern', () => { context('extra cases', () => { it('creates specName for tests/*.js', () => { - const defaultFileName = getPathFromSpecPattern('tests/*.js', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'tests/*.js', testingType: 'e2e' }) expect(defaultFileName).to.eq('tests/spec.js') }) it('creates specName for src/*-test.js', () => { - const defaultFileName = getPathFromSpecPattern('src/*-test.js', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'src/*-test.js', testingType: 'e2e' }) expect(defaultFileName).to.eq('src/spec-test.js') }) it('creates specName for src/*.foo.bar.js', () => { - const defaultFileName = getPathFromSpecPattern('src/*.foo.bar.js', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'src/*.foo.bar.js', testingType: 'e2e' }) expect(defaultFileName).to.eq('src/spec.foo.bar.js') }) it('creates specName for src/prefix.*.test.js', () => { - const defaultFileName = getPathFromSpecPattern('src/prefix.*.test.js', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'src/prefix.*.test.js', testingType: 'e2e' }) expect(defaultFileName).to.eq('src/prefix.cy.test.js') }) it('creates specName for src/*/*.test.js', () => { - const defaultFileName = getPathFromSpecPattern('src/*/*.test.js', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'src/*/*.test.js', testingType: 'e2e' }) expect(defaultFileName).to.eq('src/e2e/spec.test.js') }) it('creates specName for src-*/**/*.test.js', () => { - const defaultFileName = getPathFromSpecPattern('src-*/**/*.test.js', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'src-*/**/*.test.js', testingType: 'e2e' }) expect(defaultFileName).to.eq('src-e2e/spec.test.js') }) it('creates specName for src/*.test.(js|jsx)', () => { - const defaultFileName = getPathFromSpecPattern('src/*.test.(js|jsx)', 'component') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'src/*.test.(js|jsx)', testingType: 'component' }) const possiblesFileNames = ['src/ComponentName.test.jsx', 'src/ComponentName.test.js'] @@ -430,7 +430,7 @@ describe('getPathFromSpecPattern', () => { }) it('creates specName for (src|components)/**/*.test.js', () => { - const defaultFileName = getPathFromSpecPattern('(src|components)/**/*.test.js', 'component') + const defaultFileName = getPathFromSpecPattern({ specPattern: '(src|components)/**/*.test.js', testingType: 'component' }) const possiblesFileNames = ['src/ComponentName.test.js', 'components/ComponentName.test.js'] @@ -438,13 +438,13 @@ describe('getPathFromSpecPattern', () => { }) it('creates specName for e2e/**/*.cy.{js,jsx,ts,tsx}', () => { - const defaultFileName = getPathFromSpecPattern('e2e/**/*.cy.{js,jsx,ts,tsx}', 'e2e') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'e2e/**/*.cy.{js,jsx,ts,tsx}', testingType: 'e2e' }) expect(defaultFileName).to.eq('e2e/spec.cy.js') }) it('creates specName for cypress/component-tests/**/*', () => { - const defaultFileName = getPathFromSpecPattern('cypress/component-tests/**/*', 'component', 'ts') + const defaultFileName = getPathFromSpecPattern({ specPattern: 'cypress/component-tests/**/*', testingType: 'component', fileExtensionToUse: 'ts' }) expect(defaultFileName).to.eq('cypress/component-tests/ComponentName.cy.ts') }) @@ -772,6 +772,8 @@ describe('ProjectDataSource', () => { context('#defaultSpecFilename', () => { it('yields default if no spec pattern is set', async () => { + sinon.stub(ctx.project, 'specPatterns').resolves({ specPattern: [] }) + const defaultSpecFileName = await ctx.project.defaultSpecFileName() expect(defaultSpecFileName).to.equal('cypress/e2e/spec.cy.js') diff --git a/packages/graphql/schemas/schema.graphql b/packages/graphql/schemas/schema.graphql index c6f4110370af..613eebaa0b63 100644 --- a/packages/graphql/schemas/schema.graphql +++ b/packages/graphql/schemas/schema.graphql @@ -1211,7 +1211,7 @@ type Mutation { focusActiveBrowserWindow: Boolean! """Generate spec from source""" - generateSpecFromSource(codeGenCandidate: String!, erroredCodegenCandidate: String, type: CodeGenType!): GenerateSpecResponse + generateSpecFromSource(codeGenCandidate: String!, type: CodeGenType!): GenerateSpecResponse internal_clearAllProjectPreferencesCache: Boolean internal_clearLatestProjectCache: Boolean internal_clearProjectPreferencesCache(projectTitle: String!): Boolean diff --git a/packages/graphql/src/schemaTypes/objectTypes/gql-Mutation.ts b/packages/graphql/src/schemaTypes/objectTypes/gql-Mutation.ts index 3baf389f8087..8c3f4a9770f2 100644 --- a/packages/graphql/src/schemaTypes/objectTypes/gql-Mutation.ts +++ b/packages/graphql/src/schemaTypes/objectTypes/gql-Mutation.ts @@ -246,10 +246,9 @@ export const mutation = mutationType({ args: { codeGenCandidate: nonNull(stringArg()), type: nonNull(CodeGenTypeEnum), - erroredCodegenCandidate: stringArg(), }, resolve: (_, args, ctx) => { - return ctx.actions.project.codeGenSpec(args.codeGenCandidate, args.type, args.erroredCodegenCandidate) + return ctx.actions.project.codeGenSpec(args.codeGenCandidate, args.type) }, }) diff --git a/system-tests/projects/no-specs-vue-2/cypress-custom-spec-pattern.config.js b/system-tests/projects/no-specs-vue-2/cypress-custom-spec-pattern.config.js new file mode 100644 index 000000000000..5910e12bd83b --- /dev/null +++ b/system-tests/projects/no-specs-vue-2/cypress-custom-spec-pattern.config.js @@ -0,0 +1,9 @@ +module.exports = { + component: { + specPattern: 'src/specs-folder/*.cy.{js,jsx}', + devServer: { + framework: 'vue-cli', + bundler: 'webpack' + } + } +} From 272438977e849bec4c5a14843a95e95981b265e5 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 18 Aug 2022 12:43:05 -0400 Subject: [PATCH 09/45] chore(webkit): fix WebKit network-related driver tests (#23232) Co-authored-by: Blue F --- circle.yml | 9 +- .../cypress/e2e/commands/actions/check.cy.js | 3 +- .../cypress/e2e/commands/actions/click.cy.js | 9 +- .../e2e/commands/actions/selectFile.cy.js | 6 +- .../cypress/e2e/commands/actions/type.cy.js | 3 +- .../e2e/commands/actions/type_errors.cy.js | 3 +- .../commands/actions/type_special_chars.cy.js | 3 +- .../driver/cypress/e2e/commands/cookies.cy.js | 3 +- .../cypress/e2e/commands/navigation.cy.js | 6 +- .../cypress/e2e/commands/net_stubbing.cy.ts | 27 +++-- .../driver/cypress/e2e/commands/xhr.cy.js | 12 ++- packages/driver/cypress/e2e/cy/timers.cy.js | 3 +- packages/driver/cypress/e2e/cypress/cy.cy.js | 9 +- .../cypress/e2e/cypress/error_utils.cy.ts | 6 +- .../driver/cypress/e2e/dom/visibility.cy.ts | 3 +- .../driver/cypress/e2e/e2e/dom_hitbox.cy.js | 3 +- .../driver/cypress/e2e/e2e/focus_blur.cy.js | 3 +- .../driver/cypress/e2e/e2e/react-15.cy.js | 3 +- .../driver/cypress/e2e/e2e/react-16.cy.js | 3 +- .../cypress/e2e/e2e/testConfigOverrides.cy.js | 52 +++------- .../driver/cypress/e2e/e2e/text_mask.cy.js | 3 +- .../cypress/e2e/e2e/uncaught_errors.cy.js | 8 +- packages/driver/cypress/e2e/e2e/webcam.cy.js | 11 +-- packages/driver/cypress/e2e/issues/1244.cy.js | 3 +- packages/driver/cypress/e2e/issues/7170.cy.js | 3 +- .../server/lib/browsers/cdp_automation.ts | 2 +- .../server/lib/browsers/webkit-automation.ts | 99 +++++++++++++++++-- packages/server/lib/browsers/webkit.ts | 28 +----- packages/server/lib/project-base.ts | 8 +- 29 files changed, 202 insertions(+), 132 deletions(-) diff --git a/circle.yml b/circle.yml index caefb528a2e1..f80a53bc6e04 100644 --- a/circle.yml +++ b/circle.yml @@ -2379,11 +2379,10 @@ linux-x64-workflow: &linux-x64-workflow context: test-runner:cypress-record-key requires: - build - # TODO: Fix keyboard tests to fix the majority of these tests before re-enabling - # - driver-integration-tests-webkit: - # context: test-runner:cypress-record-key - # requires: - # - build + - driver-integration-tests-webkit: + context: test-runner:cypress-record-key + requires: + - build - driver-integration-tests-chrome-experimentalSessionAndOrigin: context: test-runner:cypress-record-key requires: diff --git a/packages/driver/cypress/e2e/commands/actions/check.cy.js b/packages/driver/cypress/e2e/commands/actions/check.cy.js index 6190444d37a0..66d4cc46631b 100644 --- a/packages/driver/cypress/e2e/commands/actions/check.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/check.cy.js @@ -272,8 +272,9 @@ describe('src/cy/commands/actions/check', () => { }) }) + // TODO(webkit): fix+unskip // https://github.com/cypress-io/cypress/issues/4233 - it('can check an element behind a sticky header', () => { + it('can check an element behind a sticky header', { browser: '!webkit' }, () => { cy.viewport(400, 400) cy.visit('./fixtures/sticky-header.html') cy.get(':checkbox:first').check() diff --git a/packages/driver/cypress/e2e/commands/actions/click.cy.js b/packages/driver/cypress/e2e/commands/actions/click.cy.js index abbe5fcb5dfb..1ec6075c6269 100644 --- a/packages/driver/cypress/e2e/commands/actions/click.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/click.cy.js @@ -46,7 +46,8 @@ const getMidPoint = (el) => { const isFirefox = Cypress.isBrowser('firefox') -describe('src/cy/commands/actions/click', () => { +// TODO(webkit): fix+unskip for experimental webkit +describe('src/cy/commands/actions/click', { browser: '!webkit' }, () => { beforeEach(() => { cy.visit('/fixtures/dom.html') }) @@ -3928,7 +3929,8 @@ describe('src/cy/commands/actions/click', () => { }) }) -describe('shadow dom', () => { +// TODO(webkit): fix+unskip for experimental webkit +describe('shadow dom', { browser: '!webkit' }, () => { beforeEach(() => { cy.visit('/fixtures/shadow-dom.html') }) @@ -3991,7 +3993,8 @@ describe('shadow dom', () => { }) }) -describe('mouse state', () => { +// TODO(webkit): fix+unskip for experimental webkit +describe('mouse state', { browser: '!webkit' }, () => { describe('mouse/pointer events', () => { beforeEach(() => { cy.visit('http://localhost:3500/fixtures/dom.html') diff --git a/packages/driver/cypress/e2e/commands/actions/selectFile.cy.js b/packages/driver/cypress/e2e/commands/actions/selectFile.cy.js index c91a52550683..e75eb986615f 100644 --- a/packages/driver/cypress/e2e/commands/actions/selectFile.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/selectFile.cy.js @@ -588,7 +588,8 @@ is being covered by another element: cy.get('#hidden-basic-label').selectFile({ contents: '@foo' }, { force: true }) }) - it('can scroll to input', () => { + // TODO(webkit): fix+unskip for experimental webkit + it('can scroll to input', { browser: '!webkit' }, () => { const scrolled = [] cy.on('scrolled', ($el, type) => { @@ -646,7 +647,8 @@ is being covered by another element: }) }) - it('can specify scrollBehavior in options', () => { + // TODO(webkit): fix+unskip for experimental webkit + it('can specify scrollBehavior in options', { browser: '!webkit' }, () => { cy.get('#scroll').then((el) => { cy.spy(el[0], 'scrollIntoView') }) diff --git a/packages/driver/cypress/e2e/commands/actions/type.cy.js b/packages/driver/cypress/e2e/commands/actions/type.cy.js index 188c8003f462..f958043dddd9 100644 --- a/packages/driver/cypress/e2e/commands/actions/type.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/type.cy.js @@ -22,7 +22,8 @@ const expectTextEndsWith = (expected) => { } } -describe('src/cy/commands/actions/type - #type', () => { +// TODO(webkit): fix+unskip for experimental webkit +describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { beforeEach(() => { cy.visit('/fixtures/dom.html') }) diff --git a/packages/driver/cypress/e2e/commands/actions/type_errors.cy.js b/packages/driver/cypress/e2e/commands/actions/type_errors.cy.js index b5c864ee7a4e..00225dc4c44d 100644 --- a/packages/driver/cypress/e2e/commands/actions/type_errors.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/type_errors.cy.js @@ -1,7 +1,8 @@ const { assertLogLength } = require('../../../support/utils') const { _, $ } = Cypress -describe('src/cy/commands/actions/type - #type errors', () => { +// TODO(webkit): fix+unskip for experimental webkit release +describe('src/cy/commands/actions/type - #type errors', { browser: '!webkit' }, () => { beforeEach(() => { cy.visit('/fixtures/dom.html') }) diff --git a/packages/driver/cypress/e2e/commands/actions/type_special_chars.cy.js b/packages/driver/cypress/e2e/commands/actions/type_special_chars.cy.js index 4123fbede66a..847ba0b64cf6 100644 --- a/packages/driver/cypress/e2e/commands/actions/type_special_chars.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/type_special_chars.cy.js @@ -6,7 +6,8 @@ const { trimInnerText, } = require('../../../support/utils') -describe('src/cy/commands/actions/type - #type special chars', () => { +// TODO(webkit): fix+unskip for experimental webkit release +describe('src/cy/commands/actions/type - #type special chars', { browser: '!webkit' }, () => { before(function () { cy .visit('/fixtures/dom.html') diff --git a/packages/driver/cypress/e2e/commands/cookies.cy.js b/packages/driver/cypress/e2e/commands/cookies.cy.js index 2129bc9c901c..eb4c3a40642a 100644 --- a/packages/driver/cypress/e2e/commands/cookies.cy.js +++ b/packages/driver/cypress/e2e/commands/cookies.cy.js @@ -500,7 +500,8 @@ describe('src/cy/commands/cookies', () => { cy.setCookie('five', 'bar') // @see https://bugzilla.mozilla.org/show_bug.cgi?id=1624668 - if (Cypress.isBrowser('firefox')) { + // TODO(webkit): pw webkit has the same issue as firefox (no "unspecified" state), need a patched binary + if (Cypress.isBrowser('firefox') || Cypress.isBrowser('webkit')) { cy.getCookie('five').should('include', { sameSite: 'no_restriction' }) } else { cy.getCookie('five').should('not.have.property', 'sameSite') diff --git a/packages/driver/cypress/e2e/commands/navigation.cy.js b/packages/driver/cypress/e2e/commands/navigation.cy.js index 1d79269b7119..f1da6de4a875 100644 --- a/packages/driver/cypress/e2e/commands/navigation.cy.js +++ b/packages/driver/cypress/e2e/commands/navigation.cy.js @@ -1906,7 +1906,8 @@ describe('src/cy/commands/navigation', () => { }) }) - context('#page load', () => { + // TODO(webkit): fix+unskip for experimental webkit release + context('#page load', { browser: '!webkit' }, () => { it('sets initial=true and then removes', () => { Cookie.remove('__cypress.initial') @@ -2364,7 +2365,8 @@ describe('src/cy/commands/navigation', () => { }) }) - context('#url:changed', () => { + // TODO(webkit): fix+unskip for experimental webkit release + context('#url:changed', { browser: '!webkit' }, () => { beforeEach(function () { this.logs = [] diff --git a/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts b/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts index eaf014043174..287e38e343b0 100644 --- a/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts +++ b/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts @@ -1009,7 +1009,7 @@ describe('network stubbing', function () { // a different domain from the page own domain // NOTE: this domain is redirected back to the local host test server // using "hosts" setting in the "cypress.json" file - const corsUrl = 'http://diff.foobar.com:3501/no-cors' + let corsUrl = 'http://diff.foobar.com:3501/no-cors' beforeEach(() => { cy.visit('http://127.0.0.1:3500/fixtures/dom.html') @@ -1043,14 +1043,20 @@ describe('network stubbing', function () { }) it('can be overwritten', function () { - cy.intercept('OPTIONS', '/no-cors', (req) => { + if (Cypress.isBrowser('webkit')) { + // WebKit appears to cache successful OPTIONS responses that happen in quick succession + // so append a number to the corsUrl so the previous test doesn't cause this one to fail + corsUrl += 'v2' + } + + cy.intercept('OPTIONS', '/no-cors*', (req) => { req.reply({ headers: { 'access-control-allow-origin': 'http://wrong.invalid', }, }) }) - .intercept('/no-cors', (req) => { + .intercept('/no-cors*', (req) => { req.reply(`intercepted ${req.method}`) }) .then(() => { @@ -2379,7 +2385,9 @@ describe('network stubbing', function () { .and('include', 'content-type: application/json') }) - it('can forceNetworkError', function (done) { + // TODO(webkit): extremely flaky for some reason. need to figure out why and either fix + // or disable forceNetworkError for experimental release + it('can forceNetworkError', { browser: '!webkit' }, function (done) { const url = uniqueRoute('/foo') cy.intercept(`${url}*`, function (req) { @@ -2609,7 +2617,9 @@ describe('network stubbing', function () { }) it('intercepts cached responses as expected', { - browser: '!firefox', // TODO: why does firefox behave differently? transparently returns cached response + // TODO: why does firefox behave differently? transparently returns cached response + // TODO(webkit): fix+unskip. currently fails in WK because cache is disabled + browser: { family: 'chromium' }, }, function () { cy.visit('/fixtures/empty.html') @@ -3062,7 +3072,9 @@ describe('network stubbing', function () { .should('include', { foo: 1 }) }) - it('can forceNetworkError', function (done) { + // TODO(webkit): extremely flaky for some reason. need to figure out why and either fix + // or disable forceNetworkError for experimental release + it('can forceNetworkError', { browser: '!webkit' }, function (done) { const url = uniqueRoute('/foo') cy.intercept(`${url}*`, function (req) { @@ -3453,7 +3465,8 @@ describe('network stubbing', function () { }) // @see https://github.com/cypress-io/cypress/issues/8934 - it('can spy on a 304 not modified image response', function () { + // TODO(webkit): fix+unskip. currently fails in WK because cache is disabled + it('can spy on a 304 not modified image response', { browser: '!webkit' }, function () { const url = `/fixtures/media/cypress.png?i=${Date.now()}` cy.intercept(url).as('image') diff --git a/packages/driver/cypress/e2e/commands/xhr.cy.js b/packages/driver/cypress/e2e/commands/xhr.cy.js index d4cfd06c557e..b05bad7ade44 100644 --- a/packages/driver/cypress/e2e/commands/xhr.cy.js +++ b/packages/driver/cypress/e2e/commands/xhr.cy.js @@ -1029,7 +1029,9 @@ describe('src/cy/commands/xhr', () => { try { assertLogLength(this.logs, 1) - expect(lastLog.get('error').message).contain('foo is not defined') + const undefinedError = Cypress.browser.family === 'webkit' ? 'Can\'t find variable: foo' : 'foo is not defined' + + expect(lastLog.get('error').message).contain(undefinedError) done() } catch (err) { @@ -2695,7 +2697,10 @@ describe('src/cy/commands/xhr', () => { }) context('Cypress.on(window:unload)', () => { - it('cancels all open XHR\'s', () => { + // TODO(webkit): fix+unskip. XHRs are at { readyState: 4 } when they are canceled + // leading to a failure when we check `xhr.canceled`. `xhr.canceled` is non-standard so a better + // test may be needed here? + it('cancels all open XHR\'s', { browser: '!webkit' }, () => { const xhrs = [] cy @@ -2750,7 +2755,8 @@ describe('src/cy/commands/xhr', () => { .wait('@getFoo').its('url').should('include', '/foo') }) - it('reapplies server + route automatically during page transitions', () => { + // TODO(webkit): fix+unskip. seems to be related to `cy.click` event not firing on the , not an actual issue in cy.route + it('reapplies server + route automatically during page transitions', { browser: '!webkit' }, () => { // this tests that the server + routes are automatically reapplied // after the 2nd visit - which is an example of the remote iframe // causing an onBeforeLoad event diff --git a/packages/driver/cypress/e2e/cy/timers.cy.js b/packages/driver/cypress/e2e/cy/timers.cy.js index 0db6a7314b7d..c97669b191ed 100644 --- a/packages/driver/cypress/e2e/cy/timers.cy.js +++ b/packages/driver/cypress/e2e/cy/timers.cy.js @@ -430,7 +430,8 @@ describe('driver/src/cy/timers', () => { // }) - it('does not fire queued timers if page transitions while paused', () => { + // TODO(webkit): fix+unskip + it('does not fire queued timers if page transitions while paused', { browser: '!webkit' }, () => { // at least in chrome... whenever the page is unloaded // the browser WILL CANCEL outstanding macrotasks automatically // and invoking them does nothing diff --git a/packages/driver/cypress/e2e/cypress/cy.cy.js b/packages/driver/cypress/e2e/cypress/cy.cy.js index 9ae804558131..32dddd8e3551 100644 --- a/packages/driver/cypress/e2e/cypress/cy.cy.js +++ b/packages/driver/cypress/e2e/cypress/cy.cy.js @@ -113,7 +113,8 @@ describe('driver/src/cypress/cy', () => { }) }) - it('stores invocation stack for first command', () => { + // TODO(webkit): fix+unskip for experimental webkit + it('stores invocation stack for first command', { browser: '!webkit' }, () => { cy .get('input:first') .then(() => { @@ -123,7 +124,8 @@ describe('driver/src/cypress/cy', () => { }) }) - it('stores invocation stack for chained command', () => { + // TODO(webkit): fix+unskip for experimental webkit + it('stores invocation stack for chained command', { browser: '!webkit' }, () => { cy .get('div') .find('input') @@ -173,7 +175,8 @@ describe('driver/src/cypress/cy', () => { }) }) - describe('invocation stack', () => { + // TODO(webkit): fix+unskip for experimental webkit + describe('invocation stack', { browser: '!webkit' }, () => { beforeEach(() => { Cypress.Commands.add('getInput', () => cy.get('input')) Cypress.Commands.add('findInput', { prevSubject: 'element' }, (subject) => { diff --git a/packages/driver/cypress/e2e/cypress/error_utils.cy.ts b/packages/driver/cypress/e2e/cypress/error_utils.cy.ts index b69043d21b8b..6d8e8d0e75bb 100644 --- a/packages/driver/cypress/e2e/cypress/error_utils.cy.ts +++ b/packages/driver/cypress/e2e/cypress/error_utils.cy.ts @@ -353,7 +353,8 @@ describe('driver/src/cypress/error_utils', () => { expect(fn).to.throw('Simple error with a message') }) - it('removes internal stack lines from stack', () => { + // TODO(webkit): fix+unskip for experimental webkit + it('removes internal stack lines from stack', { browser: '!webkit' }, () => { // this features relies on Error.captureStackTrace, which some // browsers don't have (e.g. Firefox) if (!Error.captureStackTrace) return @@ -598,7 +599,8 @@ describe('driver/src/cypress/error_utils', () => { }) context('Error.captureStackTrace', () => { - it('works - even where not natively support', () => { + // TODO(webkit): fix+unskip for experimental webkit + it('works - even where not natively support', { browser: '!webkit' }, () => { function removeMe2 () { const err: Record = {} diff --git a/packages/driver/cypress/e2e/dom/visibility.cy.ts b/packages/driver/cypress/e2e/dom/visibility.cy.ts index cc04e297dde3..903be554218a 100644 --- a/packages/driver/cypress/e2e/dom/visibility.cy.ts +++ b/packages/driver/cypress/e2e/dom/visibility.cy.ts @@ -649,7 +649,8 @@ describe('src/cypress/dom/visibility', () => { cy.wrap(this.$optionHiddenInSelect.find('#hidden-opt')).should('not.be.visible') }) - it('follows regular visibility logic if option outside of select', function () { + // TODO(webkit): fix+unskip + it('follows regular visibility logic if option outside of select', { browser: '!webkit' }, function () { expect(this.$optionOutsideSelect.find('#option-hidden').is(':hidden')).to.be.true expect(this.$optionOutsideSelect.find('#option-hidden')).to.be.hidden cy.wrap(this.$optionOutsideSelect.find('#option-hidden')).should('be.hidden') diff --git a/packages/driver/cypress/e2e/e2e/dom_hitbox.cy.js b/packages/driver/cypress/e2e/e2e/dom_hitbox.cy.js index 3bbf471875e2..4abec6436581 100644 --- a/packages/driver/cypress/e2e/e2e/dom_hitbox.cy.js +++ b/packages/driver/cypress/e2e/e2e/dom_hitbox.cy.js @@ -2,7 +2,8 @@ const { clickCommandLog } = require('../../support/utils') const { _ } = Cypress // https://github.com/cypress-io/cypress/pull/5299/files -describe('rect highlight', () => { +// TODO(webkit): fix+unskip for experimental webkit +describe('rect highlight', { browser: '!webkit' }, () => { beforeEach(() => { cy.visit('/fixtures/dom.html') }) diff --git a/packages/driver/cypress/e2e/e2e/focus_blur.cy.js b/packages/driver/cypress/e2e/e2e/focus_blur.cy.js index be8247f158fc..e80a5c1de06c 100644 --- a/packages/driver/cypress/e2e/e2e/focus_blur.cy.js +++ b/packages/driver/cypress/e2e/e2e/focus_blur.cy.js @@ -509,7 +509,8 @@ describe('polyfill programmatic blur events', () => { }) }) -describe('intercept blur methods correctly', () => { +// TODO(webkit): fix+unskip for experimental webkit release +describe('intercept blur methods correctly', { browser: '!webkit' }, () => { beforeEach(() => { cy.visit('http://localhost:3500/fixtures/active-elements.html').then(() => { top.focus() diff --git a/packages/driver/cypress/e2e/e2e/react-15.cy.js b/packages/driver/cypress/e2e/e2e/react-15.cy.js index 9e4cb9886822..16c8561e1468 100644 --- a/packages/driver/cypress/e2e/e2e/react-15.cy.js +++ b/packages/driver/cypress/e2e/e2e/react-15.cy.js @@ -1,4 +1,5 @@ -describe('react v15.6.0', () => { +// TODO(webkit): fix+unskip for experimental webkit release +describe('react v15.6.0', { browser: '!webkit' }, () => { context('fires onChange events', () => { beforeEach(() => { cy.visit('/fixtures/react-15.html') diff --git a/packages/driver/cypress/e2e/e2e/react-16.cy.js b/packages/driver/cypress/e2e/e2e/react-16.cy.js index 833993011dec..7a7c989ad256 100644 --- a/packages/driver/cypress/e2e/e2e/react-16.cy.js +++ b/packages/driver/cypress/e2e/e2e/react-16.cy.js @@ -1,4 +1,5 @@ -describe('react v16.0.0', () => { +// TODO(webkit): fix+unskip for experimental webkit release +describe('react v16.0.0', { browser: '!webkit' }, () => { context('fires onChange events', () => { beforeEach(() => { cy.visit('/fixtures/react-16.html') diff --git a/packages/driver/cypress/e2e/e2e/testConfigOverrides.cy.js b/packages/driver/cypress/e2e/e2e/testConfigOverrides.cy.js index ee774bd39fed..d7431df2f1c3 100644 --- a/packages/driver/cypress/e2e/e2e/testConfigOverrides.cy.js +++ b/packages/driver/cypress/e2e/e2e/testConfigOverrides.cy.js @@ -6,48 +6,21 @@ describe('per-test config', () => { ranChrome: false, ranChromium: false, ranElectron: false, + ranWebKit: false, } after(function () { if (hasOnly(this.currentTest)) return - if (Cypress.browser.family === 'firefox') { - return expect(testState).deep.eq({ - ranChrome: false, - ranChromium: false, - ranFirefox: true, - ranElectron: false, - }) - } - - if (Cypress.browser.name === 'chrome') { - return expect(testState).deep.eq({ - ranChrome: true, - ranChromium: false, - ranFirefox: false, - ranElectron: false, - }) - } - - if (Cypress.browser.name === 'chromium') { - return expect(testState).deep.eq({ - ranChrome: false, - ranChromium: true, - ranFirefox: false, - ranElectron: false, - }) - } + const { name } = Cypress.browser - if (Cypress.browser.name === 'electron') { - return expect(testState).deep.eq({ - ranChrome: false, - ranChromium: false, - ranFirefox: false, - ranElectron: true, - }) - } - - throw new Error('should have made assertion') + expect(testState).deep.eq({ + ranChrome: name === 'chrome', + ranChromium: name === 'chromium', + ranFirefox: name === 'firefox', + ranElectron: name === 'electron', + ranWebKit: name === 'webkit', + }) }) it('set various config values', { @@ -105,6 +78,13 @@ describe('per-test config', () => { expect(Cypress.browser.name).eq('electron') }) + it('can specify only run in webkit', { + browser: 'webkit', + }, () => { + testState.ranWebKit = true + expect(Cypress.browser.name).eq('webkit') + }) + describe('mutating global config via Cypress.config and Cypress.env', () => { it('1/2 global config and env', { defaultCommandTimeout: 1234, diff --git a/packages/driver/cypress/e2e/e2e/text_mask.cy.js b/packages/driver/cypress/e2e/e2e/text_mask.cy.js index 8de87ec3a16d..18a4580a96a6 100644 --- a/packages/driver/cypress/e2e/e2e/text_mask.cy.js +++ b/packages/driver/cypress/e2e/e2e/text_mask.cy.js @@ -1,6 +1,7 @@ let changed = 0 -describe('src/cy/commands/actions/type text_mask_spec', () => { +// TODO(webkit): fix+unskip for experimental webkit release +describe('src/cy/commands/actions/type text_mask_spec', { browser: '!webkit' }, () => { beforeEach(() => { cy.visit('/fixtures/text-mask.html') diff --git a/packages/driver/cypress/e2e/e2e/uncaught_errors.cy.js b/packages/driver/cypress/e2e/e2e/uncaught_errors.cy.js index e588d0930597..95bc5eb8fdd4 100644 --- a/packages/driver/cypress/e2e/e2e/uncaught_errors.cy.js +++ b/packages/driver/cypress/e2e/e2e/uncaught_errors.cy.js @@ -97,7 +97,8 @@ describe('uncaught errors', () => { cy.get('.error-two').invoke('text').should('equal', 'async error') }) - it('unhandled rejection triggers uncaught:exception and has promise as third argument', (done) => { + // TODO(webkit): fix+unskip. the browser emits the correct event, but not at the time expected + it('unhandled rejection triggers uncaught:exception and has promise as third argument', { browser: '!webkit' }, (done) => { cy.once('uncaught:exception', (err, runnable, promise) => { expect(err.stack).to.include('promise rejection') expect(err.stack).to.include('one') @@ -116,7 +117,7 @@ describe('uncaught errors', () => { // if we mutate the error, the app's listeners for 'error' or // 'unhandledrejection' will have our wrapped error instead of the original - it('original error is not mutated for "error"', () => { + it('original error is not mutated for "error"', { browser: '!webkit' }, () => { cy.once('uncaught:exception', () => false) cy.visit('/fixtures/errors.html') @@ -125,7 +126,8 @@ describe('uncaught errors', () => { cy.get('.error-two').invoke('text').should('equal', 'sync error') }) - it('original error is not mutated for "unhandledrejection"', () => { + // TODO(webkit): fix+unskip. the browser emits the correct event, but not at the time expected + it('original error is not mutated for "unhandledrejection"', { browser: '!webkit' }, () => { cy.once('uncaught:exception', () => false) cy.visit('/fixtures/errors.html') diff --git a/packages/driver/cypress/e2e/e2e/webcam.cy.js b/packages/driver/cypress/e2e/e2e/webcam.cy.js index debfeb3fe5ef..0c4e832b4bbb 100644 --- a/packages/driver/cypress/e2e/e2e/webcam.cy.js +++ b/packages/driver/cypress/e2e/e2e/webcam.cy.js @@ -1,13 +1,8 @@ // https://github.com/cypress-io/cypress/issues/2704 -describe('webcam support', () => { - if (Cypress.isBrowser('firefox')) { - // TODO: (firefox) allow auto-bypass webcam prompt - it.skip('navigator.mediaDevices.getUserMedia resolves with fake media stream') - - return - } - +// TODO: (firefox) allow auto-bypass webcam prompt +// NOTE: playwright-webkit does not support fake webcam: https://github.com/microsoft/playwright/issues/2973 +describe('webcam support', { browser: { family: 'chromium' } }, () => { it('navigator.mediaDevices.getUserMedia resolves with fake media stream', () => { cy.visit('/fixtures/webcam.html') cy.window().then((win) => { diff --git a/packages/driver/cypress/e2e/issues/1244.cy.js b/packages/driver/cypress/e2e/issues/1244.cy.js index c712d8804e7b..ea208886c68a 100644 --- a/packages/driver/cypress/e2e/issues/1244.cy.js +++ b/packages/driver/cypress/e2e/issues/1244.cy.js @@ -11,7 +11,8 @@ describe('issue 1244', () => { for (const [el, target, action] of [['button', 'form', 'submit'], ['a', 'a', 'click']]) { //
submit, click - describe(`<${target}> ${action}`, () => { + // TODO(webkit): fix+unskip for experimental webkit release, or make skip more specific (only 4 of these generated tests fail in webkit) + describe(`<${target}> ${action}`, { browser: '!webkit' }, () => { it('correctly redirects when target=_top with target.target =', () => { cy.get(`${el}.setTarget`).click() cy.get('#dom').should('contain', 'DOM') diff --git a/packages/driver/cypress/e2e/issues/7170.cy.js b/packages/driver/cypress/e2e/issues/7170.cy.js index da8795cde689..8f6660e1b987 100644 --- a/packages/driver/cypress/e2e/issues/7170.cy.js +++ b/packages/driver/cypress/e2e/issues/7170.cy.js @@ -1,4 +1,5 @@ -describe('issue 7170', () => { +// TODO(webkit): fix+unskip for experimental webkit - also, maybe move to the correct context in type_spec +describe('issue 7170', { browser: '!webkit' }, () => { it('can type in a number field correctly', () => { cy.visit('fixtures/issue-7170.html') cy.get('button').click() diff --git a/packages/server/lib/browsers/cdp_automation.ts b/packages/server/lib/browsers/cdp_automation.ts index 7d96704741db..77d7872827ad 100644 --- a/packages/server/lib/browsers/cdp_automation.ts +++ b/packages/server/lib/browsers/cdp_automation.ts @@ -150,7 +150,7 @@ const normalizeSetCookieProps = (cookie: CyCookie): Protocol.Network.SetCookieRe return setCookieRequest } -const normalizeResourceType = (resourceType: string | undefined): ResourceType => { +export const normalizeResourceType = (resourceType: string | undefined): ResourceType => { resourceType = resourceType ? resourceType.toLowerCase() : 'unknown' if (validResourceTypes.includes(resourceType as ResourceType)) { return resourceType as ResourceType diff --git a/packages/server/lib/browsers/webkit-automation.ts b/packages/server/lib/browsers/webkit-automation.ts index 6dc9e56e7fe5..0ebac526187a 100644 --- a/packages/server/lib/browsers/webkit-automation.ts +++ b/packages/server/lib/browsers/webkit-automation.ts @@ -1,6 +1,10 @@ import _ from 'lodash' - +import Debug from 'debug' import type playwright from 'playwright-webkit' +import type { Automation } from '../automation' +import { normalizeResourceType } from './cdp_automation' + +const debug = Debug('cypress:server:browsers:webkit-automation') export type CyCookie = Pick & { // use `undefined` instead of `unspecified` @@ -33,6 +37,8 @@ const normalizeGetCookieProps = (cookie: any): CyCookie => { if (cookie.sameSite === 'None') { cookie.sameSite = 'no_restriction' + } else if (cookie.sameSite) { + cookie.sameSite = cookie.sameSite.toLowerCase() } return cookie as CyCookie @@ -74,16 +80,89 @@ const _cookieMatches = (cookie: any, filter: Record) => { return true } +let requestIdCounter = 1 +const requestIdMap = new WeakMap() + export class WebkitAutomation { - private context: playwright.BrowserContext - public reset: (url?: string) => Promise - - constructor (resetPage, private page: playwright.Page) { - this.context = page.context() - this.reset = async (url?: string) => { - this.page = await resetPage(url) - this.context = this.page.context() - } + private context!: playwright.BrowserContext + private page!: playwright.Page + + private constructor (public automation: Automation, private browser: playwright.Browser) {} + + // static initializer to avoid "not definitively declared" + static async create (automation: Automation, browser: playwright.Browser, initialUrl: string) { + const wkAutomation = new WebkitAutomation(automation, browser) + + await wkAutomation.reset(initialUrl) + + return wkAutomation + } + + public async reset (newUrl?: string) { + debug('resetting playwright page + context %o', { newUrl }) + // new context comes with new cache + storage + const newContext = await this.browser.newContext({ + ignoreHTTPSErrors: true, + }) + const oldPwPage = this.page + + this.page = await newContext.newPage() + this.context = this.page.context() + + this.attachListeners(this.page) + + let promises: Promise[] = [] + + if (oldPwPage) promises.push(oldPwPage.context().close()) + + if (newUrl) promises.push(this.page.goto(newUrl)) + + if (promises.length) await Promise.all(promises) + } + + private attachListeners (page: playwright.Page) { + // emit preRequest to proxy + page.on('request', (request) => { + // ignore socket.io events + // TODO: use config.socketIoRoute here instead + if (request.url().includes('/__socket') || request.url().includes('/__cypress')) return + + // pw does not expose an ID on requests, so create one + const requestId = String(requestIdCounter++) + + requestIdMap.set(request, requestId) + + const browserPreRequest = { + requestId, + method: request.method(), + url: request.url(), + // TODO: await request.allHeaders() causes this to not resolve in time + headers: request.headers(), + resourceType: normalizeResourceType(request.resourceType()), + originalResourceType: request.resourceType(), + } + + debug('received request %o', { browserPreRequest }) + this.automation.onBrowserPreRequest?.(browserPreRequest) + }) + + page.on('requestfinished', async (request) => { + const requestId = requestIdMap.get(request) + + if (!requestId) return + + const response = await request.response() + + const responseReceived = { + requestId, + status: response?.status(), + headers: await response?.allHeaders(), + } + + debug('received requestfinished %o', { responseReceived }) + + this.automation.onRequestEvent?.('response:received', responseReceived) + }) } private async getCookies () { diff --git a/packages/server/lib/browsers/webkit.ts b/packages/server/lib/browsers/webkit.ts index fa7694ba1d03..e236a7ecfcf4 100644 --- a/packages/server/lib/browsers/webkit.ts +++ b/packages/server/lib/browsers/webkit.ts @@ -13,6 +13,7 @@ export async function connectToNewSpec (browser: Browser, options, automation: A if (!wkAutomation) throw new Error('connectToNewSpec called without wkAutomation') automation.use(wkAutomation) + wkAutomation.automation = automation await options.onInitializeNewBrowserTab() await wkAutomation.reset(options.url) } @@ -30,32 +31,7 @@ export async function open (browser: Browser, url, options: any = {}, automation headless: browser.isHeadless, }) - let pwPage: playwright.Page - - async function resetPage (_url) { - // new context comes with new cache + storage - const newContext = await pwBrowser.newContext({ - ignoreHTTPSErrors: true, - }) - const oldPwPage = pwPage - - pwPage = await newContext.newPage() - - let promises: Promise[] = [] - - if (oldPwPage) promises.push(oldPwPage.context().close()) - - if (_url) promises.push(pwPage.goto(_url)) - - if (promises.length) await Promise.all(promises) - - return pwPage - } - - pwPage = await resetPage(url) - - wkAutomation = new WebkitAutomation(resetPage, pwPage) - + wkAutomation = await WebkitAutomation.create(automation, pwBrowser, url) automation.use(wkAutomation) class WkInstance extends EventEmitter implements BrowserInstance { diff --git a/packages/server/lib/project-base.ts b/packages/server/lib/project-base.ts index fdd5f7ad8f7a..1f11b533922e 100644 --- a/packages/server/lib/project-base.ts +++ b/packages/server/lib/project-base.ts @@ -432,13 +432,7 @@ export class ProjectBase extends EE { } shouldCorrelatePreRequests = () => { - if (!this.browser) { - return false - } - - const { family, majorVersion } = this.browser - - return family === 'chromium' || (family === 'firefox' && majorVersion >= 86) + return !!this.browser } setCurrentSpecAndBrowser (spec, browser: FoundBrowser) { From 31527ff8c92aea1289445c8b0eb028a0740ec987 Mon Sep 17 00:00:00 2001 From: Matt Schile Date: Thu, 18 Aug 2022 15:37:05 -0600 Subject: [PATCH 10/45] chore: update add_to_triage_project github token (#23440) --- .github/workflows/add_to_triage_project.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/add_to_triage_project.yml b/.github/workflows/add_to_triage_project.yml index d0f913bc1e49..235874028d3c 100644 --- a/.github/workflows/add_to_triage_project.yml +++ b/.github/workflows/add_to_triage_project.yml @@ -16,5 +16,5 @@ jobs: - uses: actions/add-to-project@v0.3.0 with: project-url: https://github.com/orgs/cypress-io/projects/9 - github-token: ${{ secrets.GITHUB_TOKEN }} + github-token: ${{ secrets.ADD_TO_PROJECT_TOKEN }} From 47d86556bd4c90b5a3275ea5501d0d0dacf5a439 Mon Sep 17 00:00:00 2001 From: Jaime Pericas Date: Thu, 18 Aug 2022 15:34:56 -0700 Subject: [PATCH 11/45] fix: adds GITHUB_RUN_ATTEMPT counter for tracking retries --- packages/server/lib/util/ci_provider.js | 2 ++ packages/server/test/unit/util/ci_provider_spec.js | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/packages/server/lib/util/ci_provider.js b/packages/server/lib/util/ci_provider.js index b8e5a07d2b9a..965b13f5229c 100644 --- a/packages/server/lib/util/ci_provider.js +++ b/packages/server/lib/util/ci_provider.js @@ -246,6 +246,7 @@ const _providerCiParams = () => { 'GITHUB_ACTION', 'GITHUB_EVENT_NAME', 'GITHUB_RUN_ID', + 'GITHUB_RUN_ATTEMPT', 'GITHUB_REPOSITORY', ]), // see https://docs.gitlab.com/ee/ci/variables/ @@ -513,6 +514,7 @@ const _providerCommitParams = () => { branch: env.GH_BRANCH || env.GITHUB_REF, defaultBranch: env.GITHUB_BASE_REF, remoteBranch: env.GITHUB_HEAD_REF, + runAttempt: env.GITHUB_RUN_ATTEMPT, }, gitlab: { sha: env.CI_COMMIT_SHA, diff --git a/packages/server/test/unit/util/ci_provider_spec.js b/packages/server/test/unit/util/ci_provider_spec.js index 52b51f936c6c..b98908aace65 100644 --- a/packages/server/test/unit/util/ci_provider_spec.js +++ b/packages/server/test/unit/util/ci_provider_spec.js @@ -549,6 +549,7 @@ describe('lib/util/ci_provider', () => { GITHUB_ACTION: 'ciGitHubActionId', GITHUB_EVENT_NAME: 'ciEventName', GITHUB_RUN_ID: 'ciGithubRunId', + GITHUB_RUN_ATTEMPT: 'ciGithubRunAttempt', GITHUB_REPOSITORY: 'ciGithubRepository', GH_BRANCH: '', @@ -566,12 +567,14 @@ describe('lib/util/ci_provider', () => { githubEventName: 'ciEventName', githubWorkflow: 'ciGitHubWorkflowName', githubRepository: 'ciGithubRepository', + githubRunAttempt: 'ciGithubRunAttempt', githubRunId: 'ciGithubRunId', }) expectsCommitParams({ sha: 'ciCommitSha', defaultBranch: 'ciBaseRef', + runAttempt: 'ciGithubRunAttempt', remoteBranch: 'ciHeadRef', branch: 'ciCommitRef', }) @@ -580,10 +583,12 @@ describe('lib/util/ci_provider', () => { GITHUB_ACTIONS: 'true', GITHUB_REF: 'ciCommitRef', GH_BRANCH: 'GHCommitBranch', + GITHUB_RUN_ATTEMPT: 'ciGithubRunAttempt', }, { clear: true }) return expectsCommitParams({ branch: 'GHCommitBranch', + runAttempt: 'ciGithubRunAttempt', }) }) From 287aeba860608ed6f19ce64d0b5e7eb5405f4c2b Mon Sep 17 00:00:00 2001 From: GitStart <1501599+gitstart@users.noreply.github.com> Date: Fri, 19 Aug 2022 15:09:49 +0100 Subject: [PATCH 12/45] fix: missing fallback generic browser icon in some places (#23031) Co-authored-by: Mark Noonan --- .../src/runner/SpecRunnerHeaderOpenMode.cy.tsx | 15 +++++++++++++++ .../app/src/runner/SpecRunnerHeaderOpenMode.vue | 2 +- .../src/runner/SpecRunnerHeaderRunMode.cy.tsx | 17 +++++++++++++++++ .../app/src/runner/SpecRunnerHeaderRunMode.vue | 2 +- .../runner/automation/AutomationMissing.cy.tsx | 14 ++++++++++++++ .../src/runner/automation/AutomationMissing.vue | 2 +- 6 files changed, 49 insertions(+), 3 deletions(-) diff --git a/packages/app/src/runner/SpecRunnerHeaderOpenMode.cy.tsx b/packages/app/src/runner/SpecRunnerHeaderOpenMode.cy.tsx index 5562d05eaf34..a7bd4efc18fa 100644 --- a/packages/app/src/runner/SpecRunnerHeaderOpenMode.cy.tsx +++ b/packages/app/src/runner/SpecRunnerHeaderOpenMode.cy.tsx @@ -2,6 +2,7 @@ import SpecRunnerHeaderOpenMode from './SpecRunnerHeaderOpenMode.vue' import { useAutStore } from '../store' import { SpecRunnerHeaderFragment, SpecRunnerHeaderFragmentDoc } from '../generated/graphql-test' import { createEventManager, createTestAutIframe } from '../../cypress/component/support/ctSupport' +import { allBrowsersIcons } from '@packages/frontend-shared/src/assets/browserLogos' function renderWithGql (gqlVal: SpecRunnerHeaderFragment) { const eventManager = createEventManager() @@ -166,6 +167,20 @@ describe('SpecRunnerHeaderOpenMode', { viewportHeight: 500 }, () => { cy.percySnapshot() }) + it('shows generic browser icon when current browser icon is not configured', () => { + cy.mountFragment(SpecRunnerHeaderFragmentDoc, { + onResult: (ctx) => { + ctx.activeBrowser = ctx.browsers?.find((x) => x.displayName === 'Fake Browser') ?? null + }, + render: (gqlVal) => { + return renderWithGql(gqlVal) + }, + }) + + cy.get('[data-cy="select-browser"] > button img').should('have.attr', 'src', allBrowsersIcons.generic) + cy.percySnapshot() + }) + it('shows current viewport info', () => { cy.mountFragment(SpecRunnerHeaderFragmentDoc, { render: (gqlVal) => { diff --git a/packages/app/src/runner/SpecRunnerHeaderOpenMode.vue b/packages/app/src/runner/SpecRunnerHeaderOpenMode.vue index 82b7c7d0b703..3482e870da5c 100644 --- a/packages/app/src/runner/SpecRunnerHeaderOpenMode.vue +++ b/packages/app/src/runner/SpecRunnerHeaderOpenMode.vue @@ -54,7 +54,7 @@ diff --git a/packages/app/src/runner/automation/AutomationMissing.cy.tsx b/packages/app/src/runner/automation/AutomationMissing.cy.tsx index 9795130fa64b..bbadf16ea2a0 100644 --- a/packages/app/src/runner/automation/AutomationMissing.cy.tsx +++ b/packages/app/src/runner/automation/AutomationMissing.cy.tsx @@ -1,3 +1,4 @@ +import { allBrowsersIcons } from '@packages/frontend-shared/src/assets/browserLogos' import { AutomationMissingFragmentDoc, VerticalBrowserListItems_SetBrowserDocument } from '../../generated/graphql-test' import AutomationMissing from './AutomationMissing.vue' @@ -36,4 +37,17 @@ describe('AutomationMissing', () => { cy.wrap(selectBrowserStub).should('have.been.called') }) + + it('shows generic browser icon when current browser icon is not configured', () => { + cy.mountFragment(AutomationMissingFragmentDoc, { + render (gql) { + gql.activeBrowser = gql.browsers?.find((x) => x.displayName === 'Fake Browser') ?? null + + return () + }, + }) + + cy.get('[data-cy="select-browser"] > button img').should('have.attr', 'src', allBrowsersIcons.generic) + cy.percySnapshot() + }) }) diff --git a/packages/app/src/runner/automation/AutomationMissing.vue b/packages/app/src/runner/automation/AutomationMissing.vue index 4a431aecaf57..7385ca354ac1 100644 --- a/packages/app/src/runner/automation/AutomationMissing.vue +++ b/packages/app/src/runner/automation/AutomationMissing.vue @@ -21,7 +21,7 @@ From 98cbac1be763503d6b79e0c9dd835007a862f3d8 Mon Sep 17 00:00:00 2001 From: Rachel Date: Fri, 19 Aug 2022 09:10:22 -0700 Subject: [PATCH 13/45] skip set cookie 23444 --- packages/driver/cypress/e2e/commands/cookies.cy.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/driver/cypress/e2e/commands/cookies.cy.js b/packages/driver/cypress/e2e/commands/cookies.cy.js index eb4c3a40642a..16ef3e084560 100644 --- a/packages/driver/cypress/e2e/commands/cookies.cy.js +++ b/packages/driver/cypress/e2e/commands/cookies.cy.js @@ -435,7 +435,8 @@ describe('src/cy/commands/cookies', () => { }) }) - context('#setCookie', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + context.skip('#setCookie', () => { beforeEach(() => { cy.stub(Cypress.utils, 'addTwentyYears').returns(12345) }) From 97551d792045d3ead3b1c6f33bf4d4f02a96e652 Mon Sep 17 00:00:00 2001 From: Rachel Date: Fri, 19 Aug 2022 09:10:41 -0700 Subject: [PATCH 14/45] Revert "skip set cookie 23444" This reverts commit 98cbac1be763503d6b79e0c9dd835007a862f3d8. --- packages/driver/cypress/e2e/commands/cookies.cy.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/driver/cypress/e2e/commands/cookies.cy.js b/packages/driver/cypress/e2e/commands/cookies.cy.js index 16ef3e084560..eb4c3a40642a 100644 --- a/packages/driver/cypress/e2e/commands/cookies.cy.js +++ b/packages/driver/cypress/e2e/commands/cookies.cy.js @@ -435,8 +435,7 @@ describe('src/cy/commands/cookies', () => { }) }) - // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 - context.skip('#setCookie', () => { + context('#setCookie', () => { beforeEach(() => { cy.stub(Cypress.utils, 'addTwentyYears').returns(12345) }) From 6e18996d0211a6ee22ca5fb31561e6f3597b2f78 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Fri, 19 Aug 2022 13:40:27 -0400 Subject: [PATCH 15/45] chore: skip Circle env canary check unless in Docker (#23467) --- circle.yml | 7 +++++-- scripts/verify-mocha-results.js | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/circle.yml b/circle.yml index f80a53bc6e04..fe8e8791f50f 100644 --- a/circle.yml +++ b/circle.yml @@ -78,6 +78,7 @@ executors: resource_class: medium environment: PLATFORM: linux + CI_DOCKER: "true" # Docker image with non-root "node" user non-root-docker-user: @@ -1200,8 +1201,10 @@ jobs: - run: name: Check env canaries on Linux command: | - # Windows/Mac M1 CircleCI does not have a way to pull per-job env - [[ $PLATFORM == 'linux' ]] && node ./scripts/circle-env.js --check-canaries || true + # only Docker has the required env data for this + if [[ $CI_DOCKER == 'true' ]]; then + node ./scripts/circle-env.js --check-canaries + fi - build-and-persist - store-npm-logs diff --git a/scripts/verify-mocha-results.js b/scripts/verify-mocha-results.js index 231f363e6684..e2eb33eea770 100644 --- a/scripts/verify-mocha-results.js +++ b/scripts/verify-mocha-results.js @@ -83,7 +83,7 @@ async function checkReportFiles (filenames) { circleEnv = await readCircleEnv() } catch (err) { // set SKIP_CIRCLE_ENV to bypass, for local development - if (!process.env.SKIP_CIRCLE_ENV) throw err + if (!process.env.SKIP_CIRCLE_ENV && process.env.CI_DOCKER) throw err circleEnv = {} } From a9456887e4a5e2820372bb9e96bad462a8796166 Mon Sep 17 00:00:00 2001 From: Ryan Manuel Date: Fri, 19 Aug 2022 15:18:56 -0500 Subject: [PATCH 16/45] fix: app crashing on websocket upgrade request over https (#23449) --- packages/network/lib/agent.ts | 8 +++--- packages/network/test/unit/agent_spec.ts | 32 ++++++++++++++++++++---- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/packages/network/lib/agent.ts b/packages/network/lib/agent.ts index 425c3605be24..a4bc0aa46b2d 100644 --- a/packages/network/lib/agent.ts +++ b/packages/network/lib/agent.ts @@ -181,6 +181,10 @@ export class CombinedAgent { }) + options.path } + if (!options.uri) { + options.uri = url.parse(options.href) + } + debug('addRequest called %o', { isHttps, ..._.pick(options, 'href') }) return getFirstWorkingFamily(options, this.familyCache, (family: net.family) => { @@ -280,10 +284,6 @@ class HttpsAgent extends https.Agent { } addRequest (req: http.ClientRequest, options: http.RequestOptions) { - if (!options.uri) { - options.uri = url.parse(options.href) - } - // Ensure we have a proper port defined otherwise node has assumed we are port 80 // (https://github.com/nodejs/node/blob/master/lib/_http_client.js#L164) since we are a combined agent // rather than an http or https agent. This will cause issues with fetch requests (@cypress/request already handles it: diff --git a/packages/network/test/unit/agent_spec.ts b/packages/network/test/unit/agent_spec.ts index b047a23eebca..f25d78c6f181 100644 --- a/packages/network/test/unit/agent_spec.ts +++ b/packages/network/test/unit/agent_spec.ts @@ -507,11 +507,11 @@ describe('lib/agent', function () { ;[ { name: 'should present a client certificate', - peresentClientCertificate: true, + presentClientCertificate: true, }, { - name: 'should present not a client certificate', - peresentClientCertificate: false, + name: 'should not present a client certificate', + presentClientCertificate: false, }, ].slice().map((testCase) => { context(testCase.name, function () { @@ -537,7 +537,7 @@ describe('lib/agent', function () { auth: false, } - if (testCase.peresentClientCertificate) { + if (testCase.presentClientCertificate) { clientCertificateStore.clear() const certAndKey = createCertAndKey() const pemCert = pki.certificateToPem(certAndKey[0]) @@ -560,7 +560,7 @@ describe('lib/agent', function () { this.debugProxy.stop() }) - it('Client certificate presneted if appropriate', function () { + it(`Client certificate${testCase.presentClientCertificate ? ' ' : ' not '}presented for https request`, function () { return this.request({ url: `https://localhost:${HTTPS_PORT}/get`, }).then((body) => { @@ -585,6 +585,28 @@ describe('lib/agent', function () { } }) }) + + it(`Client certificate${testCase.presentClientCertificate ? ' ' : ' not '}presented for https websocket`, function () { + const socket = socketIo.client(`https://localhost:${HTTPS_PORT}`, { + agent: this.agent, + transports: ['websocket'], + rejectUnauthorized: false, + }) + + return new Bluebird((resolve) => { + socket.on('message', resolve) + }) + .then((msg) => { + expect(msg).to.eq('It worked!') + if (this.debugProxy) { + expect(this.debugProxy.requests[0]).to.include({ + url: `localhost:${HTTPS_PORT}`, + }) + } + + socket.close() + }) + }) }) }) }) From ab23d7797bc40ef463a1e5783c49040fc7a2e0aa Mon Sep 17 00:00:00 2001 From: Rachel Date: Mon, 22 Aug 2022 10:50:12 -0700 Subject: [PATCH 17/45] chore: skip or fix flaky tests II (#23386) * fix leftover percy network-idle-timeout * Skip another instance of 23153 * fix 23147 * Revert fix 23147 * try percy upgrade again * Update yarn.lock * skip 23404 * bring in emilys override version change for percy ui * skip 23406 * skip 23407 * downgrade percy to 1.2.0 * fix percy diff * fix percy diff * update comment * restore lock file * Update yarn.lock * Update yarn.lock * percy fixes * possible fix * fix verison flake?? * Revert "fix percy diff" This reverts commit e4c4e2e99033d31fe5f62cb47fb5d905e5c7d26c. * Revert "Revert "fix percy diff"" This reverts commit 94284e46948215d8e6f80dad001b91bd1a92a809. * Remove version assertion * Trigger Build * ignore spec duration in percy snapshots * use .each to preserve order of execution * add comment * fix comment * try new logic for header wait * Revert "try new logic for header wait" This reverts commit bfed31edceb3433ef1d2d6732d3dddc4812e4526. * add timeout to choose a browser * Trigger Build * try without promise.all; revert timeout to choose a browser tests * ignore spec-duration in percy in runner * clean up .thens * clean up diffs * move around .thens * wait for tooltip to take snapshot, skip flakers * try hiding spec duration * Revert: try hiding spec duration * Bring back duration mock * Add another duration mock * try cy.contains with tooltip, comment out removeGlobalStyles * skip 23417 * skip choose a browser failures * skip 23419 * skip 23414 * bring back // removeGlobalStyles() * skip 23422 * skip 23423 * skip 23424 * set version to empty string to make percy happy * Remove duration mock * Do not display top-nav-cypress-version-current-link, skip 23433? * skip 23434, clean up diffs * clean up diffs, skip percy flake * skip 23434 * skip 23437 * fix 23156 * fix 23250 and similar * fix 23157 * skip more percies * skip 23443 * skip more tooltip snapshots * Update net_stubbing.cy.ts * Update cookies.cy.js * Update e2e_cookies.cy.js * add missing github issue * Update circle.yml * Skip all of network stubbing * Skip 23158 * Skip 23448 * remove unnecessary async, add skip for 23444 * more skips for 23444 * skip 23451 * More skips 23436 * More skips 23444 * skip 23455 * more skips 23444 * skip 23457 * more skips 23444 * mroe skip 23455 * Trigger Build * skip set cookie 23444 * skip 21300 * skip 23417 * Trigger Build * potential fix for 23308 * skip 23472 * skip snapshot * skip 23474 * Trigger Build * Trigger Build * Trigger Build * Trigger Build * skip more 23245 * Trigger Build * Trigger Build * Trigger Build * Trigger Build * Trigger Build * Trigger Build * Trigger Build * skip 23480,23481 * skip 23307 * Trigger Build * addtl skip 23481 * skip 23484 * try cy.origin stability fix on nav commands issue * Revert: try cy.origin stability fix on nav commands issue * skip more 23452 * Trigger Build * Trigger Build * Trigger Build * Trigger Build * Trigger Build * Trigger Build * Trigger Build * Trigger Build * skip 23493 * Trigger Build --- circle.yml | 3 ++ .../schematics/ng-generate/e2e/index.spec.ts | 2 +- npm/vite-dev-server/.percy.yml | 2 +- npm/webpack-dev-server/.percy.yml | 2 +- .../cypress/e2e/angular.cy.ts | 3 +- npm/webpack-dev-server/cypress/e2e/next.cy.ts | 6 ++- npm/webpack-dev-server/cypress/e2e/nuxt.cy.ts | 3 +- .../cypress/e2e/cypress-in-cypress-e2e.cy.ts | 6 +-- .../e2e/cypress-in-cypress-run-mode.cy.ts | 4 +- .../app/cypress/e2e/cypress-in-cypress.cy.ts | 20 ++++++---- .../app/cypress/e2e/runner/sessions.ui.cy.ts | 13 ++++--- .../e2e/runner/support/snapshot-reporter.ts | 2 +- packages/app/cypress/e2e/runs.cy.ts | 2 +- packages/app/cypress/e2e/settings.cy.ts | 2 +- .../app/cypress/e2e/sidebar_navigation.cy.ts | 15 ++++---- packages/app/cypress/e2e/specs.cy.ts | 21 +++++----- .../cypress/e2e/specs_list_latest_runs.cy.ts | 3 +- .../cypress/e2e/specs_list_no_git_repo.cy.ts | 3 +- packages/app/cypress/e2e/top-nav.cy.ts | 4 +- .../src/navigation/SidebarNavigation.cy.tsx | 2 +- .../src/runner/screenshot/screenshot.cy.tsx | 5 +++ .../SelectorPlayground.cy.tsx | 26 ++++++++++--- .../app/src/specs/LastUpdatedHeader.cy.tsx | 4 +- packages/app/src/specs/SpecListGitInfo.cy.tsx | 16 ++++++-- .../cypress/e2e/commands/actions/check.cy.js | 9 +++-- .../cypress/e2e/commands/actions/select.cy.js | 21 ++++++---- .../command_option_immutability.cy.js | 7 ++-- .../driver/cypress/e2e/commands/cookies.cy.js | 18 ++++++--- .../cypress/e2e/commands/navigation.cy.js | 6 ++- .../cypress/e2e/commands/net_stubbing.cy.ts | 38 ++++++++++++------- .../driver/cypress/e2e/commands/xhr.cy.js | 3 +- .../cypress/e2e/cypress/proxy-logging.cy.ts | 15 ++++---- .../driver/cypress/e2e/e2e/e2e_cookies.cy.js | 15 +++++--- .../cypress/e2e/e2e/origin/basic_login.cy.ts | 3 +- .../e2e/e2e/origin/commands/actions.cy.ts | 3 +- .../cypress/e2e/e2e/origin/logging.cy.ts | 6 ++- .../cypress/e2e/e2e/origin/navigation.cy.ts | 3 +- .../cypress/e2e/e2e/origin/snapshots.cy.ts | 3 +- .../e2e/e2e/origin/uncaught_errors.cy.ts | 3 +- .../cypress/e2e/e2e/origin/validation.cy.ts | 3 +- .../cypress/e2e/support/e2eSupport.ts | 3 ++ .../gql-components/HeaderBarContent.cy.tsx | 10 ++++- .../cypress/e2e/choose-a-browser.cy.ts | 6 ++- .../cypress/e2e/config-warning.cy.ts | 3 +- .../launchpad/cypress/e2e/project-setup.cy.ts | 6 ++- .../e2e/scaffold-component-testing.cy.ts | 3 +- .../launchpad/cypress/e2e/slow-network.cy.ts | 3 +- .../src/setup/OpenBrowserList.cy.tsx | 5 ++- packages/server/test/unit/fixture_spec.js | 3 +- .../server/test/unit/open_project_spec.js | 3 +- system-tests/test/plugins_spec.js | 3 +- yarn.lock | 2 +- 52 files changed, 242 insertions(+), 133 deletions(-) diff --git a/circle.yml b/circle.yml index fe8e8791f50f..af705010732c 100644 --- a/circle.yml +++ b/circle.yml @@ -36,6 +36,7 @@ macWorkflowFilters: &darwin-workflow-filters or: - equal: [ develop, << pipeline.git.branch >> ] - equal: [ 'tbiethman/22272-globbing-working-dir', << pipeline.git.branch >> ] + - equal: [ 'skip-or-fix-flaky-tests-2', << pipeline.git.branch >> ] - matches: pattern: "-release$" value: << pipeline.git.branch >> @@ -45,6 +46,7 @@ linuxArm64WorkflowFilters: &linux-arm64-workflow-filters or: - equal: [ develop, << pipeline.git.branch >> ] - equal: [ "lmiller/experimental-single-tab-component-testing", << pipeline.git.branch >> ] + - equal: [ 'skip-or-fix-flaky-tests-2', << pipeline.git.branch >> ] - matches: pattern: "-release$" value: << pipeline.git.branch >> @@ -65,6 +67,7 @@ windowsWorkflowFilters: &windows-workflow-filters - equal: [ develop, << pipeline.git.branch >> ] - equal: [ linux-arm64, << pipeline.git.branch >> ] - equal: [ 'marktnoonan/windows-path-fix', << pipeline.git.branch >> ] + - equal: [ 'skip-or-fix-flaky-tests-2', << pipeline.git.branch >> ] - matches: pattern: "-release$" value: << pipeline.git.branch >> diff --git a/npm/cypress-schematic/src/schematics/ng-generate/e2e/index.spec.ts b/npm/cypress-schematic/src/schematics/ng-generate/e2e/index.spec.ts index d7b50b924f35..25acd6deb786 100644 --- a/npm/cypress-schematic/src/schematics/ng-generate/e2e/index.spec.ts +++ b/npm/cypress-schematic/src/schematics/ng-generate/e2e/index.spec.ts @@ -30,7 +30,7 @@ describe('@cypress/schematic:e2e ng-generate', () => { appTree = await schematicRunner.runExternalSchematicAsync('@schematics/angular', 'application', appOptions, appTree).toPromise() }) - it('should create cypress spec file', async () => { + it('should create cypress spec file', () => { return schematicRunner.runSchematicAsync('e2e', { name: 'foo', project: 'sandbox' }, appTree).toPromise().then((tree) => { const files = tree.files diff --git a/npm/vite-dev-server/.percy.yml b/npm/vite-dev-server/.percy.yml index b4289dae89f8..aebc136943bc 100644 --- a/npm/vite-dev-server/.percy.yml +++ b/npm/vite-dev-server/.percy.yml @@ -4,4 +4,4 @@ snapshot: - 1280 min-height: 1024 discovery: - network-idle-timeout: 1000 + network-idle-timeout: 750 diff --git a/npm/webpack-dev-server/.percy.yml b/npm/webpack-dev-server/.percy.yml index b4289dae89f8..aebc136943bc 100644 --- a/npm/webpack-dev-server/.percy.yml +++ b/npm/webpack-dev-server/.percy.yml @@ -4,4 +4,4 @@ snapshot: - 1280 min-height: 1024 discovery: - network-idle-timeout: 1000 + network-idle-timeout: 750 diff --git a/npm/webpack-dev-server/cypress/e2e/angular.cy.ts b/npm/webpack-dev-server/cypress/e2e/angular.cy.ts index 312ac07c8161..052581ed615d 100644 --- a/npm/webpack-dev-server/cypress/e2e/angular.cy.ts +++ b/npm/webpack-dev-server/cypress/e2e/angular.cy.ts @@ -55,7 +55,8 @@ for (const project of WEBPACK_REACT) { cy.get('.passed > .num').should('contain', 1) }) - it('should detect new spec', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23455 + it.skip('should detect new spec', () => { cy.visitApp() cy.withCtx(async (ctx) => { diff --git a/npm/webpack-dev-server/cypress/e2e/next.cy.ts b/npm/webpack-dev-server/cypress/e2e/next.cy.ts index 870ab0863cc3..adaba83d0958 100644 --- a/npm/webpack-dev-server/cypress/e2e/next.cy.ts +++ b/npm/webpack-dev-server/cypress/e2e/next.cy.ts @@ -55,7 +55,8 @@ for (const project of WEBPACK_REACT) { cy.get('.passed > .num').should('contain', 1) }) - it('should detect new spec', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23417 + it.skip('should detect new spec', () => { cy.visitApp() cy.withCtx(async (ctx) => { @@ -73,7 +74,8 @@ for (const project of WEBPACK_REACT) { cy.get('.passed > .num').should('contain', 1) }) - it('should allow import of global styles in support file', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23417 + it.skip('should allow import of global styles in support file', () => { cy.visitApp() cy.contains('styles.cy.js').click() cy.waitForSpecToFinish() diff --git a/npm/webpack-dev-server/cypress/e2e/nuxt.cy.ts b/npm/webpack-dev-server/cypress/e2e/nuxt.cy.ts index 10f77d4c9bec..2092253d0fd0 100644 --- a/npm/webpack-dev-server/cypress/e2e/nuxt.cy.ts +++ b/npm/webpack-dev-server/cypress/e2e/nuxt.cy.ts @@ -49,7 +49,8 @@ for (const project of PROJECTS) { cy.get('.passed > .num').should('contain', 1) }) - it('should detect new spec', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23455 + it.skip('should detect new spec', () => { cy.visitApp() cy.withCtx(async (ctx) => { diff --git a/packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts b/packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts index c657da01ae69..c4a1da589e05 100644 --- a/packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts +++ b/packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts @@ -110,7 +110,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout: .its('href') .should('eq', 'http://localhost:4455/__/#/specs') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 // should clear after reload cy.reload() @@ -172,7 +172,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout: // We could consider removing this after percy is // up and running for e2e tests. - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) it('should show visit failure blank page', () => { @@ -181,7 +181,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout: .click() cy.get('[data-model-state="failed"]').should('contain', 'renders the blank page') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) it('set the correct viewport values from CLI', () => { diff --git a/packages/app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts b/packages/app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts index 28586433bc90..b9f3a4130a00 100644 --- a/packages/app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts +++ b/packages/app/cypress/e2e/cypress-in-cypress-run-mode.cy.ts @@ -30,7 +30,7 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => { cy.contains('Chrome 1').click() cy.contains('Firefox').should('not.exist') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23306 @@ -61,7 +61,7 @@ describe('Cypress In Cypress - run mode', { viewportWidth: 1200 }, () => { cy.contains('Chrome 1').click() cy.contains('Firefox').should('not.exist') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) it('hides reporter when NO_COMMAND_LOG is set in run mode', () => { diff --git a/packages/app/cypress/e2e/cypress-in-cypress.cy.ts b/packages/app/cypress/e2e/cypress-in-cypress.cy.ts index d02745f839d6..1c3cb50838e4 100644 --- a/packages/app/cypress/e2e/cypress-in-cypress.cy.ts +++ b/packages/app/cypress/e2e/cypress-in-cypress.cy.ts @@ -41,7 +41,7 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100 expect(ctx.actions.project.launchProject).to.have.been.called }) - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) it(`handles automation missing in ${testingType}`, () => { @@ -74,11 +74,11 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100 cy.contains('h3', 'The Cypress extension is missing') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.get('[data-cy="select-browser"]').click() - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.withCtx((ctx, { sinon }) => { sinon.stub(ctx.actions.project, 'launchProject').resolves() @@ -92,7 +92,8 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100 }) }) - it(`scales the AUT correctly in ${testingType}`, () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23307 + it.skip(`scales the AUT correctly in ${testingType}`, () => { const assertNoScaleShown = () => { // check that no message about scale % is shown, // meaning the AUT is at 100% scale @@ -117,7 +118,7 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100 // validate that the width we set in `withCtx` above is the starting point cy.get(`[data-cy="reporter-panel"]`).invoke('outerWidth').should('eq', 800) - cy.percySnapshot('initial state') + // cy.percySnapshot('initial state') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs') .click({ force: true }) @@ -152,7 +153,10 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100 assertNoScaleShown() } - cy.percySnapshot(`panel 2 at ${ position } px`) + /* + TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 + cy.percySnapshot(`panel 2 at ${ position } px`) + */ }) }) @@ -171,11 +175,11 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100 cy.contains('Expand Specs List') assertNoScaleShown() - cy.percySnapshot('tall viewport') + // cy.percySnapshot('tall viewport') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.viewport(1500, 400) cy.contains(testingTypeExpectedScales[`${ testingType }ShortViewport`]).should('be.visible') - cy.percySnapshot('short viewport') + // cy.percySnapshot('short viewport') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) cy.get('[data-cy="select-browser"]').as('selectBrowser') diff --git a/packages/app/cypress/e2e/runner/sessions.ui.cy.ts b/packages/app/cypress/e2e/runner/sessions.ui.cy.ts index 329d5c48e4dc..a50a8d6486b4 100644 --- a/packages/app/cypress/e2e/runner/sessions.ui.cy.ts +++ b/packages/app/cypress/e2e/runner/sessions.ui.cy.ts @@ -56,7 +56,7 @@ describe('runner/cypress sessions.ui.spec', { validateSetupSessionGroup() }) - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.get('.command-name-session').eq(0).get('.command-expander').first().click() cy.get('.command').should('have.length', 2) @@ -91,7 +91,7 @@ describe('runner/cypress sessions.ui.spec', { .contains('runValidation') }) - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.get('.command-name-session').eq(0).get('.command-expander').first().click() @@ -128,7 +128,7 @@ describe('runner/cypress sessions.ui.spec', { cy.contains('CypressError') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) describe('restores saved session', () => { @@ -246,7 +246,8 @@ describe('runner/cypress sessions.ui.spec', { .find('.command-alias') .contains('runValidation') }) - .percySnapshot() + + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.get('.runnable-err').should('have.length', 1) @@ -309,7 +310,7 @@ describe('runner/cypress sessions.ui.spec', { .find('.command-alias') .contains('runValidation') }) - .percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.get('.runnable-err').should('have.length', 2) }) @@ -323,7 +324,7 @@ describe('runner/cypress sessions.ui.spec', { }) validateSessionsInstrumentPanel(['user1', 'user2']) - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) }) diff --git a/packages/app/cypress/e2e/runner/support/snapshot-reporter.ts b/packages/app/cypress/e2e/runner/support/snapshot-reporter.ts index b3dcca09aa51..4aa85c3c83f1 100644 --- a/packages/app/cypress/e2e/runner/support/snapshot-reporter.ts +++ b/packages/app/cypress/e2e/runner/support/snapshot-reporter.ts @@ -1,4 +1,4 @@ -// Takes percy snapshot with navigation/AUT hidden and run duration mocked +// Takes percy snapshot with navigation/AUT/reporter hidden export const snapshotReporter = () => { cy.percySnapshot({ width: 450, diff --git a/packages/app/cypress/e2e/runs.cy.ts b/packages/app/cypress/e2e/runs.cy.ts index b4a0d8050a23..e5c9aac554b2 100644 --- a/packages/app/cypress/e2e/runs.cy.ts +++ b/packages/app/cypress/e2e/runs.cy.ts @@ -658,7 +658,7 @@ describe('App: Runs', { viewportWidth: 1200 }, () => { moveToRunsPage() cy.contains('h2', 'Cannot connect to the Cypress Dashboard') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.remoteGraphQLIntercept((obj) => { if (obj.operationName === 'Runs_currentProject_cloudProject_cloudProjectBySlug') { diff --git a/packages/app/cypress/e2e/settings.cy.ts b/packages/app/cypress/e2e/settings.cy.ts index 82352d7ebc2f..6c36b4425b73 100644 --- a/packages/app/cypress/e2e/settings.cy.ts +++ b/packages/app/cypress/e2e/settings.cy.ts @@ -438,7 +438,7 @@ describe('App: Settings without cloud', () => { cy.contains(`channel: 'stable',`) cy.contains(`displayName: 'Chrome',`) - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) }) }) diff --git a/packages/app/cypress/e2e/sidebar_navigation.cy.ts b/packages/app/cypress/e2e/sidebar_navigation.cy.ts index 5746ec90fcb1..b0d195d723b2 100644 --- a/packages/app/cypress/e2e/sidebar_navigation.cy.ts +++ b/packages/app/cypress/e2e/sidebar_navigation.cy.ts @@ -77,7 +77,7 @@ describe('Sidebar Navigation', { viewportWidth: 1280 }, () => { it('expands the left nav bar by default', () => { cy.findByTestId('sidebar').should('have.css', 'width', '248px') // assert width to ensure transition has finished - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) it('highlights indicator on hover showing you can click to expand', () => { @@ -87,14 +87,15 @@ describe('Sidebar Navigation', { viewportWidth: 1280 }, () => { cy.findByTestId('toggle-sidebar').realHover() cy.get(navIndicatorSelector).should('be.visible') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) it('closes the left nav bar when clicking the expand button (if expanded)', () => { cy.findByTestId('sidebar').contains('todos').should('be.visible') cy.findByTestId('toggle-sidebar').click() cy.findByTestId('sidebar').contains('todos').should('not.be.visible') - cy.percySnapshot() + + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) it('closes the left nav bar when clicking the expand button and persist the state if browser is refreshed', () => { @@ -107,7 +108,7 @@ describe('Sidebar Navigation', { viewportWidth: 1280 }, () => { cy.findByTestId('sidebar').contains('todos').should('not.be.visible') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 }) it('has menu item that shows the keyboard shortcuts modal (unexpanded state)', () => { @@ -123,7 +124,7 @@ describe('Sidebar Navigation', { viewportWidth: 1280 }, () => { cy.get('li span').contains('s') cy.get('li span').contains('f') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.get('[aria-label="Close"]').click() cy.findAllByTestId('keyboard-modal').should('not.exist') }) @@ -134,7 +135,7 @@ describe('Sidebar Navigation', { viewportWidth: 1280 }, () => { cy.findByTestId('sidebar-header').trigger('mouseenter') cy.contains('.v-popper--some-open--tooltip', 'todos') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.findByTestId('sidebar-header').trigger('mouseout') cy.findByTestId('sidebar-link-runs-page').trigger('mouseenter') @@ -243,7 +244,7 @@ describe('Sidebar Navigation', { viewportWidth: 1280 }, () => { cy.findAllByTestId('spec-item').first().click() cy.location('hash').should('contain', '#/specs/runner') cy.contains('.router-link-exact-active', 'Specs').should('not.exist') - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.findByTestId('sidebar-link-specs-page').click() cy.location('hash').should('equal', '#/specs') diff --git a/packages/app/cypress/e2e/specs.cy.ts b/packages/app/cypress/e2e/specs.cy.ts index 33397bbbd222..4838370b028a 100644 --- a/packages/app/cypress/e2e/specs.cy.ts +++ b/packages/app/cypress/e2e/specs.cy.ts @@ -120,7 +120,7 @@ describe('App: Specs', () => { })).to.have.lengthOf(options.expectedScaffoldPathsForPlatform.length) }, { expectedScaffoldPathsForPlatform }) - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 // Dismisses dialog with close button press cy.get('@CloseDialogButton').click() @@ -163,7 +163,7 @@ describe('App: Specs', () => { cy.get('[data-cy="card"]').contains(defaultMessages.createSpec.e2e.importEmptySpec.header).click() }) - cy.percySnapshot('Default') + // cy.percySnapshot('Default') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.findAllByLabelText(defaultMessages.createSpec.e2e.importEmptySpec.inputPlaceholder) .as('enterSpecInput') @@ -178,7 +178,7 @@ describe('App: Specs', () => { cy.contains(defaultMessages.createSpec.e2e.importEmptySpec.invalidSpecWarning) cy.contains('button', defaultMessages.createSpec.createSpec).should('be.disabled') - cy.percySnapshot('Invalid spec error') + // cy.percySnapshot('Invalid spec error') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 // Create spec cy.get('@enterSpecInput').clear().type(getPathForPlatform('cypress/e2e/MyTest.cy.js')) @@ -189,7 +189,7 @@ describe('App: Specs', () => { cy.get('pre').should('contain', 'describe(\'empty spec\'') - cy.percySnapshot('Generator success') + // cy.percySnapshot('Generator success') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.get('[aria-label="Close"]').click() @@ -272,7 +272,7 @@ describe('App: Specs', () => { cy.get('[data-cy="card"]').contains(defaultMessages.createSpec.e2e.importEmptySpec.header).click() }) - cy.percySnapshot('Default') + // cy.percySnapshot('Default') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.findAllByLabelText(defaultMessages.createSpec.e2e.importEmptySpec.inputPlaceholder) .as('enterSpecInput') @@ -287,7 +287,7 @@ describe('App: Specs', () => { cy.contains(defaultMessages.createSpec.e2e.importEmptySpec.invalidSpecWarning) cy.contains('button', defaultMessages.createSpec.createSpec).should('be.disabled') - cy.percySnapshot('Invalid spec error') + // cy.percySnapshot('Invalid spec error') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 // Create spec cy.get('@enterSpecInput').clear().type(getPathForPlatform('cypress/e2e/MyTest.cy.ts')) @@ -296,7 +296,7 @@ describe('App: Specs', () => { cy.get('[data-cy="file-row"]').contains(getPathForPlatform('cypress/e2e/MyTest.cy.ts')).click() - cy.percySnapshot('Generator success') + // cy.percySnapshot('Generator success') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.get('pre').should('contain', 'describe(\'empty spec\'') @@ -423,7 +423,7 @@ describe('App: Specs', () => { cy.contains(defaultMessages.createSpec.e2e.importEmptySpec.invalidSpecWarning) cy.contains('button', defaultMessages.createSpec.createSpec).should('be.disabled') - cy.percySnapshot('Invalid spec error') + // cy.percySnapshot('Invalid spec error') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 // Create spec cy.get('@enterSpecInput').clear().type(getPathForPlatform('src/MyTest.cy.js')) @@ -434,7 +434,7 @@ describe('App: Specs', () => { cy.get('pre').should('contain', 'describe(\'empty spec\'') - cy.percySnapshot('Generator success') + // cy.percySnapshot('Generator success') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.get('[aria-label="Close"]').click() @@ -492,7 +492,8 @@ describe('App: Specs', () => { cy.get('@enterSpecInput').clear().type(getPathForPlatform('src/e2e/MyTest.spec.jsx')) cy.contains(defaultMessages.createSpec.e2e.importEmptySpec.specExtensionWarning) - cy.percySnapshot('Non-recommended spec pattern warning') + // cy.percySnapshot('Non-recommended spec pattern warning') // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 + cy.contains('span', '{filename}.cy.jsx') }) }) diff --git a/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts b/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts index c1a0e13861ab..0e5fbf617b77 100644 --- a/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts +++ b/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts @@ -621,7 +621,8 @@ describe('App/Cloud Integration - Latest runs and Average duration', { viewportW allVisibleSpecsShouldBePlaceholders() }) - it('shows offline alert then hides it after coming online', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23419 + it.skip('shows offline alert then hides it after coming online', () => { cy.findByTestId('offline-alert') .should('contain.text', defaultMessages.specPage.offlineWarning.title) .and('contain.text', defaultMessages.specPage.offlineWarning.explainer) diff --git a/packages/app/cypress/e2e/specs_list_no_git_repo.cy.ts b/packages/app/cypress/e2e/specs_list_no_git_repo.cy.ts index 3f30ddeddbe1..24311a6ebcc4 100644 --- a/packages/app/cypress/e2e/specs_list_no_git_repo.cy.ts +++ b/packages/app/cypress/e2e/specs_list_no_git_repo.cy.ts @@ -6,7 +6,8 @@ describe('Spec List - Last updated with no git info', () => { cy.visitApp() }) - it('shows no icon and file system timestamp for files', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23474 + it.skip('shows no icon and file system timestamp for files', () => { cy.get('[data-cy-row="blank-contents.spec.js"] [data-cy="git-info-row"] svg') .should('not.exist') diff --git a/packages/app/cypress/e2e/top-nav.cy.ts b/packages/app/cypress/e2e/top-nav.cy.ts index b8a94ff7d142..f52bf0bf2ad9 100644 --- a/packages/app/cypress/e2e/top-nav.cy.ts +++ b/packages/app/cypress/e2e/top-nav.cy.ts @@ -547,7 +547,7 @@ describe('App Top Nav Workflows', () => { cy.contains('button', loginText.actionCancel).should('be.visible') }) - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.withCtx((ctx) => { (ctx._apis.authApi.logIn as SinonStub).callsFake(async (onMessage) => { @@ -594,7 +594,7 @@ describe('App Top Nav Workflows', () => { cy.contains('An unexpected error occurred').should('be.visible') }) - cy.percySnapshot() + // cy.percySnapshot() // TODO: restore when Percy CSS is fixed. See https://github.com/cypress-io/cypress/issues/23435 cy.findByRole('dialog', { name: loginText.titleFailed }).within(() => { cy.contains('button', loginText.actionTryAgain).should('be.visible') diff --git a/packages/app/src/navigation/SidebarNavigation.cy.tsx b/packages/app/src/navigation/SidebarNavigation.cy.tsx index 7b914f19e5d5..b7d21dc6dd92 100644 --- a/packages/app/src/navigation/SidebarNavigation.cy.tsx +++ b/packages/app/src/navigation/SidebarNavigation.cy.tsx @@ -27,7 +27,7 @@ describe('SidebarNavigation', () => { }) cy.findByText('test-project').should('be.visible') - + cy.findByTestId('sidebar-link-specs-page').should('have.class', 'router-link-active') // assert active link to prevent percy flake cy.percySnapshot() }) diff --git a/packages/app/src/runner/screenshot/screenshot.cy.tsx b/packages/app/src/runner/screenshot/screenshot.cy.tsx index 150f6afd7854..6a4f9fc9d456 100644 --- a/packages/app/src/runner/screenshot/screenshot.cy.tsx +++ b/packages/app/src/runner/screenshot/screenshot.cy.tsx @@ -53,6 +53,11 @@ function removeGlobalStyles () { describe('screenshot', () => { captureTypes.forEach((capture) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23424 + if (capture === 'runner') { + return + } + it(`takes a standard screenshot with viewport: ${capture}`, () => { cy.viewport(500, 500) mount(() => , { diff --git a/packages/app/src/runner/selector-playground/SelectorPlayground.cy.tsx b/packages/app/src/runner/selector-playground/SelectorPlayground.cy.tsx index b8d6afb772a9..854d1d976bb1 100644 --- a/packages/app/src/runner/selector-playground/SelectorPlayground.cy.tsx +++ b/packages/app/src/runner/selector-playground/SelectorPlayground.cy.tsx @@ -44,7 +44,10 @@ describe('SelectorPlayground', () => { cy.get('[data-cy="playground-toggle"]').click().then(() => { expect(selectorPlaygroundStore.isEnabled).to.be.true expect(autIframe.toggleSelectorPlayground).to.have.been.called - cy.percySnapshot('toggle-enabled') + /* + TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23436 + cy.percySnapshot('toggle-enabled') + */ }) }) @@ -112,10 +115,15 @@ describe('SelectorPlayground', () => { cy.get('[data-cy="playground-copy"]').trigger('mouseenter') cy.get('[data-cy="selector-playground-tooltip"]').should('be.visible').contains('Copy to clipboard') - cy.percySnapshot('Copy to clipboard hover tooltip') + + // TODO: fix flaky snapshot https://github.com/cypress-io/cypress/issues/23436 + // cy.percySnapshot('Copy to clipboard hover tooltip') + cy.get('[data-cy="playground-copy"]').click() cy.get('[data-cy="selector-playground-tooltip"]').should('be.visible').contains('Copied!') - cy.percySnapshot('Copy to clipboard click tooltip') + + // TODO: fix flaky snapshot https://github.com/cypress-io/cypress/issues/23436 + // cy.percySnapshot('Copy to clipboard click tooltip') cy.wrap(copyStub).should('have.been.calledWith', 'cy.get(\'.foo-bar\')') }) @@ -130,12 +138,18 @@ describe('SelectorPlayground', () => { cy.get('[data-cy="playground-print"]').trigger('mouseenter') cy.get('[data-cy="selector-playground-tooltip"]').should('be.visible').contains('Print to console') - cy.percySnapshot('Print to console hover tooltip') + + /* + TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23436 + cy.percySnapshot('Print to console hover tooltip') + */ cy.get('[data-cy="playground-print"]').click() cy.get('[data-cy="selector-playground-tooltip"]').should('be.visible').contains('Printed!') - cy.percySnapshot('Print to console click tooltip') - + /* + TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23436 + cy.percySnapshot('Print to console click tooltip') + */ cy.then(() => { expect(logger.logFormatted).to.have.been.calledWith({ Command: `cy.get('.foo-bar')`, diff --git a/packages/app/src/specs/LastUpdatedHeader.cy.tsx b/packages/app/src/specs/LastUpdatedHeader.cy.tsx index d63cee0deddc..93b9fd8071be 100644 --- a/packages/app/src/specs/LastUpdatedHeader.cy.tsx +++ b/packages/app/src/specs/LastUpdatedHeader.cy.tsx @@ -19,7 +19,9 @@ describe('', () => { cy.get(popperContentSelector).should('have.text', expectedTooltipText) - cy.percySnapshot() + /* TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23436 + cy.percySnapshot() + */ }) it('mounts correctly with git unavailable', () => { diff --git a/packages/app/src/specs/SpecListGitInfo.cy.tsx b/packages/app/src/specs/SpecListGitInfo.cy.tsx index f448d46f730b..49480d470729 100644 --- a/packages/app/src/specs/SpecListGitInfo.cy.tsx +++ b/packages/app/src/specs/SpecListGitInfo.cy.tsx @@ -34,7 +34,10 @@ describe('SpecListGitInfo', () => { cy.findByTestId('git-info-tooltip').should('be.visible') .and('have.text', 'Created') - cy.percySnapshot() + /* + TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23436 + cy.percySnapshot() + */ }) }) @@ -53,8 +56,10 @@ describe('SpecListGitInfo', () => { cy.get('.v-popper').trigger('mouseenter') cy.findByTestId('git-info-tooltip').should('be.visible') .and('have.text', 'Modified') - - cy.percySnapshot() + /* + TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23436 + cy.percySnapshot() + */ }) }) @@ -75,7 +80,10 @@ describe('SpecListGitInfo', () => { .and('contain', 'chore: did stuff') .and('contain', 'abc123 by Bob') - cy.percySnapshot() + /* + TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23436 + cy.percySnapshot() + */ }) }) }) diff --git a/packages/driver/cypress/e2e/commands/actions/check.cy.js b/packages/driver/cypress/e2e/commands/actions/check.cy.js index 66d4cc46631b..49a37886a623 100644 --- a/packages/driver/cypress/e2e/commands/actions/check.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/check.cy.js @@ -903,16 +903,19 @@ describe('src/cy/commands/actions/check', () => { }) }) - it('can forcibly click even when being covered by another element', (done) => { + it('can forcibly click even when being covered by another element', () => { + let clicked = false const checkbox = $('').attr('id', 'checkbox-covered-in-span').prop('checked', true).prependTo($('body')) $('span on checkbox').css({ position: 'absolute', left: checkbox.offset().left, top: checkbox.offset().top, padding: 5, display: 'inline-block', backgroundColor: 'yellow' }).prependTo($('body')) checkbox.on('click', () => { - done() + clicked = true }) - cy.get('#checkbox-covered-in-span').uncheck({ force: true }) + cy.get('#checkbox-covered-in-span').uncheck({ force: true }).then(() => { + expect(clicked).to.be.true + }) }) it('passes timeout and interval down to click', (done) => { diff --git a/packages/driver/cypress/e2e/commands/actions/select.cy.js b/packages/driver/cypress/e2e/commands/actions/select.cy.js index 956ab67d2194..f0ed01b70247 100644 --- a/packages/driver/cypress/e2e/commands/actions/select.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/select.cy.js @@ -146,17 +146,19 @@ describe('src/cy/commands/actions/select', () => { cy.get('#select-maps').select('de_train') }) - // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23156 - it.skip('can forcibly click even when being covered by another element', (done) => { + it('can forcibly click even when being covered by another element', () => { + let clicked = false const select = $('').attr('id', 'select-covered-in-span').prependTo(cy.$$('body')) $('span on select').css({ position: 'absolute', left: select.offset().left, top: select.offset().top, padding: 5, display: 'inline-block', backgroundColor: 'yellow' }).prependTo(cy.$$('body')) select.on('click', () => { - done() + clicked = true }) - cy.get('#select-covered-in-span').select('foo', { force: true }) + cy.get('#select-covered-in-span').select('foo', { force: true }).then(() => { + expect(clicked).to.be.true + }) }) it('passes timeout and interval down to click', (done) => { @@ -174,15 +176,18 @@ describe('src/cy/commands/actions/select', () => { cy.get('#select-covered-in-span').select('foobar', { timeout: 1000, interval: 60 }) }) - // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23157 - it.skip('can forcibly click even when element is invisible', (done) => { + it('can forcibly click even when element is invisible', () => { + let clicked = false + const select = cy.$$('#select-maps').hide() select.click(() => { - done() + clicked = true }) - cy.get('#select-maps').select('de_dust2', { force: true }) + cy.get('#select-maps').select('de_dust2', { force: true }).then(() => { + expect(clicked).to.be.true + }) }) it('can forcibly click when select is disabled', () => { diff --git a/packages/driver/cypress/e2e/commands/command_option_immutability.cy.js b/packages/driver/cypress/e2e/commands/command_option_immutability.cy.js index 18d0728186a3..99e1f5e9d2d9 100644 --- a/packages/driver/cypress/e2e/commands/command_option_immutability.cy.js +++ b/packages/driver/cypress/e2e/commands/command_option_immutability.cy.js @@ -233,9 +233,10 @@ describe('command log', () => { // Ignore cy.server() because it doesn't log to reporter. - testOptions('setCookie', { httpOnly: true }, 0, (options) => { - cy.setCookie('auth_key', '123key', options) - }) + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + // testOptions('setCookie', { httpOnly: true }, 0, (options) => { + // cy.setCookie('auth_key', '123key', options) + // }) // Ignore cy.should() because it doesn't have options. diff --git a/packages/driver/cypress/e2e/commands/cookies.cy.js b/packages/driver/cypress/e2e/commands/cookies.cy.js index eb4c3a40642a..b739a8a7af8b 100644 --- a/packages/driver/cypress/e2e/commands/cookies.cy.js +++ b/packages/driver/cypress/e2e/commands/cookies.cy.js @@ -435,7 +435,8 @@ describe('src/cy/commands/cookies', () => { }) }) - context('#setCookie', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + context.skip('#setCookie', () => { beforeEach(() => { cy.stub(Cypress.utils, 'addTwentyYears').returns(12345) }) @@ -509,7 +510,8 @@ describe('src/cy/commands/cookies', () => { }) describe('timeout', () => { - it('sets timeout to Cypress.config(responseTimeout)', { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + it.skip('sets timeout to Cypress.config(responseTimeout)', { responseTimeout: 2500, }, () => { Cypress.automation.resolves(null) @@ -521,7 +523,8 @@ describe('src/cy/commands/cookies', () => { }) }) - it('can override timeout', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + it.skip('can override timeout', () => { Cypress.automation.resolves(null) const timeout = cy.spy(Promise.prototype, 'timeout') @@ -531,7 +534,8 @@ describe('src/cy/commands/cookies', () => { }) }) - it('clears the current timeout and restores after success', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + it.skip('clears the current timeout and restores after success', () => { Cypress.automation.resolves(null) cy.timeout(100) @@ -563,7 +567,8 @@ describe('src/cy/commands/cookies', () => { return null }) - it('logs once on error', function (done) { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + it.skip('logs once on error', function (done) { const error = new Error('some err message') error.name = 'foo' @@ -583,7 +588,8 @@ describe('src/cy/commands/cookies', () => { cy.setCookie('foo', 'bar') }) - it('throws after timing out', function (done) { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + it.skip('throws after timing out', function (done) { Cypress.automation.resolves(Promise.delay(1000)) cy.on('fail', (err) => { diff --git a/packages/driver/cypress/e2e/commands/navigation.cy.js b/packages/driver/cypress/e2e/commands/navigation.cy.js index f1da6de4a875..fdcd033a66dc 100644 --- a/packages/driver/cypress/e2e/commands/navigation.cy.js +++ b/packages/driver/cypress/e2e/commands/navigation.cy.js @@ -271,7 +271,8 @@ describe('src/cy/commands/navigation', () => { }) }) - context('#go', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23308 + context.skip('#go', () => { // TODO: fix this it('sets timeout to Cypress.config(pageLoadTimeout)', { pageLoadTimeout: 4567, @@ -735,7 +736,8 @@ describe('src/cy/commands/navigation', () => { }) // https://github.com/cypress-io/cypress/issues/14445 - it('should eventually fail on assertion despite redirects', (done) => { + // TODO: skip flaky test https://github.com/cypress-io/cypress/issues/23472 + it.skip('should eventually fail on assertion despite redirects', (done) => { cy.on('fail', (err) => { expect(err.message).to.contain('The application redirected to') diff --git a/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts b/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts index 287e38e343b0..ccea3125e0e2 100644 --- a/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts +++ b/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts @@ -20,7 +20,8 @@ const uniqueRoute = (route) => { return `${route}-${routeCount}` } -describe('network stubbing', function () { +// TODO: fix flaky tests https://github.com/cypress-io/cypress/issues/23434 +describe.skip('network stubbing', function () { const { $, _, sinon, state, Promise } = Cypress beforeEach(function () { @@ -1636,7 +1637,8 @@ describe('network stubbing', function () { }) }) - it('can add a body to a request that does not have one', function () { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23422 + it.skip('can add a body to a request that does not have one', function () { const body = '{"foo":"bar"}' cy.intercept('/post-only', function (req) { @@ -1692,7 +1694,8 @@ describe('network stubbing', function () { }) }) - it('can delay with deprecated delayMs param', function () { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23404 + it.skip('can delay with deprecated delayMs param', function () { const delayMs = 250 cy.intercept('/timeout*', (req) => { @@ -1709,7 +1712,8 @@ describe('network stubbing', function () { }) // @see https://github.com/cypress-io/cypress/issues/14446 - it('should delay the same amount on every response', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23406 + it.skip('should delay the same amount on every response', () => { const delay = 250 const testDelay = () => { @@ -1817,7 +1821,8 @@ describe('network stubbing', function () { cy.wait('@getUrl') }) - it('by doing both', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23407 + it.skip('by doing both', () => { cy.intercept({ url: '/users*' }, (req) => { req.query = { a: 'b', @@ -1839,7 +1844,8 @@ describe('network stubbing', function () { cy.wait('@getUrl') }) - it('by deleting query member', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23414 + it.skip('by deleting query member', () => { cy.intercept({ url: '/users*' }, (req) => { req.query = { a: 'b', @@ -1862,7 +1868,8 @@ describe('network stubbing', function () { }) context('by setting new url', () => { - it('absolute path', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23415 + it.skip('absolute path', () => { cy.intercept({ url: '/users*' }, (req) => { req.url = 'http://localhost:3500/users?a=b' @@ -1879,7 +1886,8 @@ describe('network stubbing', function () { cy.wait('@getUrl') }) - it('relative path', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23433 + it.skip('relative path', () => { cy.intercept({ url: '/users*' }, (req) => { req.url = '/users?a=b' @@ -1897,7 +1905,8 @@ describe('network stubbing', function () { cy.wait('@getUrl') }) - it('empty string', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23434 + it.skip('empty string', () => { cy.intercept({ url: '/users*' }, (req) => { req.url = '' @@ -1916,7 +1925,8 @@ describe('network stubbing', function () { }) context('throwing errors correctly', () => { - it('defineproperty', (done) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23423 + it.skip('defineproperty', (done) => { cy.on('fail', (err) => { expect(err.message).to.eq('`defineProperty()` is not allowed.') @@ -1944,7 +1954,7 @@ describe('network stubbing', function () { cy.wait('@getUrl') }) - // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23100 + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23147 it.skip('setPrototypeOf', (done) => { cy.on('fail', (err) => { expect(err.message).to.eq('`setPrototypeOf()` is not allowed.') @@ -1974,7 +1984,8 @@ describe('network stubbing', function () { context('request events', function () { context('can end response', () => { for (const eventName of ['before:response', 'response']) { - it(`in \`${eventName}\``, () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23434 + it.skip(`in \`${eventName}\``, () => { const url = uniqueRoute('/foo') const expectBeforeResponse = eventName === 'response' let beforeResponseCalled = false @@ -2184,7 +2195,8 @@ describe('network stubbing', function () { }) context('with `times`', function () { - it('only uses each handler N times', function () { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23434 + it.skip('only uses each handler N times', function () { const url = uniqueRoute('/foo') const third = sinon.stub() diff --git a/packages/driver/cypress/e2e/commands/xhr.cy.js b/packages/driver/cypress/e2e/commands/xhr.cy.js index b05bad7ade44..39efbbd72b08 100644 --- a/packages/driver/cypress/e2e/commands/xhr.cy.js +++ b/packages/driver/cypress/e2e/commands/xhr.cy.js @@ -2385,7 +2385,8 @@ describe('src/cy/commands/xhr', () => { }) }) - describe('{force404: false}', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23245 + describe.skip('{force404: false}', () => { beforeEach(() => { cy .server() diff --git a/packages/driver/cypress/e2e/cypress/proxy-logging.cy.ts b/packages/driver/cypress/e2e/cypress/proxy-logging.cy.ts index a9d810344aa8..0d99501c4d57 100644 --- a/packages/driver/cypress/e2e/cypress/proxy-logging.cy.ts +++ b/packages/driver/cypress/e2e/cypress/proxy-logging.cy.ts @@ -46,7 +46,8 @@ describe('Proxy Logging', () => { } context('request logging', () => { - it('fetch log shows resource type, url, method, and status code and has expected snapshots and consoleProps', (done) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23443 + it.skip('fetch log shows resource type, url, method, and status code and has expected snapshots and consoleProps', (done) => { fetch('/some-url') // trigger: Cypress.Log() called @@ -95,8 +96,7 @@ describe('Proxy Logging', () => { done() } catch (err) { - // eslint-disable-next-line no-console - console.log('assertion error, retrying', err) + done(new Error(err)) } }) }) @@ -133,8 +133,7 @@ describe('Proxy Logging', () => { done() } catch (err) { - // eslint-disable-next-line no-console - console.log('assertion error, retrying', err) + done(new Error(err)) } }) @@ -181,8 +180,7 @@ describe('Proxy Logging', () => { done() } catch (err) { - // eslint-disable-next-line no-console - console.log('assertion error, retrying', err) + done(new Error(err)) } }) @@ -265,7 +263,8 @@ describe('Proxy Logging', () => { .visit('/fixtures/empty.html') }) - it('intercept log has consoleProps with intercept info', (done) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23420 + it.skip('intercept log has consoleProps with intercept info', (done) => { cy.intercept('/some-url', 'stubbed response').as('alias') .then(() => { fetch('/some-url') diff --git a/packages/driver/cypress/e2e/e2e/e2e_cookies.cy.js b/packages/driver/cypress/e2e/e2e/e2e_cookies.cy.js index 6f71522c1aa0..671691caab16 100644 --- a/packages/driver/cypress/e2e/e2e/e2e_cookies.cy.js +++ b/packages/driver/cypress/e2e/e2e/e2e_cookies.cy.js @@ -19,7 +19,8 @@ describe('e2e cookies spec', () => { context('__Host- prefix', () => { // https://github.com/cypress-io/cypress/issues/8261 - it('can set __Host- cookie', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + it.skip('can set __Host- cookie', () => { cy.visit('https://example.com') cy.setCookie('__Host-foobar', 'someval', { domain: 'example.com', @@ -35,7 +36,8 @@ describe('e2e cookies spec', () => { })) }) - it('errors when __Host- cookie and secure:false', (done) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + it.skip('errors when __Host- cookie and secure:false', (done) => { cy.visit('https://example.com') cy.setCookie('__Host-foobar', 'someval') @@ -48,7 +50,8 @@ describe('e2e cookies spec', () => { }) }) - it('errors when __Host- cookie and path', (done) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + it.skip('errors when __Host- cookie and path', (done) => { cy.visit('https://example.com') cy.setCookie('__Host-foobar', 'someval', { secure: true, @@ -63,7 +66,8 @@ describe('e2e cookies spec', () => { }) context('__Secure- prefix', () => { - it('can set __Secure- cookie', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + it.skip('can set __Secure- cookie', () => { cy.visit('https://example.com') cy.setCookie('__Secure-foobar', 'someval', { domain: 'example.com', @@ -79,7 +83,8 @@ describe('e2e cookies spec', () => { })) }) - it('errors when __Secure- cookie secure:false', (done) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23444 + it.skip('errors when __Secure- cookie secure:false', (done) => { cy.visit('https://example.com') cy.setCookie('__Secure-foobar', 'someval', { domain: 'example.com', diff --git a/packages/driver/cypress/e2e/e2e/origin/basic_login.cy.ts b/packages/driver/cypress/e2e/e2e/origin/basic_login.cy.ts index d843a0bb4dc0..a06c7a1a4406 100644 --- a/packages/driver/cypress/e2e/e2e/origin/basic_login.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/basic_login.cy.ts @@ -168,7 +168,8 @@ describe('Multi-step Auth', () => { .should('equal', 'Welcome MarkyMark') }) - it('final-auth redirects back to localhost - flat', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23481 + it.skip('final-auth redirects back to localhost - flat', () => { cy.visit('/fixtures/auth/index.html') cy.get('[data-cy="login-with-approval"]').click() // takes you to foobar.com.../approval cy.origin('http://foobar.com:3500', () => { // Parent origin is localhost diff --git a/packages/driver/cypress/e2e/e2e/origin/commands/actions.cy.ts b/packages/driver/cypress/e2e/e2e/origin/commands/actions.cy.ts index 3ed50a18259d..3d6819a00e74 100644 --- a/packages/driver/cypress/e2e/e2e/origin/commands/actions.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/commands/actions.cy.ts @@ -466,7 +466,8 @@ context('cy.origin actions', () => { }) }) - it('.submit()', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23480 + it.skip('.submit()', () => { cy.get('a[data-cy="dom-link"]').click() cy.origin('http://foobar.com:3500', () => { cy.get('form#multiple-inputs-and-input-submit input[name="fname"]').type('foo') diff --git a/packages/driver/cypress/e2e/e2e/origin/logging.cy.ts b/packages/driver/cypress/e2e/e2e/origin/logging.cy.ts index 3121df5ef22a..0b1887d42771 100644 --- a/packages/driver/cypress/e2e/e2e/origin/logging.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/logging.cy.ts @@ -30,7 +30,8 @@ describe('cy.origin logging', () => { }) }) - it('logs cy.origin as group when failing with validation failure', (done) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/21300 + it.skip('logs cy.origin as group when failing with validation failure', (done) => { const logs: any[] = [] cy.on('log:added', (attrs) => { @@ -58,7 +59,8 @@ describe('cy.origin logging', () => { cy.origin(false, () => {}) }) - it('logs cy.origin as group when failing with serialization failure', (done) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/21300 + it.skip('logs cy.origin as group when failing with serialization failure', (done) => { const logs: any[] = [] cy.on('log:added', (attrs) => { diff --git a/packages/driver/cypress/e2e/e2e/origin/navigation.cy.ts b/packages/driver/cypress/e2e/e2e/origin/navigation.cy.ts index e84fb90e7ee5..9693647e2f6d 100644 --- a/packages/driver/cypress/e2e/e2e/origin/navigation.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/navigation.cy.ts @@ -417,7 +417,8 @@ describe('errors', () => { .should('equal', 'Welcome BJohnson') }) - it('fails in cy.origin when a command is run after we return to localhost', { defaultCommandTimeout: 50 }, (done) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23481 + it.skip('fails in cy.origin when a command is run after we return to localhost', { defaultCommandTimeout: 50 }, (done) => { cy.on('fail', (err) => { expect(err.message).to.include(`Timed out retrying after 50ms: Expected to find element: \`[data-cy="cannot_find"]\`, but never found it`) expect(err.message).to.include(`The command was expected to run against origin \`http://idp.com:3500\` but the application is at origin \`http://localhost:3500\`.`) diff --git a/packages/driver/cypress/e2e/e2e/origin/snapshots.cy.ts b/packages/driver/cypress/e2e/e2e/origin/snapshots.cy.ts index 08af38a0a00e..9510f116e6b8 100644 --- a/packages/driver/cypress/e2e/e2e/origin/snapshots.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/snapshots.cy.ts @@ -48,7 +48,8 @@ describe('cy.origin - snapshots', () => { }) }) - it('verifies fetch requests made while a secondary origin is active eventually update with snapshots of the secondary origin', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23437 + it.skip('verifies fetch requests made while a secondary origin is active eventually update with snapshots of the secondary origin', () => { cy.origin('http://foobar.com:3500', () => { // need to set isInteractive in the spec bridge in order to take xhr snapshots in run mode, similar to how isInteractive is set within support/defaults.js // @ts-ignore diff --git a/packages/driver/cypress/e2e/e2e/origin/uncaught_errors.cy.ts b/packages/driver/cypress/e2e/e2e/origin/uncaught_errors.cy.ts index 1c1827bb0431..379cd991f95c 100644 --- a/packages/driver/cypress/e2e/e2e/origin/uncaught_errors.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/uncaught_errors.cy.ts @@ -247,7 +247,8 @@ describe('cy.origin - uncaught errors', () => { }) }) - it('fails the current test/command if a promise is rejected from the cy.origin callback after it is finished running', (done) => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23484 + it.skip('fails the current test/command if a promise is rejected from the cy.origin callback after it is finished running', (done) => { cy.on('fail', (err) => { expect(err.name).to.eq('Error') expect(err.message).to.include('rejected promise') diff --git a/packages/driver/cypress/e2e/e2e/origin/validation.cy.ts b/packages/driver/cypress/e2e/e2e/origin/validation.cy.ts index da326175f05d..2de82525ca1d 100644 --- a/packages/driver/cypress/e2e/e2e/origin/validation.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/validation.cy.ts @@ -207,7 +207,8 @@ describe('cy.origin', () => { }) }) - it('uses cy.origin twice', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23451 + it.skip('uses cy.origin twice', () => { cy.visit('/fixtures/auth/index.html') cy.get('[data-cy="login-idp"]').click() cy.origin('http://idp.com:3500', () => { diff --git a/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts b/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts index b2cce8cb6688..d9ddffbcf3cd 100644 --- a/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts +++ b/packages/frontend-shared/cypress/e2e/support/e2eSupport.ts @@ -544,6 +544,9 @@ Cypress.Commands.add('validateExternalLink', { prevSubject: ['optional', 'elemen installCustomPercyCommand({ elementOverrides: { + '[data-cy=top-nav-cypress-version-current-link]': ($el) => { + $el.attr('style', 'display: none !important') // TODO: display and set dummy text to vX.X.X once flake is fixed. See issue https://github.com/cypress-io/cypress/issues/21897 + }, '.runnable-header .duration': ($el) => { $el.text('XX:XX') }, diff --git a/packages/frontend-shared/src/gql-components/HeaderBarContent.cy.tsx b/packages/frontend-shared/src/gql-components/HeaderBarContent.cy.tsx index 102115453f64..2695fb0c5817 100644 --- a/packages/frontend-shared/src/gql-components/HeaderBarContent.cy.tsx +++ b/packages/frontend-shared/src/gql-components/HeaderBarContent.cy.tsx @@ -30,7 +30,10 @@ describe('', { viewportWidth: 1000, viewportHeight: 750 }, ( .should('be.visible') .click() - cy.percySnapshot('after browsers open') + /* + TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23436 + cy.percySnapshot('after browsers open') + */ cy.contains('Edge Canary') .should('be.visible') @@ -55,7 +58,10 @@ describe('', { viewportWidth: 1000, viewportHeight: 750 }, ( cy.contains('Unsupported browser').should('be.visible') - cy.percySnapshot('unsupported browser tooltip') + /* + TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23436 + cy.percySnapshot('unsupported browser tooltip') + */ }) describe('breadcrumbs', () => { diff --git a/packages/launchpad/cypress/e2e/choose-a-browser.cy.ts b/packages/launchpad/cypress/e2e/choose-a-browser.cy.ts index 0e8db68f92c7..d2acd567841c 100644 --- a/packages/launchpad/cypress/e2e/choose-a-browser.cy.ts +++ b/packages/launchpad/cypress/e2e/choose-a-browser.cy.ts @@ -1,6 +1,7 @@ import type { FoundBrowser } from '@packages/types/src' -describe('Choose a Browser Page', () => { +// TODO: fix flaky tests https://github.com/cypress-io/cypress/issues/23418 +describe.skip('Choose a Browser Page', () => { beforeEach(() => { cy.scaffoldProject('launchpad') }) @@ -14,7 +15,8 @@ describe('Choose a Browser Page', () => { }) }) - it('preselects browser that is provided through the command line', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23158 + it.skip('preselects browser that is provided through the command line', () => { cy.withCtx((ctx, o) => { // stub launching project since we have `--browser --testingType --project` here o.sinon.stub(ctx._apis.projectApi, 'launchProject').resolves() diff --git a/packages/launchpad/cypress/e2e/config-warning.cy.ts b/packages/launchpad/cypress/e2e/config-warning.cy.ts index 222983059b69..8e5ec9be09a1 100644 --- a/packages/launchpad/cypress/e2e/config-warning.cy.ts +++ b/packages/launchpad/cypress/e2e/config-warning.cy.ts @@ -68,7 +68,8 @@ describe('baseUrl', () => { }) describe('experimentalSingleTabRunMode', () => { - it('is a valid config for component testing', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23158 + it.skip('is a valid config for component testing', () => { cy.scaffoldProject('experimentalSingleTabRunMode') cy.openProject('experimentalSingleTabRunMode') cy.visitLaunchpad() diff --git a/packages/launchpad/cypress/e2e/project-setup.cy.ts b/packages/launchpad/cypress/e2e/project-setup.cy.ts index 44250413f219..597d6af1f3d2 100644 --- a/packages/launchpad/cypress/e2e/project-setup.cy.ts +++ b/packages/launchpad/cypress/e2e/project-setup.cy.ts @@ -568,7 +568,8 @@ describe('Launchpad: Setup Project', () => { cy.get('code').should('contain.text', 'yarn add -D ') }) - it('makes the right command for pnpm', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23153 + it.skip('makes the right command for pnpm', () => { scaffoldAndOpenProject('pristine-pnpm') cy.visitLaunchpad() @@ -655,7 +656,8 @@ describe('Launchpad: Setup Project', () => { verifyScaffoldedFiles('e2e') }) - it('takes the user to first step of ct setup when switching from app', () => { + // TODO: fix flaky tests https://github.com/cypress-io/cypress/issues/23418 + it.skip('takes the user to first step of ct setup when switching from app', () => { scaffoldAndOpenProject('pristine-with-e2e-testing') cy.visitLaunchpad() verifyWelcomePage({ e2eIsConfigured: true, ctIsConfigured: false }) diff --git a/packages/launchpad/cypress/e2e/scaffold-component-testing.cy.ts b/packages/launchpad/cypress/e2e/scaffold-component-testing.cy.ts index e7fccd081b26..4d1682b2bf7c 100644 --- a/packages/launchpad/cypress/e2e/scaffold-component-testing.cy.ts +++ b/packages/launchpad/cypress/e2e/scaffold-component-testing.cy.ts @@ -109,7 +109,8 @@ describe('scaffolding component testing', { }) context('angular-cli-unconfigured', () => { - it('scaffolds component testing for Angular', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23452 + it.skip('scaffolds component testing for Angular', () => { startSetupFor('angular-cli-unconfigured') // should detect correctly diff --git a/packages/launchpad/cypress/e2e/slow-network.cy.ts b/packages/launchpad/cypress/e2e/slow-network.cy.ts index b15e78e8ef42..ed709d17eaf3 100644 --- a/packages/launchpad/cypress/e2e/slow-network.cy.ts +++ b/packages/launchpad/cypress/e2e/slow-network.cy.ts @@ -38,7 +38,8 @@ describe('slow network: launchpad', () => { cy.get('h1').should('contain', 'Choose a Browser') }) - it('shows the versions after they resolve', () => { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/21897 + it.skip('shows the versions after they resolve', () => { cy.visitLaunchpad() cy.get('[data-cy=top-nav-cypress-version-current-link]').should('not.exist') cy.contains('Log In') diff --git a/packages/launchpad/src/setup/OpenBrowserList.cy.tsx b/packages/launchpad/src/setup/OpenBrowserList.cy.tsx index 76c699a47d91..9b7b20bcf3cd 100644 --- a/packages/launchpad/src/setup/OpenBrowserList.cy.tsx +++ b/packages/launchpad/src/setup/OpenBrowserList.cy.tsx @@ -51,7 +51,10 @@ describe('', () => { cy.get('.v-popper__popper--shown') .contains('Cypress does not support running Firefox Developer Edition version 69.') - cy.percySnapshot() + /* + TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23436 + cy.percySnapshot() + */ }) it('emits navigates back', () => { diff --git a/packages/server/test/unit/fixture_spec.js b/packages/server/test/unit/fixture_spec.js index 0205b7d5ea5f..514545e194c3 100644 --- a/packages/server/test/unit/fixture_spec.js +++ b/packages/server/test/unit/fixture_spec.js @@ -153,7 +153,8 @@ Expecting 'EOF', '}', ':', ',', ']', got 'STRING'\ }) }) - it('does not reformat empty objects', function () { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23457 + it.skip('does not reformat empty objects', function () { const fn = () => { return fixture.get(this.fixturesFolder, 'empty_objects') } diff --git a/packages/server/test/unit/open_project_spec.js b/packages/server/test/unit/open_project_spec.js index 931d3d6c3a35..44c9d11fcfb6 100644 --- a/packages/server/test/unit/open_project_spec.js +++ b/packages/server/test/unit/open_project_spec.js @@ -205,7 +205,8 @@ describe('lib/open_project', () => { }) }) - it('sends after:spec errors through onError option', function () { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23448 + it.skip('sends after:spec errors through onError option', function () { const err = new Error('thrown from after:spec handler') this.config.experimentalInteractiveRunEvents = true diff --git a/system-tests/test/plugins_spec.js b/system-tests/test/plugins_spec.js index 1c4128eae59d..4dc5859a08cc 100644 --- a/system-tests/test/plugins_spec.js +++ b/system-tests/test/plugins_spec.js @@ -26,7 +26,8 @@ describe('e2e plugins', function () { }, }) - it('fails when there is an async error inside an event handler', function () { + // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23493 + it.skip('fails when there is an async error inside an event handler', function () { return systemTests.exec(this, { spec: 'app.cy.js', project: 'plugins-async-error', diff --git a/yarn.lock b/yarn.lock index b048b3221dc0..26bbccef00e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35841,4 +35841,4 @@ zone.js@~0.11.4: resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.7.tgz#262194267c7b964e8da77ce16b9fba9bea23cfdc" integrity sha512-e39K2EdK5JfA3FDuUTVRvPlYV4aBfnOOcGuILhQAT7nzeV12uSrLBzImUM9CDVoncDSX4brR/gwqu0heQ3BQ0g== dependencies: - tslib "^2.3.0" + tslib "^2.3.0" \ No newline at end of file From 9ba3ed3b5ab6ad6c114998790ae3ed5502edbb6c Mon Sep 17 00:00:00 2001 From: Blue F Date: Mon, 22 Aug 2022 10:56:27 -0700 Subject: [PATCH 18/45] chore: Refactor assertion logging (#23354) * chore: Refactor assertion logging * Remove duplicate snapshot on command failure; Prevent circular json error when inspecting commands * Fix for 'next' attribute in logs * Add comments about logging and assertions * Fix duplicate logs on not.exist assertions * Move command-merging logic into asserting.ts * Fix TS error * Fix race condition with cross-origin tests * Review updates --- .../cypress/e2e/commands/assertions.cy.js | 26 ++-- packages/driver/src/cy/assertions.ts | 124 ++---------------- packages/driver/src/cy/commands/asserting.ts | 107 ++++++++++++--- packages/driver/src/cy/commands/waiting.ts | 4 +- packages/driver/src/cy/ensures.ts | 23 +--- packages/driver/src/cy/retries.ts | 13 +- packages/driver/src/cypress/cy.ts | 2 +- packages/driver/src/cypress/log.ts | 60 ++++----- 8 files changed, 141 insertions(+), 218 deletions(-) diff --git a/packages/driver/cypress/e2e/commands/assertions.cy.js b/packages/driver/cypress/e2e/commands/assertions.cy.js index f69f28289212..7e6d62e59724 100644 --- a/packages/driver/cypress/e2e/commands/assertions.cy.js +++ b/packages/driver/cypress/e2e/commands/assertions.cy.js @@ -329,11 +329,15 @@ describe('src/cy/commands/assertions', () => { it('resolves eventually not exist', () => { const button = cy.$$('button:first') - cy.on('command:retry', _.after(2, _.once(() => { + cy.on('command:retry', _.after(3, _.once(() => { button.remove() }))) cy.get('button:first').click().should('not.exist') + + cy.then(function () { + assertLogLength(this.logs, 3) + }) }) it('resolves all 3 assertions', (done) => { @@ -715,7 +719,6 @@ describe('src/cy/commands/assertions', () => { it('does not log ensureElExistence errors', function (done) { cy.on('fail', (err) => { assertLogLength(this.logs, 1) - done() }) @@ -790,19 +793,18 @@ describe('src/cy/commands/assertions', () => { cy.noop({}).should('have.property', 'foo') }) - it('ends and snapshots immediately and sets child', (done) => { + it('snapshots immediately and sets child', (done) => { cy.on('log:added', (attrs, log) => { - if (attrs.name === 'assert') { - cy.removeAllListeners('log:added') + if (attrs.name !== 'assert') { + return + } - expect(log.get('ended')).to.be.true - expect(log.get('state')).to.eq('passed') - expect(log.get('snapshots').length).to.eq(1) - expect(log.get('snapshots')[0]).to.be.an('object') - expect(log.get('type')).to.eq('child') + cy.removeAllListeners('log:added') + expect(log.get('snapshots').length).to.eq(1) + expect(log.get('snapshots')[0]).to.be.an('object') + expect(log.get('type')).to.eq('child') - done() - } + done() }) cy.get('body').then(() => { diff --git a/packages/driver/src/cy/assertions.ts b/packages/driver/src/cy/assertions.ts index e2f1f6ab6f4c..1fee4b240db7 100644 --- a/packages/driver/src/cy/assertions.ts +++ b/packages/driver/src/cy/assertions.ts @@ -222,9 +222,11 @@ export const create = (Cypress: ICypress, cy: $Cy) => { return null } - const finishAssertions = (assertions) => { - return _.each(assertions, (log) => { - log.snapshot() + const finishAssertions = () => { + cy.state('current').get('logs').forEach((log) => { + if (log.get('next') || !log.get('snapshots')) { + log.snapshot() + } const e = log.get('_error') @@ -238,7 +240,6 @@ export const create = (Cypress: ICypress, cy: $Cy) => { type VerifyUpcomingAssertionsCallbacks = { ensureExistenceFor?: 'subject' | 'dom' | boolean - onPass?: Function onFail?: (err?, isDefaultAssertionErr?: boolean, cmds?: any[]) => void onRetry?: () => any } @@ -256,10 +257,6 @@ export const create = (Cypress: ICypress, cy: $Cy) => { // case where there are no upcoming assertion commands const isDefaultAssertionErr = cmds.length === 0 - if (options.assertions == null) { - options.assertions = [] - } - _.defaults(callbacks, { ensureExistenceFor: 'dom', }) @@ -296,9 +293,6 @@ export const create = (Cypress: ICypress, cy: $Cy) => { const onPassFn = () => { cy.state('overrideAssert', undefined) - if (_.isFunction(callbacks.onPass)) { - return callbacks.onPass.call(this, cmds, options.assertions) - } return subject } @@ -342,8 +336,9 @@ export const create = (Cypress: ICypress, cy: $Cy) => { onFail.call(this, err, isDefaultAssertionErr, cmds) } } catch (e3) { - finishAssertions(options.assertions) throw e3 + } finally { + finishAssertions() } if (_.isFunction(onRetry)) { @@ -380,108 +375,7 @@ export const create = (Cypress: ICypress, cy: $Cy) => { .catch(onFailFn) } - let i = 0 - - const cmdHasFunctionArg = (cmd) => { - return _.isFunction(cmd.get('args')[0]) - } - const overrideAssert = function (...args) { - let cmd = cmds[i] - const setCommandLog = (log) => { - // our next log may not be an assertion - // due to page events so make sure we wait - // until we see page events - if (log.get('name') !== 'assert') { - return - } - - // when we do immediately unbind this function - cy.state('onBeforeLog', null) - - const insertNewLog = (log) => { - cmd.log(log) - - return options.assertions.push(log) - } - - // its possible a single 'should' will assert multiple - // things such as the case with have.property. we can - // detect when that is happening because cmd will be null. - // if thats the case then just set cmd to be the previous - // cmd and do not increase 'i' - // this will prevent 2 logs from ever showing up but still - // provide errors when the 1st assertion fails. - if (!cmd) { - cmd = cmds[i - 1] - } else { - i += 1 - } - - // if our command has a function argument - // then we know it may contain multiple - // assertions - if (cmdHasFunctionArg(cmd)) { - let index = cmd.get('assertionIndex') - let assertions = cmd.get('assertions') - - // https://github.com/cypress-io/cypress/issues/4981 - // `assertions` is undefined because assertions added by - // `should` command are not handled yet. - // So, don't increase i and go back to the last command. - if (!assertions) { - i -= 1 - cmd = cmds[i - 1] - index = cmd.get('assertionIndex') - assertions = cmd.get('assertions') - } - - // always increase the assertionIndex - // so our next assertion matches up - // to the correct index - const incrementIndex = () => { - return cmd.set('assertionIndex', index += 1) - } - - // if we dont have an assertion at this - // index then insert a new log - const assertion = assertions[index] - - if (!assertion) { - assertions.push(log) - incrementIndex() - - return insertNewLog(log) - } - - // else just merge this log - // into the previous assertion log - incrementIndex() - assertion.merge(log) - - // dont output a new log - return false - } - - // if we already have a log - // then just update its attrs from - // the new log - const l = cmd.getLastLog() - - if (l) { - l.merge(log) - - // and make sure we return false - // which prevents a new log from - // being added - return false - } - - return insertNewLog(log) - } - - cy.state('onBeforeLog', setCommandLog) - // send verify=true as the last arg return assertFn.apply(this, args.concat(true) as any) } @@ -537,7 +431,7 @@ export const create = (Cypress: ICypress, cy: $Cy) => { setSubjectAndSkip() - finishAssertions(options.assertions) + finishAssertions() return onPassFn() }) @@ -547,7 +441,7 @@ export const create = (Cypress: ICypress, cy: $Cy) => { // when we're told not to retry if (err.retry === false) { // finish the assertions - finishAssertions(options.assertions) + finishAssertions() // and then push our command into this err try { diff --git a/packages/driver/src/cy/commands/asserting.ts b/packages/driver/src/cy/commands/asserting.ts index 4f4bc2dfbf5d..cdb37022ec31 100644 --- a/packages/driver/src/cy/commands/asserting.ts +++ b/packages/driver/src/cy/commands/asserting.ts @@ -7,6 +7,29 @@ import $errUtils from '../../cypress/error_utils' const reExistence = /exist/ const reHaveLength = /length/ +const onBeforeLog = (log, command, commandLogId) => { + log.set('commandLogId', commandLogId) + + const previousLogInstance = command.get('logs').find(_.matchesProperty('attributes.commandLogId', commandLogId)) + + if (previousLogInstance) { + // log.merge unsets any keys that aren't set on the new log instance. We + // copy over 'snapshots' beforehand so that existing snapshots aren't lost + // in the merge operation. + log.set('snapshots', previousLogInstance.get('snapshots')) + previousLogInstance.merge(log) + + if (previousLogInstance.get('end')) { + previousLogInstance.end() + } + + // Returning false prevents this new log from being added to the command log + return false + } + + return true +} + export default function (Commands, Cypress, cy, state) { const shouldFnWithCallback = function (subject, fn) { state('current')?.set('followedByShouldCallback', true) @@ -24,8 +47,44 @@ export default function (Commands, Cypress, cy, state) { } const shouldFn = function (subject, chainers, ...args) { + const command = cy.state('current') + + // Most commands are responsible for creating and managing their own log messages directly. + // .should(), however, is an exception - it is invoked by earlier commands, as part of + // `verifyUpcomingAssertions`. This callback can also be invoked any number of times, but we only want + // to display a few log messages (one for each assertion). + + // Therefore, we each time Cypress.log() is called, we need a way to identify if this log call + // a duplicate of a previous one that's just being retried. This is the purpose of `commandLogId` - it should + // remain the same across multiple invocations of verifyUpcomingAssertions(). + + // It is composed of two parts: assertionIndex and logIndex. Assertion index is "which .should() command are we + // inside". Consider the following case: + // `cy.noop(3).should('be.lessThan', 4).should('be.greaterThan', 2)` + // cy.state('current') is always the 'noop' command, which rolls up the two upcoming assertions, lessThan and + // greaterThan. `assertionIndex` lets us tell them apart even though they have the same logIndex of 0 (since it + // resets each time .should() is called). + + // As another case, consider: + // cy.noop(3).should((n) => { expect(n).to.be.lessThan(4); expect(n).to.be.greaterThan(2); }) + // Here, assertionIndex is 0 for both - one .should() block generates two log messages. In this case, logIndex is + // used to tell them apart, since it increments each time Cypress.log() is called within a single retry of a single + // .should(). + const assertionIndex = cy.state('upcomingAssertions') ? cy.state('upcomingAssertions').indexOf(command.get('currentAssertionCommand')) : 0 + let logIndex = 0 + if (_.isFunction(chainers)) { - return shouldFnWithCallback.apply(this, [subject, chainers]) + cy.state('onBeforeLog', (log) => { + logIndex++ + + return onBeforeLog(log, command, `${assertionIndex}-${logIndex}`) + }) + + try { + return shouldFnWithCallback.apply(this, [subject, chainers]) + } finally { + cy.state('onBeforeLog', undefined) + } } let exp = cy.expect(subject).to @@ -35,6 +94,7 @@ export default function (Commands, Cypress, cy, state) { // since we are throwing our own error // without going through the assertion we need // to ensure our .should command gets logged + logIndex++ const log = Cypress.log({ name: 'should', type: 'child', @@ -58,31 +118,40 @@ export default function (Commands, Cypress, cy, state) { const isCheckingLengthOrExistence = isCheckingExistence || reHaveLength.test(chainers) const applyChainer = function (memo, value) { - if (value === lastChainer && !isCheckingExistence) { + logIndex++ + cy.state('onBeforeLog', (log) => { + return onBeforeLog(log, command, `${assertionIndex}-${logIndex}`) + }) + + try { + if (value === lastChainer && !isCheckingExistence) { // https://github.com/cypress-io/cypress/issues/16006 // Referring some commands like 'visible' triggers assert function in chai_jquery.js // It creates duplicated messages and confuses users. - const cmd = memo[value] - - if (_.isFunction(cmd)) { - try { - return cmd.apply(memo, args) - } catch (err: any) { - // if we made it all the way to the actual - // assertion but its set to retry false then - // we need to log out this .should since there - // was a problem with the actual assertion syntax - if (err.retry === false) { - return throwAndLogErr(err) + const cmd = memo[value] + + if (_.isFunction(cmd)) { + try { + return cmd.apply(memo, args) + } catch (err: any) { + // if we made it all the way to the actual + // assertion but its set to retry false then + // we need to log out this .should since there + // was a problem with the actual assertion syntax + if (err.retry === false) { + return throwAndLogErr(err) + } + + throw err } - - throw err + } else { + return cmd } } else { - return cmd + return memo[value] } - } else { - return memo[value] + } finally { + cy.state('onBeforeLog', undefined) } } diff --git a/packages/driver/src/cy/commands/waiting.ts b/packages/driver/src/cy/commands/waiting.ts index b0d19ff0fd56..1c0a4873b2f8 100644 --- a/packages/driver/src/cy/commands/waiting.ts +++ b/packages/driver/src/cy/commands/waiting.ts @@ -300,8 +300,8 @@ export default (Commands, Cypress, cy, state) => { if (responsesOrErr.hasSpecBridgeError) { delete responsesOrErr.hasSpecBridgeError if (options.log) { + // skip this 'wait' log since it was already added through the primary Cypress.state('onBeforeLog', (log) => { - // skip this 'wait' log since it was already added through the primary if (log.get('name') === 'wait') { // unbind this function so we don't impact any other logs cy.state('onBeforeLog', null) @@ -309,7 +309,7 @@ export default (Commands, Cypress, cy, state) => { return false } - return + return true }) } diff --git a/packages/driver/src/cy/ensures.ts b/packages/driver/src/cy/ensures.ts index 481906ae0e22..274da64d40ad 100644 --- a/packages/driver/src/cy/ensures.ts +++ b/packages/driver/src/cy/ensures.ts @@ -14,8 +14,6 @@ const VALID_POSITIONS = 'topLeft top topRight left center right bottomLeft botto // they may need to work with both element arrays, or specific items // such as a single element, a single document, or single window -let returnFalse = () => false - export const create = (state: StateFunc, expect: $Cy['expect']) => { // TODO: we should probably normalize all subjects // into an array and loop through each and verify @@ -246,27 +244,14 @@ export const create = (state: StateFunc, expect: $Cy['expect']) => { } const ensureExistence = (subject) => { - returnFalse = () => { - cleanup() - - return false - } - - const cleanup = () => { - return state('onBeforeLog', null) - } - - // prevent any additional logs this is an implicit assertion - state('onBeforeLog', returnFalse) + // prevent any additional logs since this is an implicit assertion + state('onBeforeLog', () => false) // verify the $el exists and use our default error messages - // TODO: always unbind if our expectation failed try { expect(subject).to.exist - } catch (err) { - cleanup() - - throw err + } finally { + state('onBeforeLog', null) } } diff --git a/packages/driver/src/cy/retries.ts b/packages/driver/src/cy/retries.ts index 94ba98515f82..4f69f473298c 100644 --- a/packages/driver/src/cy/retries.ts +++ b/packages/driver/src/cy/retries.ts @@ -55,18 +55,7 @@ export const create = (Cypress: ICypress, state: StateFunc, timeout: $Cy['timeou // if our total exceeds the timeout OR the total + the interval // exceed the runnables timeout, then bail if ((total + interval) >= options._runnableTimeout) { - // snapshot the DOM since we are bailing - // so the user can see the state we're in - // when we fail - if (log) { - log.snapshot() - } - - const assertions = options.assertions - - if (assertions) { - finishAssertions(assertions) - } + finishAssertions() let onFail diff --git a/packages/driver/src/cypress/cy.ts b/packages/driver/src/cypress/cy.ts index 2c35c26c1f5d..002b7f5455c0 100644 --- a/packages/driver/src/cypress/cy.ts +++ b/packages/driver/src/cypress/cy.ts @@ -1185,7 +1185,7 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert // if this is a number, then we know we're about to insert this // into our commands and need to reset next + increment the index - if (_.isNumber(nestedIndex)) { + if (_.isNumber(nestedIndex) && nestedIndex < this.queue.length) { this.state('nestedIndex', (nestedIndex += 1)) } diff --git a/packages/driver/src/cypress/log.ts b/packages/driver/src/cypress/log.ts index 56ee9ed5fa73..b059cbbbc3c7 100644 --- a/packages/driver/src/cypress/log.ts +++ b/packages/driver/src/cypress/log.ts @@ -355,15 +355,7 @@ export class Log { this.set('snapshots', snapshots) if (options.next && shouldRebindSnapshotFn) { - const originalLogSnapshotFn = this.snapshot - - this.snapshot = function () { - // restore the original snapshot function - this.snapshot = originalLogSnapshotFn - - // call orig fn with next as name - return originalLogSnapshotFn.call(this, options.next) - } + this.set('next', options.next) } return this @@ -376,10 +368,10 @@ export class Log { return this } - _.defaults(options, { - at: null, - next: null, - }) + if (this.get('next')) { + name = this.get('next') + this.set('next', null) + } if (this.config('experimentalSessionAndOrigin') && !Cypress.isCrossOriginSpecBridge) { const activeSpecBridgeOriginPolicyIfApplicable = this.state('currentActiveOriginPolicy') || undefined @@ -620,24 +612,6 @@ class LogManager { log.set(options) - // if snapshot was passed - // in, go ahead and snapshot - if (log.get('snapshot')) { - log.snapshot() - } - - // if end was passed in - // go ahead and end - if (log.get('end')) { - log.end() - } - - if (log.get('error')) { - log.error(log.get('error')) - } - - log.wrapConsoleProps() - const onBeforeLog = state('onBeforeLog') // dont trigger log if this function @@ -648,13 +622,24 @@ class LogManager { } } - // set the log on the command - const current = state('current') + const command = state('current') + + if (command) { + command.log(log) + } + + // if snapshot was passed + // in, go ahead and snapshot + if (log.get('snapshot')) { + log.snapshot() + } - if (current) { - current.log(log) + if (log.get('error')) { + log.error(log.get('error')) } + log.wrapConsoleProps() + this.addToLogs(log) if (options.sessionInfo) { @@ -667,9 +652,8 @@ class LogManager { this.triggerLog(log) - // if not current state then the log is being run - // with no command reference, so just end the log - if (!current) { + // if the log isn't associated with a command, then we know it won't be retrying and we should just end it. + if (!command || log.get('end')) { log.end() } From a07a2a118d7b62b90e790ef475c86959ae894b3b Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 22 Aug 2022 11:49:10 -0400 Subject: [PATCH 19/45] fix(webpack-dev-server): add custom project config to handler --- cli/types/cypress.d.ts | 15 +- npm/webpack-dev-server/src/devServer.ts | 3 + .../src/helpers/angularHandler.ts | 109 +- system-tests/projects/angular-13/yarn.lock | 689 +- .../angular-custom-config/angular.json | 96 + .../angular-custom-config/cypress.config.ts | 37 + .../angular-custom-config/package.json | 31 + .../src/app/my-component.cy.ts | 8 + .../src/app/my-component.ts | 6 + .../src/custom-style.scss | 3 + .../projects/angular-custom-config/yarn.lock | 6805 +++++++++++++++++ system-tests/test/component_testing_spec.ts | 8 + 12 files changed, 7096 insertions(+), 714 deletions(-) create mode 100644 system-tests/projects/angular-custom-config/angular.json create mode 100644 system-tests/projects/angular-custom-config/cypress.config.ts create mode 100644 system-tests/projects/angular-custom-config/package.json create mode 100644 system-tests/projects/angular-custom-config/src/app/my-component.cy.ts create mode 100644 system-tests/projects/angular-custom-config/src/app/my-component.ts create mode 100644 system-tests/projects/angular-custom-config/src/custom-style.scss create mode 100644 system-tests/projects/angular-custom-config/yarn.lock diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 8c6a20e487af..d4062d96813f 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -3047,16 +3047,29 @@ declare namespace Cypress { type PickConfigOpt = T extends keyof DefineDevServerConfig ? DefineDevServerConfig[T] : any + type ProjectConfig = { + root: string, + sourceRoot: string, + buildOptions: Record + } + type DevServerFn = (cypressDevServerConfig: DevServerConfig, devServerConfig: ComponentDevServerOpts) => ResolvedDevServerConfig | Promise type DevServerConfigOptions = { bundler: 'webpack' - framework: 'react' | 'vue' | 'vue-cli' | 'nuxt' | 'create-react-app' | 'next' | 'angular' + framework: 'react' | 'vue' | 'vue-cli' | 'nuxt' | 'create-react-app' | 'next' webpackConfig?: PickConfigOpt<'webpackConfig'> } | { bundler: 'vite' framework: 'react' | 'vue' viteConfig?: Omit, undefined>, 'base' | 'root'> + } | { + bundler: 'webpack', + framework: 'angular', + webpackConfig?: PickConfigOpt<'webpackConfig'>, + options?: { + projectConfig: ProjectConfig + } } interface ComponentConfigOptions extends Omit { diff --git a/npm/webpack-dev-server/src/devServer.ts b/npm/webpack-dev-server/src/devServer.ts index dd46f152bbc5..ebf9eb45694e 100644 --- a/npm/webpack-dev-server/src/devServer.ts +++ b/npm/webpack-dev-server/src/devServer.ts @@ -24,6 +24,9 @@ export type WebpackDevServerConfig = { } & { framework?: typeof ALL_FRAMEWORKS[number] // Add frameworks here as we implement webpackConfig?: unknown // Derived from the user's webpack + options?: { + projectConfig?: Cypress.ProjectConfig + } } export const ALL_FRAMEWORKS = ['create-react-app', 'nuxt', 'react', 'vue-cli', 'next', 'vue', 'angular'] as const diff --git a/npm/webpack-dev-server/src/helpers/angularHandler.ts b/npm/webpack-dev-server/src/helpers/angularHandler.ts index 9d0887f15620..d56b69c05352 100644 --- a/npm/webpack-dev-server/src/helpers/angularHandler.ts +++ b/npm/webpack-dev-server/src/helpers/angularHandler.ts @@ -5,19 +5,22 @@ import { pathToFileURL } from 'url' import type { PresetHandlerResult, WebpackDevServerConfig } from '../devServer' import { sourceDefaultWebpackDependencies } from './sourceRelativeWebpackModules' +type BuildOptions = Record + +type Configurations = { + configurations?: { + [configuration: string]: BuildOptions + } +} + +export type MyType = Extract + export type AngularJsonProjectConfig = { projectType: string root: string sourceRoot: string architect: { - build: { - options: { [key: string]: any } & { polyfills?: string } - configurations?: { - [configuration: string]: { - [key: string]: any - } - } - } + build: { options: BuildOptions } & Configurations } } @@ -30,21 +33,7 @@ type AngularJson = { const dynamicImport = new Function('specifier', 'return import(specifier)') -export async function angularHandler (devServerConfig: WebpackDevServerConfig): Promise { - const webpackConfig = await getAngularCliWebpackConfig(devServerConfig) - - return { frameworkConfig: webpackConfig, sourceWebpackModulesResult: sourceDefaultWebpackDependencies(devServerConfig) } -} - -async function getAngularCliWebpackConfig (devServerConfig: WebpackDevServerConfig) { - const { projectRoot } = devServerConfig.cypressConfig - - const { - generateBrowserWebpackConfigFromContext, - getCommonConfig, - getStylesConfig, - } = await getAngularCliModules(projectRoot) - +async function getProjectConfig (projectRoot: string): Promise { const angularJson = await getAngularJson(projectRoot) let { defaultProject } = angularJson @@ -59,24 +48,20 @@ async function getAngularCliWebpackConfig (devServerConfig: WebpackDevServerConf const defaultProjectConfig = angularJson.projects[defaultProject] - const tsConfig = await generateTsConfig(devServerConfig, defaultProjectConfig) - - const buildOptions = getAngularBuildOptions(defaultProjectConfig, tsConfig) - - const context = createFakeContext(projectRoot, defaultProject, defaultProjectConfig) - - const { config } = await generateBrowserWebpackConfigFromContext( - buildOptions, - context, - (wco: any) => [getCommonConfig(wco), getStylesConfig(wco)], - ) - - delete config.entry.main + const { architect, root, sourceRoot } = defaultProjectConfig + const { build } = architect - return config + return { + root, + sourceRoot, + buildOptions: { + ...build.options, + ...build.configurations?.development || {}, + }, + } } -export function getAngularBuildOptions (projectConfig: AngularJsonProjectConfig, tsConfig: string) { +export function getAngularBuildOptions (buildOptions: BuildOptions, tsConfig: string) { // Default options are derived from the @angular-devkit/build-angular browser builder, with some options from // the serve builder thrown in for development. // see: https://github.com/angular/angular-cli/blob/main/packages/angular_devkit/build_angular/src/builders/browser/schema.json @@ -115,8 +100,7 @@ export function getAngularBuildOptions (projectConfig: AngularJsonProjectConfig, extractLicenses: false, sourceMap: true, namedChunks: true, - ...projectConfig.architect.build.options, - ...projectConfig.architect.build.configurations?.development || {}, + ...buildOptions, tsConfig, aot: false, outputHashing: 'none', @@ -124,7 +108,7 @@ export function getAngularBuildOptions (projectConfig: AngularJsonProjectConfig, } } -export async function generateTsConfig (devServerConfig: WebpackDevServerConfig, projectConfig: AngularJsonProjectConfig): Promise { +export async function generateTsConfig (devServerConfig: WebpackDevServerConfig, buildOptions: BuildOptions): Promise { const { cypressConfig } = devServerConfig const { projectRoot } = cypressConfig @@ -138,8 +122,8 @@ export async function generateTsConfig (devServerConfig: WebpackDevServerConfig, includePaths.push(toPosix(cypressConfig.supportFile)) } - if (projectConfig.architect.build.options.polyfills) { - const polyfills = getProjectFilePath(projectConfig.architect.build.options.polyfills) + if (buildOptions?.polyfills) { + const polyfills = getProjectFilePath(buildOptions?.polyfills) includePaths.push(polyfills) } @@ -215,14 +199,14 @@ export async function getAngularJson (projectRoot: string): Promise return JSON.parse(angularJson) } -function createFakeContext (projectRoot: string, defaultProject: string, defaultProjectConfig: any) { +function createFakeContext (projectRoot: string, defaultProjectConfig: Cypress.ProjectConfig) { const logger = { createChild: () => ({}), } const context = { target: { - project: defaultProject, + project: 'angular', }, workspaceRoot: projectRoot, getProjectMetadata: () => { @@ -239,3 +223,38 @@ function createFakeContext (projectRoot: string, defaultProject: string, default } export const toPosix = (filePath: string) => filePath.split(path.sep).join(path.posix.sep) + +async function getAngularCliWebpackConfig (devServerConfig: WebpackDevServerConfig) { + const { projectRoot } = devServerConfig.cypressConfig + + const { + generateBrowserWebpackConfigFromContext, + getCommonConfig, + getStylesConfig, + } = await getAngularCliModules(projectRoot) + + // normalize + const projectConfig = devServerConfig.options?.projectConfig || await getProjectConfig(projectRoot) + + const tsConfig = await generateTsConfig(devServerConfig, projectConfig.buildOptions) + + const buildOptions = getAngularBuildOptions(projectConfig.buildOptions, tsConfig) + + const context = createFakeContext(projectRoot, projectConfig) + + const { config } = await generateBrowserWebpackConfigFromContext( + buildOptions, + context, + (wco: any) => [getCommonConfig(wco), getStylesConfig(wco)], + ) + + delete config.entry.main + + return config +} + +export async function angularHandler (devServerConfig: WebpackDevServerConfig): Promise { + const webpackConfig = await getAngularCliWebpackConfig(devServerConfig) + + return { frameworkConfig: webpackConfig, sourceWebpackModulesResult: sourceDefaultWebpackDependencies(devServerConfig) } +} diff --git a/system-tests/projects/angular-13/yarn.lock b/system-tests/projects/angular-13/yarn.lock index 3bc0ca1d27f8..b798db599555 100644 --- a/system-tests/projects/angular-13/yarn.lock +++ b/system-tests/projects/angular-13/yarn.lock @@ -1186,11 +1186,6 @@ "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" -"@colors/colors@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" - integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== - "@csstools/postcss-progressive-custom-properties@^1.1.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz#542292558384361776b45c85226b9a3a34f276fa" @@ -1203,38 +1198,6 @@ resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== -"@cypress/request@^2.88.10": - version "2.88.10" - resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.10.tgz#b66d76b07f860d3a4b8d7a0604d020c662752cce" - integrity sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - http-signature "~1.3.6" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^8.3.2" - -"@cypress/xvfb@^1.2.4": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" - integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== - dependencies: - debug "^3.1.0" - lodash.once "^4.1.1" - "@discoveryjs/json-ext@0.5.6": version "0.5.6" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" @@ -1532,11 +1495,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== -"@types/node@^14.14.31": - version "14.18.22" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.22.tgz#fd2a15dca290fc9ad565b672fde746191cd0c6e6" - integrity sha512-qzaYbXVzin6EPjghf/hTdIbnVW1ErMx8rPzwRNJhlbyJhu2SyqlvjGOY/tbUt6VFyzg56lROcOeSQRInpt63Yw== - "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -1572,16 +1530,6 @@ "@types/mime" "^1" "@types/node" "*" -"@types/sinonjs__fake-timers@8.1.1": - version "8.1.1" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" - integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== - -"@types/sizzle@^2.3.2": - version "2.3.3" - resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef" - integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ== - "@types/sockjs@^0.3.33": version "0.3.33" resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" @@ -1596,13 +1544,6 @@ dependencies: "@types/node" "*" -"@types/yauzl@^2.9.1": - version "2.10.0" - resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599" - integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw== - dependencies: - "@types/node" "*" - "@webassemblyjs/ast@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" @@ -1853,12 +1794,7 @@ ansi-colors@4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: +ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -1907,11 +1843,6 @@ anymatch@~3.1.2: resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== -arch@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" - integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== - are-we-there-yet@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d" @@ -1947,23 +1878,6 @@ array-union@^3.0.1: resolved "https://registry.yarnpkg.com/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975" integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw== -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - async@^2.6.2: version "2.6.4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" @@ -1971,21 +1885,6 @@ async@^2.6.2: dependencies: lodash "^4.17.14" -async@^3.2.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -2003,16 +1902,6 @@ autoprefixer@^10.4.2: picocolors "^1.0.0" postcss-value-parser "^4.2.0" -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - babel-loader@8.2.5: version "8.2.5" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" @@ -2080,13 +1969,6 @@ batch@0.6.1: resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== - dependencies: - tweetnacl "^0.14.3" - big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -2106,16 +1988,6 @@ bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" -blob-util@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb" - integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ== - -bluebird@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - body-parser@1.20.0: version "1.20.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" @@ -2183,11 +2055,6 @@ browserslist@^4.14.5, browserslist@^4.19.1, browserslist@^4.20.2, browserslist@^ node-releases "^2.0.6" update-browserslist-db "^1.0.4" -buffer-crc32@~0.2.3: - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== - buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -2198,7 +2065,7 @@ buffer-indexof@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== -buffer@^5.5.0, buffer@^5.6.0: +buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -2269,11 +2136,6 @@ cacache@^16.1.0: tar "^6.1.11" unique-filename "^1.1.1" -cachedir@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" - integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== - call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -2297,11 +2159,6 @@ caniuse-lite@^1.0.30001299, caniuse-lite@^1.0.30001335, caniuse-lite@^1.0.300013 resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz#2b97fe472e8fa29c78c5970615d7cd2ee414108a" integrity sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== - chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -2324,11 +2181,6 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -check-more-types@^2.24.0: - version "2.24.0" - resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" - integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA== - "chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.5.2: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -2354,11 +2206,6 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== -ci-info@^3.2.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128" - integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg== - circular-dependency-plugin@5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz#39e836079db1d3cf2f988dc48c5188a44058b600" @@ -2381,23 +2228,6 @@ cli-spinners@^2.5.0: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== -cli-table3@~0.6.1: - version "0.6.2" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.2.tgz#aaf5df9d8b5bf12634dc8b3040806a0c07120d2a" - integrity sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw== - dependencies: - string-width "^4.2.0" - optionalDependencies: - "@colors/colors" "1.5.0" - -cli-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== - dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" - cli-width@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" @@ -2455,33 +2285,16 @@ color-support@^1.1.3: resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== -colorette@^2.0.10, colorette@^2.0.16: +colorette@^2.0.10: version "2.0.19" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" - integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== - -common-tags@^1.8.0: - version "1.8.2" - resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" - integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2583,11 +2396,6 @@ core-js@3.20.3: resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.20.3.tgz#c710d0a676e684522f3db4ee84e5e18a9d11d69a" integrity sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag== -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -2616,7 +2424,7 @@ critters@0.0.16: postcss "^8.3.7" pretty-bytes "^5.3.0" -cross-spawn@^7.0.0, cross-spawn@^7.0.3: +cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -2693,64 +2501,6 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -"cypress@file:../../../cli": - version "0.0.0-development" - dependencies: - "@cypress/request" "^2.88.10" - "@cypress/xvfb" "^1.2.4" - "@types/node" "^14.14.31" - "@types/sinonjs__fake-timers" "8.1.1" - "@types/sizzle" "^2.3.2" - arch "^2.2.0" - blob-util "^2.0.2" - bluebird "^3.7.2" - buffer "^5.6.0" - cachedir "^2.3.0" - chalk "^4.1.0" - check-more-types "^2.24.0" - cli-cursor "^3.1.0" - cli-table3 "~0.6.1" - commander "^5.1.0" - common-tags "^1.8.0" - dayjs "^1.10.4" - debug "^4.3.2" - enquirer "^2.3.6" - eventemitter2 "^6.4.3" - execa "4.1.0" - executable "^4.1.1" - extract-zip "2.0.1" - figures "^3.2.0" - fs-extra "^9.1.0" - getos "^3.2.1" - is-ci "^3.0.0" - is-installed-globally "~0.4.0" - lazy-ass "^1.6.0" - listr2 "^3.8.3" - lodash "^4.17.21" - log-symbols "^4.0.0" - minimist "^1.2.6" - ospath "^1.2.2" - pretty-bytes "^5.6.0" - proxy-from-env "1.0.0" - request-progress "^3.0.0" - semver "^7.3.2" - supports-color "^8.1.1" - tmp "~0.2.1" - untildify "^4.0.0" - yauzl "^2.10.0" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== - dependencies: - assert-plus "^1.0.0" - -dayjs@^1.10.4: - version "1.11.4" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.4.tgz#3b3c10ca378140d8917e06ebc13a4922af4f433e" - integrity sha512-Zj/lPM5hOvQ1Bf7uAvewDaUcsJoI6JmNqmHhHl3nyumwe0XHwt8sWdOVAPACJzCebL8gQCi+K49w7iKWnGwX9g== - debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2772,7 +2522,7 @@ debug@4.3.3: dependencies: ms "2.1.2" -debug@^3.1.0, debug@^3.1.1, debug@^3.2.6: +debug@^3.1.1, debug@^3.2.6: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -2837,11 +2587,6 @@ del@^6.0.0: rimraf "^3.0.2" slash "^3.0.0" -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" @@ -2929,14 +2674,6 @@ domutils@^2.8.0: domelementtype "^2.2.0" domhandler "^4.2.0" -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -2969,13 +2706,6 @@ encoding@^0.1.12, encoding@^0.1.13: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - enhanced-resolve@^5.9.2: version "5.10.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" @@ -2984,13 +2714,6 @@ enhanced-resolve@^5.9.2: graceful-fs "^4.2.4" tapable "^2.2.0" -enquirer@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" @@ -3210,11 +2933,6 @@ eventemitter-asyncresource@^1.0.0: resolved "https://registry.yarnpkg.com/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz#734ff2e44bf448e627f7748f905d6bdd57bdb65b" integrity sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ== -eventemitter2@^6.4.3: - version "6.4.6" - resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.6.tgz#92d56569cc147a4d9b9da9e942e89b20ce236b0a" - integrity sha512-OHqo4wbHX5VbvlbB6o6eDwhYmiTjrpWACjF8Pmof/GTD6rdBNdZFNck3xlhqOiQFGCOoq3uzHvA0cQpFHIGVAQ== - eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -3225,21 +2943,6 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" - integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -3255,13 +2958,6 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -executable@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" - integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== - dependencies: - pify "^2.2.0" - express@^4.17.1: version "4.18.1" resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" @@ -3299,11 +2995,6 @@ express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -3313,27 +3004,6 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -extract-zip@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" - integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== - dependencies: - debug "^4.1.1" - get-stream "^5.1.0" - yauzl "^2.10.0" - optionalDependencies: - "@types/yauzl" "^2.9.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -3369,14 +3039,7 @@ faye-websocket@^0.11.3: dependencies: websocket-driver ">=0.5.1" -fd-slicer@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" - integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== - dependencies: - pend "~1.2.0" - -figures@^3.0.0, figures@^3.2.0: +figures@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== @@ -3425,20 +3088,6 @@ follow-redirects@^1.0.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -3454,16 +3103,6 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -fs-extra@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -3534,32 +3173,11 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== -get-stream@^5.0.0, get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -getos@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" - integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== - dependencies: - async "^3.2.0" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== - dependencies: - assert-plus "^1.0.0" - glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -3614,13 +3232,6 @@ glob@^8.0.1: minimatch "^5.0.1" once "^1.3.0" -global-dirs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" - integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== - dependencies: - ini "2.0.0" - globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -3650,7 +3261,7 @@ globby@^12.0.2: merge2 "^1.4.1" slash "^4.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== @@ -3811,15 +3422,6 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" -http-signature@~1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" - integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw== - dependencies: - assert-plus "^1.0.0" - jsprim "^2.0.2" - sshpk "^1.14.1" - https-proxy-agent@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" @@ -3836,11 +3438,6 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== - human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -4005,13 +3602,6 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-ci@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" - integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== - dependencies: - ci-info "^3.2.0" - is-core-module@^2.8.1, is-core-module@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" @@ -4048,14 +3638,6 @@ is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-installed-globally@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" - integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== - dependencies: - global-dirs "^3.0.0" - is-path-inside "^3.0.2" - is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -4106,11 +3688,6 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== - is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" @@ -4143,11 +3720,6 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== - istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" @@ -4186,11 +3758,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== - jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -4221,16 +3788,6 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - json5@^2.1.2, json5@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" @@ -4241,30 +3798,11 @@ jsonc-parser@3.0.0: resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - jsonparse@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -jsprim@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d" - integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - karma-source-map-support@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz#58526ceccf7e8730e56effd97a4de8d712ac0d6b" @@ -4282,11 +3820,6 @@ klona@^2.0.4, klona@^2.0.5: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== -lazy-ass@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" - integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw== - less-loader@10.2.0: version "10.2.0" resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-10.2.0.tgz#97286d8797dc3dc05b1d16b0ecec5f968bdd4e32" @@ -4323,20 +3856,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -listr2@^3.8.3: - version "3.14.0" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" - integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== - dependencies: - cli-truncate "^2.1.0" - colorette "^2.0.16" - log-update "^4.0.0" - p-map "^4.0.0" - rfdc "^1.3.0" - rxjs "^7.5.1" - through "^2.3.8" - wrap-ansi "^7.0.0" - loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -4368,17 +3887,12 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== -lodash.once@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== - lodash@^4.17.14, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@^4.0.0, log-symbols@^4.1.0: +log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -4386,16 +3900,6 @@ log-symbols@^4.0.0, log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log-update@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" - integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== - dependencies: - ansi-escapes "^4.3.0" - cli-cursor "^3.1.0" - slice-ansi "^4.0.0" - wrap-ansi "^6.2.0" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -4526,7 +4030,7 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -4844,7 +4348,7 @@ npm-registry-fetch@^12.0.0: minizlib "^2.1.2" npm-package-arg "^8.1.5" -npm-run-path@^4.0.0, npm-run-path@^4.0.1: +npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -4913,7 +4417,7 @@ on-headers@~1.0.2: resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -4956,11 +4460,6 @@ os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== -ospath@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" - integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA== - p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -5109,16 +4608,6 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pend@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" - integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -5129,7 +4618,7 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.2.0, pify@^2.3.0: +pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== @@ -5453,7 +4942,7 @@ postcss@^8.2.14, postcss@^8.2.15, postcss@^8.3.7: picocolors "^1.0.0" source-map-js "^1.0.2" -pretty-bytes@^5.3.0, pretty-bytes@^5.6.0: +pretty-bytes@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== @@ -5484,30 +4973,12 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -proxy-from-env@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" - integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== - prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== -psl@^1.1.28: - version "1.9.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -5519,11 +4990,6 @@ qs@6.10.3: dependencies: side-channel "^1.0.4" -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -5662,13 +5128,6 @@ regjsparser@^0.8.2: dependencies: jsesc "~0.5.0" -request-progress@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" - integrity sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg== - dependencies: - throttleit "^1.0.0" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -5746,12 +5205,7 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -5777,7 +5231,7 @@ rxjs@6.6.7: dependencies: tslib "^1.9.0" -rxjs@^7.2.0, rxjs@^7.5.1, rxjs@~7.5.0: +rxjs@^7.2.0, rxjs@~7.5.0: version "7.5.6" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw== @@ -5789,12 +5243,12 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@^2.1.2, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -5883,7 +5337,7 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@^7.0.0, semver@^7.1.1, semver@^7.3.4, semver@^7.3.5: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== @@ -5997,24 +5451,6 @@ slash@^4.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== -slice-ansi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" - integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" @@ -6138,21 +5574,6 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== -sshpk@^1.14.1: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" @@ -6254,7 +5675,7 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.0.0, supports-color@^8.1.1: +supports-color@^8.0.0: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== @@ -6333,12 +5754,7 @@ text-table@0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -throttleit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" - integrity sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g== - -through@^2.3.6, through@^2.3.8: +through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== @@ -6355,13 +5771,6 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmp@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -6379,14 +5788,6 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tree-kill@1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -6407,18 +5808,6 @@ tslib@^2.1.0, tslib@^2.3.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== - type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" @@ -6479,21 +5868,11 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - update-browserslist-db@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" @@ -6536,15 +5915,6 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - watchpack@^2.3.1: version "2.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" @@ -6707,15 +6077,6 @@ wildcard@^2.0.0: resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -6768,14 +6129,6 @@ yargs@^17.2.1: y18n "^5.0.5" yargs-parser "^21.0.0" -yauzl@^2.10.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" - integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== - dependencies: - buffer-crc32 "~0.2.3" - fd-slicer "~1.1.0" - zone.js@~0.11.4: version "0.11.6" resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.6.tgz#c7cacfc298fe24bb585329ca04a44d9e2e840e74" diff --git a/system-tests/projects/angular-custom-config/angular.json b/system-tests/projects/angular-custom-config/angular.json new file mode 100644 index 000000000000..6ad8116bf631 --- /dev/null +++ b/system-tests/projects/angular-custom-config/angular.json @@ -0,0 +1,96 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "cli": { + "analytics": false + }, + "version": 1, + "newProjectRoot": "projects", + "projects": { + "angular": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + }, + "@schematics/angular:application": { + "strict": true + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "custom": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/angular", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "src/custom-style.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "browserTarget": "angular:build:production" + }, + "development": { + "browserTarget": "angular:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "angular:build" + } + } + } + } + }, + "defaultProject": "angular" +} diff --git a/system-tests/projects/angular-custom-config/cypress.config.ts b/system-tests/projects/angular-custom-config/cypress.config.ts new file mode 100644 index 000000000000..b85dbc7bb2d5 --- /dev/null +++ b/system-tests/projects/angular-custom-config/cypress.config.ts @@ -0,0 +1,37 @@ +import { defineConfig } from 'cypress' +const { projects } = require('./angular.json') + +export default defineConfig({ + component: { + devServer: { + framework: 'angular', + bundler: 'webpack', + options: { + projectConfig: { + root: projects.angular.root, + sourceRoot: projects.angular.sourceRoot, + buildOptions: { + ...projects.angular.architect.custom.options, + ...projects.angular.architect.custom.configurations.development, + }, + }, + }, + webpackConfig: { + resolve: { + alias: { + '@angular/common': require.resolve('@angular/common'), + '@angular/core/testing': require.resolve('@angular/core/testing'), + '@angular/core': require.resolve('@angular/core'), + '@angular/platform-browser/testing': require.resolve('@angular/platform-browser/testing'), + '@angular/platform-browser': require.resolve('@angular/platform-browser'), + '@angular/platform-browser-dynamic/testing': require.resolve('@angular/platform-browser-dynamic/testing'), + '@angular/platform-browser-dynamic': require.resolve('@angular/platform-browser-dynamic'), + 'zone.js/testing': require.resolve('zone.js/dist/zone-testing'), + 'zone.js': require.resolve('zone.js'), + }, + }, + }, + }, + specPattern: 'src/**/*.cy.ts', + }, +}) diff --git a/system-tests/projects/angular-custom-config/package.json b/system-tests/projects/angular-custom-config/package.json new file mode 100644 index 000000000000..9cb2e5243545 --- /dev/null +++ b/system-tests/projects/angular-custom-config/package.json @@ -0,0 +1,31 @@ +{ + "name": "angular-14-custom-config", + "version": "0.0.0", + "private": true, + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development" + }, + "dependencies": { + "@angular/animations": "^14.0.0", + "@angular/common": "^14.0.0", + "@angular/compiler": "^14.0.0", + "@angular/core": "^14.0.0", + "@angular/forms": "^14.0.0", + "@angular/platform-browser": "^14.0.0", + "@angular/platform-browser-dynamic": "^14.0.0", + "@angular/router": "^14.0.0", + "rxjs": "~7.5.0", + "tslib": "^2.3.0", + "zone.js": "~0.11.4" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^14.0.0", + "@angular/cli": "~14.0.0", + "@angular/compiler-cli": "^14.0.0", + "typescript": "~4.7.2" + }, + "projectFixtureDirectory": "angular" +} diff --git a/system-tests/projects/angular-custom-config/src/app/my-component.cy.ts b/system-tests/projects/angular-custom-config/src/app/my-component.cy.ts new file mode 100644 index 000000000000..01c5c548bc1d --- /dev/null +++ b/system-tests/projects/angular-custom-config/src/app/my-component.cy.ts @@ -0,0 +1,8 @@ +import { MyComponent } from './my-component' + +describe('MyComponent', () => { + it('should mount with an h1 tag with a class of very-red', () => { + cy.mount(MyComponent) + cy.get('h1').should('have.css', 'color', 'rgb(255, 0, 0)') + }) +}) diff --git a/system-tests/projects/angular-custom-config/src/app/my-component.ts b/system-tests/projects/angular-custom-config/src/app/my-component.ts new file mode 100644 index 000000000000..c3a249daf065 --- /dev/null +++ b/system-tests/projects/angular-custom-config/src/app/my-component.ts @@ -0,0 +1,6 @@ +import { Component } from '@angular/core' + +@Component({ + template: `

Hello Angular

`, +}) +export class MyComponent {} diff --git a/system-tests/projects/angular-custom-config/src/custom-style.scss b/system-tests/projects/angular-custom-config/src/custom-style.scss new file mode 100644 index 000000000000..e4d4f183effb --- /dev/null +++ b/system-tests/projects/angular-custom-config/src/custom-style.scss @@ -0,0 +1,3 @@ +h1.very-red { + color: red +} \ No newline at end of file diff --git a/system-tests/projects/angular-custom-config/yarn.lock b/system-tests/projects/angular-custom-config/yarn.lock new file mode 100644 index 000000000000..1814b1634ae0 --- /dev/null +++ b/system-tests/projects/angular-custom-config/yarn.lock @@ -0,0 +1,6805 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@2.2.0", "@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@angular-devkit/architect@0.1400.6": + version "0.1400.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1400.6.tgz#545f65e7aa9a8c8fb09756a43491679ea259b760" + integrity sha512-POqWsCvo5O4/5dsPYGA68YU9x5k/xAU+a5h/QvhjeRJVCuYZ0IX97EPQ+w/tXRRL3kdwS6zfaIXR2p+U3F1DmA== + dependencies: + "@angular-devkit/core" "14.0.6" + rxjs "6.6.7" + +"@angular-devkit/build-angular@^14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-14.0.6.tgz#53832fe6f4926514e86824d60f3dc409a36d0ac5" + integrity sha512-xwLG37ta5qV1NrqdAFGa6t8lrNuoO1WYYEJ4LcHqid7sXlN4cpV88CzNoWn8ElDdEZwcjPOW81mPRLY663iudQ== + dependencies: + "@ampproject/remapping" "2.2.0" + "@angular-devkit/architect" "0.1400.6" + "@angular-devkit/build-webpack" "0.1400.6" + "@angular-devkit/core" "14.0.6" + "@babel/core" "7.17.10" + "@babel/generator" "7.17.10" + "@babel/helper-annotate-as-pure" "7.16.7" + "@babel/plugin-proposal-async-generator-functions" "7.16.8" + "@babel/plugin-transform-async-to-generator" "7.16.8" + "@babel/plugin-transform-runtime" "7.17.10" + "@babel/preset-env" "7.17.10" + "@babel/runtime" "7.17.9" + "@babel/template" "7.16.7" + "@discoveryjs/json-ext" "0.5.7" + "@ngtools/webpack" "14.0.6" + ansi-colors "4.1.1" + babel-loader "8.2.5" + babel-plugin-istanbul "6.1.1" + browserslist "^4.9.1" + cacache "16.0.7" + copy-webpack-plugin "10.2.4" + critters "0.0.16" + css-loader "6.7.1" + esbuild-wasm "0.14.38" + glob "8.0.1" + https-proxy-agent "5.0.1" + inquirer "8.2.4" + jsonc-parser "3.0.0" + karma-source-map-support "1.4.0" + less "4.1.2" + less-loader "10.2.0" + license-webpack-plugin "4.0.2" + loader-utils "3.2.0" + mini-css-extract-plugin "2.6.0" + minimatch "5.0.1" + open "8.4.0" + ora "5.4.1" + parse5-html-rewriting-stream "6.0.1" + piscina "3.2.0" + postcss "8.4.13" + postcss-import "14.1.0" + postcss-loader "6.2.1" + postcss-preset-env "7.5.0" + regenerator-runtime "0.13.9" + resolve-url-loader "5.0.0" + rxjs "6.6.7" + sass "1.51.0" + sass-loader "12.6.0" + semver "7.3.7" + source-map-loader "3.0.1" + source-map-support "0.5.21" + stylus "0.57.0" + stylus-loader "6.2.0" + terser "5.13.1" + text-table "0.2.0" + tree-kill "1.2.2" + tslib "2.4.0" + webpack "5.72.1" + webpack-dev-middleware "5.3.1" + webpack-dev-server "4.9.0" + webpack-merge "5.8.0" + webpack-subresource-integrity "5.1.0" + optionalDependencies: + esbuild "0.14.38" + +"@angular-devkit/build-webpack@0.1400.6": + version "0.1400.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1400.6.tgz#fa0d455d183a8ad9a27edadd4887025ee1e3ab65" + integrity sha512-3Zg+jST6a2Xj8s4IQ7XIH31Pv6/0XbKCbGC0W31fPRAxTKIeLfEJYkDXwnhpEY5ctYq3PR1/IXjZNlGoz0AhvQ== + dependencies: + "@angular-devkit/architect" "0.1400.6" + rxjs "6.6.7" + +"@angular-devkit/core@14.0.6": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-14.0.6.tgz#e2171be2b8f3b5235f07441cf11da4eaa8c454fa" + integrity sha512-b0U4D5jxAsx26F4YQu7XW+lpxLZT4ssdyMarbfIryeupznnGE+69F+U/G+FhTEMYbxrYRMGn/wYy6vcg57NYfQ== + dependencies: + ajv "8.11.0" + ajv-formats "2.1.1" + jsonc-parser "3.0.0" + rxjs "6.6.7" + source-map "0.7.3" + +"@angular-devkit/schematics@14.0.6": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-14.0.6.tgz#d0ccb5ca75de60bbc5349141a3eac820ccd4d723" + integrity sha512-o7I5KBnz/fxYgVLZ+XIsaGZUDiQCqM89aaIPOg84Ij0Nr3N+f4NYq56PPRln7hAfV3m/3JpH+cgycaGND5wHHQ== + dependencies: + "@angular-devkit/core" "14.0.6" + jsonc-parser "3.0.0" + magic-string "0.26.1" + ora "5.4.1" + rxjs "6.6.7" + +"@angular/animations@^14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-14.0.6.tgz#7f7c3a64fbbeee9fd7141649cb903d59c65a15f5" + integrity sha512-l363hFgj5Dxw6WKZkJRd77izOznCqJVrWhxfO9ERG0ShVUb/3WB9RSOUCVltDrTY5sFK+cw+slQYGH6AXgvMVQ== + dependencies: + tslib "^2.3.0" + +"@angular/cli@~14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-14.0.6.tgz#93d3f1d24c3ac27f0d6e81d08c0db4926f07b162" + integrity sha512-q8iByoyVNLUOCosc5/wD9FkaM09d5HOic5RYSAg265pMgreQ/oQM1ajGRzzVWFhzw/RlUuon8ezZyAUAXfszCQ== + dependencies: + "@angular-devkit/architect" "0.1400.6" + "@angular-devkit/core" "14.0.6" + "@angular-devkit/schematics" "14.0.6" + "@schematics/angular" "14.0.6" + "@yarnpkg/lockfile" "1.1.0" + ansi-colors "4.1.1" + debug "4.3.4" + ini "3.0.0" + inquirer "8.2.4" + jsonc-parser "3.0.0" + npm-package-arg "9.0.2" + npm-pick-manifest "7.0.1" + open "8.4.0" + ora "5.4.1" + pacote "13.3.0" + resolve "1.22.0" + semver "7.3.7" + symbol-observable "4.0.0" + uuid "8.3.2" + yargs "17.4.1" + +"@angular/common@^14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-14.0.6.tgz#1ae36eec1b9030f78ab8c62916ef9af7a9a92bea" + integrity sha512-AynjE7OOEfrdKmS3nu00tkf4g66cx97T6qhfaTvc3hKi45MreBcJkIMcSowF24peygvUN41htMJuq3WQLu92iQ== + dependencies: + tslib "^2.3.0" + +"@angular/compiler-cli@^14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-14.0.6.tgz#c87e2698b6a642919bfe9b5d66ea9ef3095a396d" + integrity sha512-w1ccZEzbRRqzMNaty0P4QliSslmR+9pBhDpKNfI+PsRqjJOnyC9tFdtZQLjcbnaM8W0yJLnCfZQ7KKXjnjzawg== + dependencies: + "@babel/core" "^7.17.2" + chokidar "^3.0.0" + convert-source-map "^1.5.1" + dependency-graph "^0.11.0" + magic-string "^0.26.0" + reflect-metadata "^0.1.2" + semver "^7.0.0" + sourcemap-codec "^1.4.8" + tslib "^2.3.0" + yargs "^17.2.1" + +"@angular/compiler@^14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-14.0.6.tgz#d2cd7afac7bb833ff4298aec1abd460f6ed32910" + integrity sha512-zYq3+Pg6m7NKivqEk+vNy+5ic5A+B0ReqIECjs10pVeXoWBxjvZAqG2ksrCQ0axtju2hA3lrFsDthLShWBEf4g== + dependencies: + tslib "^2.3.0" + +"@angular/core@^14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-14.0.6.tgz#697d52ca9d772877a5138af26d1d9c5e7c267ade" + integrity sha512-hyQ3s9Yrm3ejhumgAC9ENhMFmvmPlJkk1tEOjruyoiHwK4EOaDpI+GCNQIBUB1Z3B/QLMlgZeMXrULQztjSQwg== + dependencies: + tslib "^2.3.0" + +"@angular/forms@^14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-14.0.6.tgz#87aa36b1a3f3bd1ca71615fd250f04f8e660971c" + integrity sha512-ITa3A6pWecDgDjBTlwQnJnSOc1o35bIvRpTclLx/ysDbn4FB2tPy4iseCSrOlgdJHZjBcHBIxX27yYjWyBfIwQ== + dependencies: + tslib "^2.3.0" + +"@angular/platform-browser-dynamic@^14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.0.6.tgz#a05fa27f9bbc4a0a0fbb25fd8058a9f6791cf7f6" + integrity sha512-iYWmzUDWO+qc7wN1ED3dIkvDjIBdSqh/gpFvLGyCUZBwzwZ45sJOT/YgCmLBzBsVV/2GhAhV0QL4ioVQ5Jy3UA== + dependencies: + tslib "^2.3.0" + +"@angular/platform-browser@^14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-14.0.6.tgz#5a98fc8f52c076dd0ead03b3c5ecabbd4dc7abb4" + integrity sha512-d9PS2E5HSgiKzItHzVdxdBoMeaOvlDo6ccSEXLYCGyJ9MykDjKvJPWy6GicilBPa8g4VGJpk9J+lbgXXAOkCFA== + dependencies: + tslib "^2.3.0" + +"@angular/router@^14.0.0": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-14.0.6.tgz#008852d6796781d1dcb32899dd7e2921e8245bdf" + integrity sha512-FFLnaBuOASqUCbr8QIBX8Y+PbSSVrN6YFVI82bQDr2fesI+5UdLTfiEBUMizwnQ4choEtSd8542DjiEW8Rc+lA== + dependencies: + tslib "^2.3.0" + +"@assemblyscript/loader@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@assemblyscript/loader/-/loader-0.10.1.tgz#70e45678f06c72fa2e350e8553ec4a4d72b92e06" + integrity sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg== + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.17.10", "@babel/compat-data@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== + +"@babel/core@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.10.tgz#74ef0fbf56b7dfc3f198fc2d927f4f03e12f4b05" + integrity sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.10" + "@babel/helper-compilation-targets" "^7.17.10" + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helpers" "^7.17.9" + "@babel/parser" "^7.17.10" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.10" + "@babel/types" "^7.17.10" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/core@^7.12.3", "@babel/core@^7.17.2": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59" + integrity sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.9" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/generator@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.10.tgz#c281fa35b0c349bbe9d02916f4ae08fc85ed7189" + integrity sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg== + dependencies: + "@babel/types" "^7.17.10" + "@jridgewell/gen-mapping" "^0.1.0" + jsesc "^2.5.1" + +"@babel/generator@^7.17.10", "@babel/generator@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.9.tgz#68337e9ea8044d6ddc690fb29acae39359cca0a5" + integrity sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug== + dependencies: + "@babel/types" "^7.18.9" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/helper-annotate-as-pure@7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" + integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" + integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.18.6" + "@babel/types" "^7.18.9" + +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.17.10", "@babel/helper-compilation-targets@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" + integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.20.2" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.18.6": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz#d802ee16a64a9e824fcbf0a2ffc92f19d58550ce" + integrity sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" + +"@babel/helper-create-regexp-features-plugin@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz#3e35f4e04acbbf25f1b3534a657610a000543d3c" + integrity sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.1.0" + +"@babel/helper-define-polyfill-provider@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" + integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-environment-visitor@^7.18.6", "@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + +"@babel/helper-explode-assignable-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" + integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" + integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== + dependencies: + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.9" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-member-expression-to-functions@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" + integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== + dependencies: + "@babel/types" "^7.18.9" + +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-transforms@^7.17.7", "@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" + integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-optimise-call-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" + integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f" + integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w== + +"@babel/helper-remap-async-to-generator@^7.16.8", "@babel/helper-remap-async-to-generator@^7.18.6": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" + integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-wrap-function" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6" + integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" + integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== + dependencies: + "@babel/types" "^7.18.9" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + +"@babel/helper-validator-option@^7.16.7", "@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helper-wrap-function@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.18.9.tgz#ae1feddc6ebbaa2fd79346b77821c3bd73a39646" + integrity sha512-cG2ru3TRAL6a60tfQflpEfs4ldiPwF6YW3zfJiRgmoFVIaC1vGnBBgatfec+ZUziPHkHSaXAuEck3Cdkf3eRpQ== + dependencies: + "@babel/helper-function-name" "^7.18.9" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helpers@^7.17.9", "@babel/helpers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" + integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== + dependencies: + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.10", "@babel/parser@^7.18.6", "@babel/parser@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" + integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" + integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" + integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" + +"@babel/plugin-proposal-async-generator-functions@7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" + integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-async-generator-functions@^7.16.8": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz#aedac81e6fc12bb643374656dd5f2605bf743d17" + integrity sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w== + dependencies: + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-class-properties@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-class-static-block@^7.17.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" + integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-proposal-dynamic-import@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" + integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" + integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" + integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" + integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" + integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.17.3": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" + integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.18.8" + +"@babel/plugin-proposal-optional-catch-binding@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" + integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.16.7", "@babel/plugin-proposal-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" + integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.16.11": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" + integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-private-property-in-object@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503" + integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-proposal-unicode-property-regex@^7.16.7", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" + integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-arrow-functions@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" + integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-async-to-generator@7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" + integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + +"@babel/plugin-transform-async-to-generator@^7.16.8": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" + integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== + dependencies: + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" + +"@babel/plugin-transform-block-scoped-functions@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" + integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-block-scoping@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" + integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-classes@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz#90818efc5b9746879b869d5ce83eb2aa48bbc3da" + integrity sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" + integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-destructuring@^7.17.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.9.tgz#68906549c021cb231bee1db21d3b5b095f8ee292" + integrity sha512-p5VCYNddPLkZTq4XymQIaIfZNJwT9YsjkPOhkVEqt6QIpQFZVM9IltqqYpOEkJoN1DPznmxUDyZ5CTZs/ZCuHA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-dotall-regex@^7.16.7", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" + integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-duplicate-keys@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" + integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-exponentiation-operator@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" + integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-for-of@^7.16.7": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" + integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-function-name@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" + integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== + dependencies: + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-literals@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" + integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-member-expression-literals@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" + integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-modules-amd@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21" + integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== + dependencies: + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.17.9": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" + integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== + dependencies: + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.17.8": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz#545df284a7ac6a05125e3e405e536c5853099a06" + integrity sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A== + dependencies: + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-validator-identifier" "^7.18.6" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" + integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== + dependencies: + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.17.10": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz#c89bfbc7cc6805d692f3a49bc5fc1b630007246d" + integrity sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-new-target@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" + integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-object-super@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" + integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" + +"@babel/plugin-transform-parameters@^7.16.7", "@babel/plugin-transform-parameters@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" + integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-property-literals@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" + integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-regenerator@^7.17.9": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73" + integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + regenerator-transform "^0.15.0" + +"@babel/plugin-transform-reserved-words@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" + integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-runtime@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.10.tgz#b89d821c55d61b5e3d3c3d1d636d8d5a81040ae1" + integrity sha512-6jrMilUAJhktTr56kACL8LnWC5hx3Lf27BS0R0DSyW/OoJfb/iTHeE96V3b1dgKG3FSFdd/0culnYWMkjcKCig== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.5.0" + babel-plugin-polyfill-regenerator "^0.3.0" + semver "^6.3.0" + +"@babel/plugin-transform-shorthand-properties@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" + integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-spread@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz#6ea7a6297740f381c540ac56caf75b05b74fb664" + integrity sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + +"@babel/plugin-transform-sticky-regex@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" + integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-template-literals@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" + integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-typeof-symbol@^7.16.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" + integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-unicode-escapes@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz#0d01fb7fb2243ae1c033f65f6e3b4be78db75f27" + integrity sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-unicode-regex@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" + integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/preset-env@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.17.10.tgz#a81b093669e3eb6541bb81a23173c5963c5de69c" + integrity sha512-YNgyBHZQpeoBSRBg0xixsZzfT58Ze1iZrajvv0lJc70qDDGuGfonEnMGfWeSY0mQ3JTuCWFbMkzFRVafOyJx4g== + dependencies: + "@babel/compat-data" "^7.17.10" + "@babel/helper-compilation-targets" "^7.17.10" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-option" "^7.16.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.7" + "@babel/plugin-proposal-async-generator-functions" "^7.16.8" + "@babel/plugin-proposal-class-properties" "^7.16.7" + "@babel/plugin-proposal-class-static-block" "^7.17.6" + "@babel/plugin-proposal-dynamic-import" "^7.16.7" + "@babel/plugin-proposal-export-namespace-from" "^7.16.7" + "@babel/plugin-proposal-json-strings" "^7.16.7" + "@babel/plugin-proposal-logical-assignment-operators" "^7.16.7" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.7" + "@babel/plugin-proposal-numeric-separator" "^7.16.7" + "@babel/plugin-proposal-object-rest-spread" "^7.17.3" + "@babel/plugin-proposal-optional-catch-binding" "^7.16.7" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + "@babel/plugin-proposal-private-methods" "^7.16.11" + "@babel/plugin-proposal-private-property-in-object" "^7.16.7" + "@babel/plugin-proposal-unicode-property-regex" "^7.16.7" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.16.7" + "@babel/plugin-transform-async-to-generator" "^7.16.8" + "@babel/plugin-transform-block-scoped-functions" "^7.16.7" + "@babel/plugin-transform-block-scoping" "^7.16.7" + "@babel/plugin-transform-classes" "^7.16.7" + "@babel/plugin-transform-computed-properties" "^7.16.7" + "@babel/plugin-transform-destructuring" "^7.17.7" + "@babel/plugin-transform-dotall-regex" "^7.16.7" + "@babel/plugin-transform-duplicate-keys" "^7.16.7" + "@babel/plugin-transform-exponentiation-operator" "^7.16.7" + "@babel/plugin-transform-for-of" "^7.16.7" + "@babel/plugin-transform-function-name" "^7.16.7" + "@babel/plugin-transform-literals" "^7.16.7" + "@babel/plugin-transform-member-expression-literals" "^7.16.7" + "@babel/plugin-transform-modules-amd" "^7.16.7" + "@babel/plugin-transform-modules-commonjs" "^7.17.9" + "@babel/plugin-transform-modules-systemjs" "^7.17.8" + "@babel/plugin-transform-modules-umd" "^7.16.7" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.17.10" + "@babel/plugin-transform-new-target" "^7.16.7" + "@babel/plugin-transform-object-super" "^7.16.7" + "@babel/plugin-transform-parameters" "^7.16.7" + "@babel/plugin-transform-property-literals" "^7.16.7" + "@babel/plugin-transform-regenerator" "^7.17.9" + "@babel/plugin-transform-reserved-words" "^7.16.7" + "@babel/plugin-transform-shorthand-properties" "^7.16.7" + "@babel/plugin-transform-spread" "^7.16.7" + "@babel/plugin-transform-sticky-regex" "^7.16.7" + "@babel/plugin-transform-template-literals" "^7.16.7" + "@babel/plugin-transform-typeof-symbol" "^7.16.7" + "@babel/plugin-transform-unicode-escapes" "^7.16.7" + "@babel/plugin-transform-unicode-regex" "^7.16.7" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.17.10" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.5.0" + babel-plugin-polyfill-regenerator "^0.3.0" + core-js-compat "^3.22.1" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" + integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.8.4": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/template@^7.16.7", "@babel/template@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" + integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/traverse@^7.13.0", "@babel/traverse@^7.17.10", "@babel/traverse@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.9.tgz#deeff3e8f1bad9786874cb2feda7a2d77a904f98" + integrity sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.9" + "@babel/types" "^7.18.9" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.16.7", "@babel/types@^7.17.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.4.4": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.9.tgz#7148d64ba133d8d73a41b3172ac4b83a1452205f" + integrity sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" + +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@csstools/postcss-color-function@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz#2bd36ab34f82d0497cfacdc9b18d34b5e6f64b6b" + integrity sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-font-format-keywords@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz#677b34e9e88ae997a67283311657973150e8b16a" + integrity sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-hwb-function@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz#ab54a9fce0ac102c754854769962f2422ae8aa8b" + integrity sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-ic-unit@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz#28237d812a124d1a16a5acc5c3832b040b303e58" + integrity sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-is-pseudo-class@^2.0.2": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz#846ae6c0d5a1eaa878fce352c544f9c295509cd1" + integrity sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA== + dependencies: + "@csstools/selector-specificity" "^2.0.0" + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-normalize-display-values@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz#15da54a36e867b3ac5163ee12c1d7f82d4d612c3" + integrity sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-oklab-function@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz#88cee0fbc8d6df27079ebd2fa016ee261eecf844" + integrity sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-progressive-custom-properties@^1.1.0", "@csstools/postcss-progressive-custom-properties@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz#542292558384361776b45c85226b9a3a34f276fa" + integrity sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-stepped-value-functions@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz#f8772c3681cc2befed695e2b0b1d68e22f08c4f4" + integrity sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-unset-value@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz#c99bb70e2cdc7312948d1eb41df2412330b81f77" + integrity sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g== + +"@csstools/selector-specificity@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" + integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== + +"@cypress/request@^2.88.10": + version "2.88.10" + resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.10.tgz#b66d76b07f860d3a4b8d7a0604d020c662752cce" + integrity sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + http-signature "~1.3.6" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^8.3.2" + +"@cypress/xvfb@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" + integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== + dependencies: + debug "^3.1.0" + lodash.once "^4.1.1" + +"@discoveryjs/json-ext@0.5.7": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + +"@ngtools/webpack@14.0.6": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-14.0.6.tgz#a48185b584a528a59ce82217830673268ceee8c2" + integrity sha512-mSmLqzRKxQgGiOhvJ8guvRLjXoTL17cVSWlL/Cz+Q3xc1bXa7537ZXBTQTEuZVU2ytdkniKc8l1HqXIx0pFNVQ== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@npmcli/fs@^1.0.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" + integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== + dependencies: + "@gar/promisify" "^1.0.1" + semver "^7.3.5" + +"@npmcli/fs@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.0.tgz#f2a21c28386e299d1a9fae8051d35ad180e33109" + integrity sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ== + dependencies: + "@gar/promisify" "^1.1.3" + semver "^7.3.5" + +"@npmcli/git@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-3.0.1.tgz#049b99b1381a2ddf7dc56ba3e91eaf76ca803a8d" + integrity sha512-UU85F/T+F1oVn3IsB/L6k9zXIMpXBuUBE25QDH0SsURwT6IOBqkC7M16uqo2vVZIyji3X1K4XH9luip7YekH1A== + dependencies: + "@npmcli/promise-spawn" "^3.0.0" + lru-cache "^7.4.4" + mkdirp "^1.0.4" + npm-pick-manifest "^7.0.0" + proc-log "^2.0.0" + promise-inflight "^1.0.1" + promise-retry "^2.0.1" + semver "^7.3.5" + which "^2.0.2" + +"@npmcli/installed-package-contents@^1.0.7": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa" + integrity sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw== + dependencies: + npm-bundled "^1.1.1" + npm-normalize-package-bin "^1.0.1" + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@npmcli/move-file@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.0.tgz#417f585016081a0184cef3e38902cd917a9bbd02" + integrity sha512-UR6D5f4KEGWJV6BGPH3Qb2EtgH+t+1XQ1Tt85c7qicN6cezzuHPdZwwAxqZr4JLtnQu0LZsTza/5gmNmSl8XLg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@npmcli/node-gyp@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz#8c20e53e34e9078d18815c1d2dda6f2420d75e35" + integrity sha512-doNI35wIe3bBaEgrlPfdJPaCpUR89pJWep4Hq3aRdh6gKazIVWfs0jHttvSSoq47ZXgC7h73kDsUl8AoIQUB+A== + +"@npmcli/promise-spawn@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz#53283b5f18f855c6925f23c24e67c911501ef573" + integrity sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g== + dependencies: + infer-owner "^1.0.4" + +"@npmcli/run-script@^3.0.1": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-3.0.3.tgz#66afa6e0c4c3484056195f295fa6c1d1a45ddf58" + integrity sha512-ZXL6qgC5NjwfZJ2nET+ZSLEz/PJgJ/5CU90C2S66dZY4Jw73DasS4ZCXuy/KHWYP0imjJ4VtA+Gebb5BxxKp9Q== + dependencies: + "@npmcli/node-gyp" "^2.0.0" + "@npmcli/promise-spawn" "^3.0.0" + node-gyp "^8.4.1" + read-package-json-fast "^2.0.3" + +"@schematics/angular@14.0.6": + version "14.0.6" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-14.0.6.tgz#56b16d830cdbc69a17767a033ed52e432c0ae514" + integrity sha512-vc4N6AXANMHUfcj5hOIDwBj4HQUrVSs03ksnznJGt2gkg2ClzJkK5Vg4/QA6lJ09VWSVZCuZ2Kkaua4bsTf6AA== + dependencies: + "@angular-devkit/core" "14.0.6" + "@angular-devkit/schematics" "14.0.6" + jsonc-parser "3.0.0" + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.4.5" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.5.tgz#acdfb7dd36b91cc5d812d7c093811a8f3d9b31e4" + integrity sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.29" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz#2a1795ea8e9e9c91b4a4bbe475034b20c1ec711c" + integrity sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/http-proxy@^1.17.8": + version "1.17.9" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" + integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== + dependencies: + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/node@*": + version "18.0.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.6.tgz#0ba49ac517ad69abe7a1508bc9b3a5483df9d5d7" + integrity sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw== + +"@types/node@^14.14.31": + version "14.18.22" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.22.tgz#fd2a15dca290fc9ad565b672fde746191cd0c6e6" + integrity sha512-qzaYbXVzin6EPjghf/hTdIbnVW1ErMx8rPzwRNJhlbyJhu2SyqlvjGOY/tbUt6VFyzg56lROcOeSQRInpt63Yw== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/sinonjs__fake-timers@8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" + integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== + +"@types/sizzle@^2.3.2": + version "2.3.3" + resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef" + integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ== + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + +"@types/yauzl@^2.9.1": + version "2.10.0" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599" + integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw== + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +"@yarnpkg/lockfile@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + +abab@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.4.1, acorn@^8.5.0: + version "8.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" + integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== + +adjust-sourcemap-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz#fc4a0fd080f7d10471f30a7320f25560ade28c99" + integrity sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A== + dependencies: + loader-utils "^2.0.0" + regex-parser "^2.2.11" + +agent-base@6, agent-base@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@^4.1.3, agentkeepalive@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" + integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== + dependencies: + debug "^4.1.0" + depd "^1.1.2" + humanize-ms "^1.2.1" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-formats@2.1.1, ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@8.11.0, ajv@^8.0.0, ajv@^8.8.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +arch@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + +are-we-there-yet@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d" + integrity sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975" + integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw== + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async@^3.2.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@^10.4.6: + version "10.4.7" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.7.tgz#1db8d195f41a52ca5069b7593be167618edbbedf" + integrity sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA== + dependencies: + browserslist "^4.20.3" + caniuse-lite "^1.0.30001335" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +babel-loader@8.2.5: + version "8.2.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" + integrity sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ== + dependencies: + find-cache-dir "^3.3.1" + loader-utils "^2.0.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-istanbul@6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-polyfill-corejs2@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" + integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.3.1" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" + integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + core-js-compat "^3.21.0" + +babel-plugin-polyfill-regenerator@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" + integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.2.0, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bl@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +blob-util@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb" + integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ== + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.0.13" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.13.tgz#4ac003dc1626023252d58adf2946f57e5da450c1" + integrity sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.14.5, browserslist@^4.20.2, browserslist@^4.20.3, browserslist@^4.21.2, browserslist@^4.9.1: + version "4.21.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.2.tgz#59a400757465535954946a400b841ed37e2b4ecf" + integrity sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA== + dependencies: + caniuse-lite "^1.0.30001366" + electron-to-chromium "^1.4.188" + node-releases "^2.0.6" + update-browserslist-db "^1.0.4" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@^5.5.0, buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +builtins@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" + integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + dependencies: + semver "^7.0.0" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cacache@16.0.7: + version "16.0.7" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.0.7.tgz#74a5d9bc4c17b4c0b373c1f5d42dadf5dc06638d" + integrity sha512-a4zfQpp5vm4Ipdvbj+ZrPonikRhm6WBEd4zT1Yc1DXsmAxrPgDwWBLF/u/wTVXSFPIgOJ1U3ghSa2Xm4s3h28w== + dependencies: + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + unique-filename "^1.1.1" + +cacache@^15.2.0: + version "15.3.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" + integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== + dependencies: + "@npmcli/fs" "^1.0.0" + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + +cacache@^16.0.0, cacache@^16.1.0: + version "16.1.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.1.tgz#4e79fb91d3efffe0630d5ad32db55cc1b870669c" + integrity sha512-VDKN+LHyCQXaaYZ7rA/qtkURU+/yYhviUdvqEv2LT6QPZU8jpyzEkEVAcKlKLt5dJ5BRp11ym8lo3NKLluEPLg== + dependencies: + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + unique-filename "^1.1.1" + +cachedir@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" + integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30001335, caniuse-lite@^1.0.30001366: + version "1.0.30001367" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz#2b97fe472e8fa29c78c5970615d7cd2ee414108a" + integrity sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0, chalk@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +check-more-types@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" + integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA== + +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +ci-info@^3.2.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128" + integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" + integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== + +cli-table3@~0.6.1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.2.tgz#aaf5df9d8b5bf12634dc8b3040806a0c07120d2a" + integrity sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +colorette@^2.0.10, colorette@^2.0.16: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== + +common-tags@^1.8.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.5.1, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +copy-anything@^2.0.1: + version "2.0.6" + resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.6.tgz#092454ea9584a7b7ad5573062b2a87f5900fc480" + integrity sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw== + dependencies: + is-what "^3.14.1" + +copy-webpack-plugin@10.2.4: + version "10.2.4" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-10.2.4.tgz#6c854be3fdaae22025da34b9112ccf81c63308fe" + integrity sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg== + dependencies: + fast-glob "^3.2.7" + glob-parent "^6.0.1" + globby "^12.0.2" + normalize-path "^3.0.0" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + +core-js-compat@^3.21.0, core-js-compat@^3.22.1: + version "3.23.5" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.23.5.tgz#11edce2f1c4f69a96d30ce77c805ce118909cd5b" + integrity sha512-fHYozIFIxd+91IIbXJgWd/igXIc8Mf9is0fusswjnGIWVG96y2cwyUdlCkGOw6rMLHKAxg7xtCIVaHsyOUnJIg== + dependencies: + browserslist "^4.21.2" + semver "7.0.0" + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cosmiconfig@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +critters@0.0.16: + version "0.0.16" + resolved "https://registry.yarnpkg.com/critters/-/critters-0.0.16.tgz#ffa2c5561a65b43c53b940036237ce72dcebfe93" + integrity sha512-JwjgmO6i3y6RWtLYmXwO5jMd+maZt8Tnfu7VVISmEWyQqfLpB8soBswf8/2bu6SBXxtKA68Al3c+qIG1ApT68A== + dependencies: + chalk "^4.1.0" + css-select "^4.2.0" + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter "^6.0.1" + postcss "^8.3.7" + pretty-bytes "^5.3.0" + +cross-spawn@^7.0.0, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-blank-pseudo@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz#36523b01c12a25d812df343a32c322d2a2324561" + integrity sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ== + dependencies: + postcss-selector-parser "^6.0.9" + +css-has-pseudo@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz#57f6be91ca242d5c9020ee3e51bbb5b89fc7af73" + integrity sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw== + dependencies: + postcss-selector-parser "^6.0.9" + +css-loader@6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" + integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.7" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.5" + +css-prefers-color-scheme@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz#ca8a22e5992c10a5b9d315155e7caee625903349" + integrity sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA== + +css-select@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== + dependencies: + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +css@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" + integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== + dependencies: + inherits "^2.0.4" + source-map "^0.6.1" + source-map-resolve "^0.6.0" + +cssdb@^6.6.1: + version "6.6.3" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-6.6.3.tgz#1f331a2fab30c18d9f087301e6122a878bb1e505" + integrity sha512-7GDvDSmE+20+WcSMhP17Q1EVWUrLlbxxpMDqG731n8P99JhnQZHR9YvtjPvEHfjFUjvQJvdpKCjlKOX+xe4UVA== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +"cypress@file:../../../cli": + version "0.0.0-development" + dependencies: + "@cypress/request" "^2.88.10" + "@cypress/xvfb" "^1.2.4" + "@types/node" "^14.14.31" + "@types/sinonjs__fake-timers" "8.1.1" + "@types/sizzle" "^2.3.2" + arch "^2.2.0" + blob-util "^2.0.2" + bluebird "^3.7.2" + buffer "^5.6.0" + cachedir "^2.3.0" + chalk "^4.1.0" + check-more-types "^2.24.0" + cli-cursor "^3.1.0" + cli-table3 "~0.6.1" + commander "^5.1.0" + common-tags "^1.8.0" + dayjs "^1.10.4" + debug "^4.3.2" + enquirer "^2.3.6" + eventemitter2 "^6.4.3" + execa "4.1.0" + executable "^4.1.1" + extract-zip "2.0.1" + figures "^3.2.0" + fs-extra "^9.1.0" + getos "^3.2.1" + is-ci "^3.0.0" + is-installed-globally "~0.4.0" + lazy-ass "^1.6.0" + listr2 "^3.8.3" + lodash "^4.17.21" + log-symbols "^4.0.0" + minimist "^1.2.6" + ospath "^1.2.2" + pretty-bytes "^5.6.0" + proxy-from-env "1.0.0" + request-progress "^3.0.0" + semver "^7.3.2" + supports-color "^8.1.1" + tmp "~0.2.1" + untildify "^4.0.0" + yauzl "^2.10.0" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + +dayjs@^1.10.4: + version "1.11.4" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.4.tgz#3b3c10ca378140d8917e06ebc13a4922af4f433e" + integrity sha512-Zj/lPM5hOvQ1Bf7uAvewDaUcsJoI6JmNqmHhHl3nyumwe0XHwt8sWdOVAPACJzCebL8gQCi+K49w7iKWnGwX9g== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^3.1.0, debug@^3.2.6: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA== + dependencies: + clone "^1.0.2" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@^1.1.2, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +dependency-graph@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27" + integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + +dns-packet@^5.2.2: + version "5.4.0" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" + integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.188: + version "1.4.192" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.192.tgz#fac050058b3e0713b401a1088cc579e14c2ab165" + integrity sha512-8nCXyIQY9An88NXAp+PuPy5h3/w5ZY7Iu2lag65Q0XREprcat5F8gKhoHsBUnQcFuCRnmevpR8yEBYRU3d2HDw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +encoding@^0.1.12, encoding@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^5.9.3: + version "5.10.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +enquirer@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + +errno@^0.1.1: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +esbuild-android-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.38.tgz#5b94a1306df31d55055f64a62ff6b763a47b7f64" + integrity sha512-aRFxR3scRKkbmNuGAK+Gee3+yFxkTJO/cx83Dkyzo4CnQl/2zVSurtG6+G86EQIZ+w+VYngVyK7P3HyTBKu3nw== + +esbuild-android-arm64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.38.tgz#78acc80773d16007de5219ccce544c036abd50b8" + integrity sha512-L2NgQRWuHFI89IIZIlpAcINy9FvBk6xFVZ7xGdOwIm8VyhX1vNCEqUJO3DPSSy945Gzdg98cxtNt8Grv1CsyhA== + +esbuild-darwin-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.38.tgz#e02b1291f629ebdc2aa46fabfacc9aa28ff6aa46" + integrity sha512-5JJvgXkX87Pd1Og0u/NJuO7TSqAikAcQQ74gyJ87bqWRVeouky84ICoV4sN6VV53aTW+NE87qLdGY4QA2S7KNA== + +esbuild-darwin-arm64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.38.tgz#01eb6650ec010b18c990e443a6abcca1d71290a9" + integrity sha512-eqF+OejMI3mC5Dlo9Kdq/Ilbki9sQBw3QlHW3wjLmsLh+quNfHmGMp3Ly1eWm981iGBMdbtSS9+LRvR2T8B3eQ== + +esbuild-freebsd-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.38.tgz#790b8786729d4aac7be17648f9ea8e0e16475b5e" + integrity sha512-epnPbhZUt93xV5cgeY36ZxPXDsQeO55DppzsIgWM8vgiG/Rz+qYDLmh5ts3e+Ln1wA9dQ+nZmVHw+RjaW3I5Ig== + +esbuild-freebsd-arm64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.38.tgz#b66340ab28c09c1098e6d9d8ff656db47d7211e6" + integrity sha512-/9icXUYJWherhk+y5fjPI5yNUdFPtXHQlwP7/K/zg8t8lQdHVj20SqU9/udQmeUo5pDFHMYzcEFfJqgOVeKNNQ== + +esbuild-linux-32@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.38.tgz#7927f950986fd39f0ff319e92839455912b67f70" + integrity sha512-QfgfeNHRFvr2XeHFzP8kOZVnal3QvST3A0cgq32ZrHjSMFTdgXhMhmWdKzRXP/PKcfv3e2OW9tT9PpcjNvaq6g== + +esbuild-linux-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.38.tgz#4893d07b229d9cfe34a2b3ce586399e73c3ac519" + integrity sha512-uuZHNmqcs+Bj1qiW9k/HZU3FtIHmYiuxZ/6Aa+/KHb/pFKr7R3aVqvxlAudYI9Fw3St0VCPfv7QBpUITSmBR1Q== + +esbuild-linux-arm64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.38.tgz#8442402e37d0b8ae946ac616784d9c1a2041056a" + integrity sha512-HlMGZTEsBrXrivr64eZ/EO0NQM8H8DuSENRok9d+Jtvq8hOLzrxfsAT9U94K3KOGk2XgCmkaI2KD8hX7F97lvA== + +esbuild-linux-arm@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.38.tgz#d5dbf32d38b7f79be0ec6b5fb2f9251fd9066986" + integrity sha512-FiFvQe8J3VKTDXG01JbvoVRXQ0x6UZwyrU4IaLBZeq39Bsbatd94Fuc3F1RGqPF5RbIWW7RvkVQjn79ejzysnA== + +esbuild-linux-mips64le@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.38.tgz#95081e42f698bbe35d8ccee0e3a237594b337eb5" + integrity sha512-qd1dLf2v7QBiI5wwfil9j0HG/5YMFBAmMVmdeokbNAMbcg49p25t6IlJFXAeLzogv1AvgaXRXvgFNhScYEUXGQ== + +esbuild-linux-ppc64le@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.38.tgz#dceb0a1b186f5df679618882a7990bd422089b47" + integrity sha512-mnbEm7o69gTl60jSuK+nn+pRsRHGtDPfzhrqEUXyCl7CTOCLtWN2bhK8bgsdp6J/2NyS/wHBjs1x8aBWwP2X9Q== + +esbuild-linux-riscv64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.38.tgz#61fb8edb75f475f9208c4a93ab2bfab63821afd2" + integrity sha512-+p6YKYbuV72uikChRk14FSyNJZ4WfYkffj6Af0/Tw63/6TJX6TnIKE+6D3xtEc7DeDth1fjUOEqm+ApKFXbbVQ== + +esbuild-linux-s390x@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.38.tgz#34c7126a4937406bf6a5e69100185fd702d12fe0" + integrity sha512-0zUsiDkGJiMHxBQ7JDU8jbaanUY975CdOW1YDrurjrM0vWHfjv9tLQsW9GSyEb/heSK1L5gaweRjzfUVBFoybQ== + +esbuild-netbsd-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.38.tgz#322ea9937d9e529183ee281c7996b93eb38a5d95" + integrity sha512-cljBAApVwkpnJZfnRVThpRBGzCi+a+V9Ofb1fVkKhtrPLDYlHLrSYGtmnoTVWDQdU516qYI8+wOgcGZ4XIZh0Q== + +esbuild-openbsd-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.38.tgz#1ca29bb7a2bf09592dcc26afdb45108f08a2cdbd" + integrity sha512-CDswYr2PWPGEPpLDUO50mL3WO/07EMjnZDNKpmaxUPsrW+kVM3LoAqr/CE8UbzugpEiflYqJsGPLirThRB18IQ== + +esbuild-sunos-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.38.tgz#c9446f7d8ebf45093e7bb0e7045506a88540019b" + integrity sha512-2mfIoYW58gKcC3bck0j7lD3RZkqYA7MmujFYmSn9l6TiIcAMpuEvqksO+ntBgbLep/eyjpgdplF7b+4T9VJGOA== + +esbuild-wasm@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.14.38.tgz#76a347f3e12d2ddd72f20fee0a43c3aee2c81665" + integrity sha512-mObTw5/3+KIOTShVgk3fuEn+INnHgOSbWJuGkInEZTWpUOh/+TCSgRxl5cDon4OkoaLU5rWm7R7Dkl/mJv8SGw== + +esbuild-windows-32@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.38.tgz#f8e9b4602fd0ccbd48e5c8d117ec0ba4040f2ad1" + integrity sha512-L2BmEeFZATAvU+FJzJiRLFUP+d9RHN+QXpgaOrs2klshoAm1AE6Us4X6fS9k33Uy5SzScn2TpcgecbqJza1Hjw== + +esbuild-windows-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.38.tgz#280f58e69f78535f470905ce3e43db1746518107" + integrity sha512-Khy4wVmebnzue8aeSXLC+6clo/hRYeNIm0DyikoEqX+3w3rcvrhzpoix0S+MF9vzh6JFskkIGD7Zx47ODJNyCw== + +esbuild-windows-arm64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.38.tgz#d97e9ac0f95a4c236d9173fa9f86c983d6a53f54" + integrity sha512-k3FGCNmHBkqdJXuJszdWciAH77PukEyDsdIryEHn9cKLQFxzhT39dSumeTuggaQcXY57UlmLGIkklWZo2qzHpw== + +esbuild@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.38.tgz#99526b778cd9f35532955e26e1709a16cca2fb30" + integrity sha512-12fzJ0fsm7gVZX1YQ1InkOE5f9Tl7cgf6JPYXRJtPIoE0zkWAbHdPHVPPaLi9tYAcEBqheGzqLn/3RdTOyBfcA== + optionalDependencies: + esbuild-android-64 "0.14.38" + esbuild-android-arm64 "0.14.38" + esbuild-darwin-64 "0.14.38" + esbuild-darwin-arm64 "0.14.38" + esbuild-freebsd-64 "0.14.38" + esbuild-freebsd-arm64 "0.14.38" + esbuild-linux-32 "0.14.38" + esbuild-linux-64 "0.14.38" + esbuild-linux-arm "0.14.38" + esbuild-linux-arm64 "0.14.38" + esbuild-linux-mips64le "0.14.38" + esbuild-linux-ppc64le "0.14.38" + esbuild-linux-riscv64 "0.14.38" + esbuild-linux-s390x "0.14.38" + esbuild-netbsd-64 "0.14.38" + esbuild-openbsd-64 "0.14.38" + esbuild-sunos-64 "0.14.38" + esbuild-windows-32 "0.14.38" + esbuild-windows-64 "0.14.38" + esbuild-windows-arm64 "0.14.38" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter-asyncresource@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz#734ff2e44bf448e627f7748f905d6bdd57bdb65b" + integrity sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ== + +eventemitter2@^6.4.3: + version "6.4.6" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.6.tgz#92d56569cc147a4d9b9da9e942e89b20ce236b0a" + integrity sha512-OHqo4wbHX5VbvlbB6o6eDwhYmiTjrpWACjF8Pmof/GTD6rdBNdZFNck3xlhqOiQFGCOoq3uzHvA0cQpFHIGVAQ== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +executable@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== + dependencies: + pify "^2.2.0" + +express@^4.17.3: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.0" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.10.3" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.7: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +figures@^3.0.0, figures@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +follow-redirects@^1.0.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^2.0.0, fs-minipass@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs-monkey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^5.0.0, get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +getos@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" + integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== + dependencies: + async "^3.2.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.1.tgz#00308f5c035aa0b2a447cd37ead267ddff1577d3" + integrity sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^8.0.1: + version "8.0.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" + integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== + dependencies: + ini "2.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@^12.0.2: + version "12.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-12.2.0.tgz#2ab8046b4fba4ff6eede835b29f678f90e3d3c22" + integrity sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA== + dependencies: + array-union "^3.0.1" + dir-glob "^3.0.1" + fast-glob "^3.2.7" + ignore "^5.1.9" + merge2 "^1.4.1" + slash "^4.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +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-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-symbols@^1.0.1, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hdr-histogram-js@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz#0b860534655722b6e3f3e7dca7b78867cf43dcb5" + integrity sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g== + dependencies: + "@assemblyscript/loader" "^0.10.1" + base64-js "^1.2.0" + pako "^1.0.3" + +hdr-histogram-percentiles-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz#9409f4de0c2dda78e61de2d9d78b1e9f3cba283c" + integrity sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw== + +hosted-git-info@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-5.0.0.tgz#df7a06678b4ebd722139786303db80fdf302ea56" + integrity sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q== + dependencies: + lru-cache "^7.5.1" + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" + integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + +http-cache-semantics@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" + integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw== + dependencies: + assert-plus "^1.0.0" + jsprim "^2.0.2" + sshpk "^1.14.1" + +https-proxy-agent@5.0.1, https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2, iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore-walk@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" + integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== + dependencies: + minimatch "^5.0.1" + +ignore@^5.1.9: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ== + +immutable@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef" + integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + +ini@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-3.0.0.tgz#2f6de95006923aa75feed8894f5686165adc08f1" + integrity sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw== + +inquirer@8.2.4: + version "8.2.4" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.4.tgz#ddbfe86ca2f67649a67daa6f1051c128f684f0b4" + integrity sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.1" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.21" + mute-stream "0.0.8" + ora "^5.4.1" + run-async "^2.4.0" + rxjs "^7.5.5" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + wrap-ansi "^7.0.0" + +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-ci@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== + dependencies: + ci-info "^3.2.0" + +is-core-module@^2.8.1, is-core-module@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + dependencies: + has "^1.0.3" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-what@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" + integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + +istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4: + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +json5@^2.1.2, json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +jsonc-parser@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonparse@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== + +jsprim@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d" + integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +karma-source-map-support@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz#58526ceccf7e8730e56effd97a4de8d712ac0d6b" + integrity sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A== + dependencies: + source-map-support "^0.5.5" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klona@^2.0.4, klona@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" + integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== + +lazy-ass@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" + integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw== + +less-loader@10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-10.2.0.tgz#97286d8797dc3dc05b1d16b0ecec5f968bdd4e32" + integrity sha512-AV5KHWvCezW27GT90WATaDnfXBv99llDbtaj4bshq6DvAihMdNjaPDcUMa6EXKLRF+P2opFenJp89BXg91XLYg== + dependencies: + klona "^2.0.4" + +less@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/less/-/less-4.1.2.tgz#6099ee584999750c2624b65f80145f8674e4b4b0" + integrity sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA== + dependencies: + copy-anything "^2.0.1" + parse-node-version "^1.0.1" + tslib "^2.3.0" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + make-dir "^2.1.0" + mime "^1.4.1" + needle "^2.5.2" + source-map "~0.6.0" + +license-webpack-plugin@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz#1e18442ed20b754b82f1adeff42249b81d11aec6" + integrity sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw== + dependencies: + webpack-sources "^3.0.0" + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +listr2@^3.8.3: + version "3.14.0" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" + integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.16" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.5.1" + through "^2.3.8" + wrap-ansi "^7.0.0" + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +loader-utils@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.0.tgz#bcecc51a7898bee7473d4bc6b845b23af8304d4f" + integrity sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ== + +loader-utils@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" + integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + +lodash.once@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@^4.0.0, log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: + version "7.13.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.13.1.tgz#267a81fbd0881327c46a81c5922606a2cfe336c4" + integrity sha512-CHqbAq7NFlW3RSnoWXLJBxCWaZVBrfa9UEHId2M3AW8iEBurbqduNexEUCGc3SHc6iCYXNJCDi903LajSVAEPQ== + +magic-string@0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.1.tgz#ba9b651354fa9512474199acecf9c6dbe93f97fd" + integrity sha512-ndThHmvgtieXe8J/VGPjG+Apu7v7ItcD5mhEIvOscWjPF/ccOiLxHaSuCAS2G+3x4GKsAbT8u7zdyamupui8Tg== + dependencies: + sourcemap-codec "^1.4.8" + +magic-string@^0.26.0: + version "0.26.2" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.2.tgz#5331700e4158cd6befda738bb6b0c7b93c0d4432" + integrity sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A== + dependencies: + sourcemap-codec "^1.4.8" + +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.2, make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-fetch-happen@^10.0.6: + version "10.1.8" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.1.8.tgz#3b6e93dd8d8fdb76c0d7bf32e617f37c3108435a" + integrity sha512-0ASJbG12Au6+N5I84W+8FhGS6iM8MyzvZady+zaQAu+6IOaESFzCLLD0AR1sAFF3Jufi8bxm586ABN6hWd3k7g== + dependencies: + agentkeepalive "^4.2.1" + cacache "^16.1.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-fetch "^2.0.3" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^9.0.0" + +make-fetch-happen@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" + integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.2.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.2" + promise-retry "^2.0.1" + socks-proxy-agent "^6.0.0" + ssri "^8.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.4.1, memfs@^3.4.3: + version "3.4.7" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" + integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== + dependencies: + fs-monkey "^1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0, mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mini-css-extract-plugin@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz#578aebc7fc14d32c0ad304c2c34f08af44673f5e" + integrity sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w== + dependencies: + schema-utils "^4.0.0" + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" + integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^1.3.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" + integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + +minipass-fetch@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.0.tgz#ca1754a5f857a3be99a9271277246ac0b44c3ff8" + integrity sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg== + dependencies: + minipass "^3.1.6" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-json-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" + integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== + dependencies: + jsonparse "^1.3.1" + minipass "^3.0.0" + +minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6: + version "3.3.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.4.tgz#ca99f95dd77c43c7a76bf51e6d200025eee0ffae" + integrity sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw== + dependencies: + yallist "^4.0.0" + +minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp@^1.0.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.0.0, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nanoid@^3.3.3, nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + +needle@^2.5.2: + version "2.9.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684" + integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.3, negotiator@^0.6.2, negotiator@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +nice-napi@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nice-napi/-/nice-napi-1.0.2.tgz#dc0ab5a1eac20ce548802fc5686eaa6bc654927b" + integrity sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA== + dependencies: + node-addon-api "^3.0.0" + node-gyp-build "^4.2.2" + +node-addon-api@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" + integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== + +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-gyp-build@^4.2.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" + integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg== + +node-gyp@^8.4.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" + integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^9.1.0" + nopt "^5.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + +normalize-package-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-4.0.0.tgz#1122d5359af21d4cd08718b92b058a658594177c" + integrity sha512-m+GL22VXJKkKbw62ZaBBjv8u6IE3UI4Mh5QakIqs3fWiKe0Xyi6L97hakwZK41/LD4R/2ly71Bayx0NLMwLA/g== + dependencies: + hosted-git-info "^5.0.0" + is-core-module "^2.8.1" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +npm-bundled@^1.1.1, npm-bundled@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" + integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-install-checks@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-5.0.0.tgz#5ff27d209a4e3542b8ac6b0c1db6063506248234" + integrity sha512-65lUsMI8ztHCxFz5ckCEC44DRvEGdZX5usQFriauxHEwt7upv1FKaQEmAtU0YnOAdwuNWCmk64xYiQABNrEyLA== + dependencies: + semver "^7.1.1" + +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-package-arg@9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-9.0.2.tgz#f3ef7b1b3b02e82564af2d5228b4c36567dcd389" + integrity sha512-v/miORuX8cndiOheW8p2moNuPJ7QhcFh9WGlTorruG8hXSA23vMTEp5hTCmDxic0nD8KHhj/NQgFuySD3GYY3g== + dependencies: + hosted-git-info "^5.0.0" + semver "^7.3.5" + validate-npm-package-name "^4.0.0" + +npm-package-arg@^9.0.0, npm-package-arg@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-9.1.0.tgz#a60e9f1e7c03e4e3e4e994ea87fff8b90b522987" + integrity sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw== + dependencies: + hosted-git-info "^5.0.0" + proc-log "^2.0.1" + semver "^7.3.5" + validate-npm-package-name "^4.0.0" + +npm-packlist@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.1.tgz#79bcaf22a26b6c30aa4dd66b976d69cc286800e0" + integrity sha512-UfpSvQ5YKwctmodvPPkK6Fwk603aoVsf8AEbmVKAEECrfvL8SSe1A2YIwrJ6xmTHAITKPwwZsWo7WwEbNk0kxw== + dependencies: + glob "^8.0.1" + ignore-walk "^5.0.1" + npm-bundled "^1.1.2" + npm-normalize-package-bin "^1.0.1" + +npm-pick-manifest@7.0.1, npm-pick-manifest@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-7.0.1.tgz#76dda30a7cd6b99be822217a935c2f5eacdaca4c" + integrity sha512-IA8+tuv8KujbsbLQvselW2XQgmXWS47t3CB0ZrzsRZ82DbDfkcFunOaPm4X7qNuhMfq+FmV7hQT4iFVpHqV7mg== + dependencies: + npm-install-checks "^5.0.0" + npm-normalize-package-bin "^1.0.1" + npm-package-arg "^9.0.0" + semver "^7.3.5" + +npm-registry-fetch@^13.0.1: + version "13.2.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-13.2.0.tgz#8ba2e801bee45b6dfa428367ab42b7d8dea3bfce" + integrity sha512-NEKnK02Co31+cnDtnAvEdq9xn6E9yKPK/aOHXZieVbw/qVOcFd7su6kviZjImYoszjM2GykMfGMiyyPUQjUkag== + dependencies: + make-fetch-happen "^10.0.6" + minipass "^3.1.6" + minipass-fetch "^2.0.3" + minipass-json-stream "^1.0.1" + minizlib "^2.1.2" + npm-package-arg "^9.0.1" + proc-log "^2.0.0" + +npm-run-path@^4.0.0, npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npmlog@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@8.4.0, open@^8.0.9: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +ora@5.4.1, ora@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + +ospath@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" + integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA== + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pacote@13.3.0: + version "13.3.0" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-13.3.0.tgz#e221febc17ce2435ce9f31de411832327a34c5ad" + integrity sha512-auhJAUlfC2TALo6I0s1vFoPvVFgWGx+uz/PnIojTTgkGwlK3Np8sGJ0ghfFhiuzJXTZoTycMLk8uLskdntPbDw== + dependencies: + "@npmcli/git" "^3.0.0" + "@npmcli/installed-package-contents" "^1.0.7" + "@npmcli/promise-spawn" "^3.0.0" + "@npmcli/run-script" "^3.0.1" + cacache "^16.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + infer-owner "^1.0.4" + minipass "^3.1.6" + mkdirp "^1.0.4" + npm-package-arg "^9.0.0" + npm-packlist "^5.0.0" + npm-pick-manifest "^7.0.0" + npm-registry-fetch "^13.0.1" + proc-log "^2.0.0" + promise-retry "^2.0.1" + read-package-json "^5.0.0" + read-package-json-fast "^2.0.3" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + +pako@^1.0.3: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse-node-version@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse5-html-rewriting-stream@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-6.0.1.tgz#de1820559317ab4e451ea72dba05fddfd914480b" + integrity sha512-vwLQzynJVEfUlURxgnf51yAJDQTtVpNyGD8tKi2Za7m+akukNHxCcUQMAa/mUGLhCeicFdpy7Tlvj8ZNKadprg== + dependencies: + parse5 "^6.0.1" + parse5-sax-parser "^6.0.1" + +parse5-htmlparser2-tree-adapter@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + +parse5-sax-parser@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz#98b4d366b5b266a7cd90b4b58906667af882daba" + integrity sha512-kXX+5S81lgESA0LsDuGjAlBybImAChYRMT+/uKCEXFBFOeEhS52qUCydGhU3qLRD8D9DVjaUo821WK7DM4iCeg== + dependencies: + parse5 "^6.0.1" + +parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.2.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +piscina@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/piscina/-/piscina-3.2.0.tgz#f5a1dde0c05567775690cccefe59d9223924d154" + integrity sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA== + dependencies: + eventemitter-asyncresource "^1.0.0" + hdr-histogram-js "^2.0.1" + hdr-histogram-percentiles-obj "^3.0.0" + optionalDependencies: + nice-napi "^1.0.2" + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +postcss-attribute-case-insensitive@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz#03d761b24afc04c09e757e92ff53716ae8ea2741" + integrity sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-clamp@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-clamp/-/postcss-clamp-4.1.0.tgz#7263e95abadd8c2ba1bd911b0b5a5c9c93e02363" + integrity sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-functional-notation@^4.2.2: + version "4.2.4" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz#21a909e8d7454d3612d1659e471ce4696f28caec" + integrity sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-hex-alpha@^8.0.3: + version "8.0.4" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz#c66e2980f2fbc1a63f5b079663340ce8b55f25a5" + integrity sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-rebeccapurple@^7.0.2: + version "7.1.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz#63fdab91d878ebc4dd4b7c02619a0c3d6a56ced0" + integrity sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-media@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz#c8f9637edf45fef761b014c024cee013f80529ea" + integrity sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-properties@^12.1.7: + version "12.1.8" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.8.tgz#aa003e1885c5bd28e2e32496cd597e389ca889e4" + integrity sha512-8rbj8kVu00RQh2fQF81oBqtduiANu4MIxhyf0HbbStgPtnFlWn0yiaYTpLHrPnJbffVY1s9apWsIoVZcc68FxA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-selectors@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz#1ab4684d65f30fed175520f82d223db0337239d9" + integrity sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-dir-pseudo-class@^6.0.4: + version "6.0.5" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz#2bf31de5de76added44e0a25ecf60ae9f7c7c26c" + integrity sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-double-position-gradients@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz#b96318fdb477be95997e86edd29c6e3557a49b91" + integrity sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-env-function@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-4.0.6.tgz#7b2d24c812f540ed6eda4c81f6090416722a8e7a" + integrity sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-focus-visible@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz#50c9ea9afa0ee657fb75635fabad25e18d76bf9e" + integrity sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-focus-within@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz#5b1d2ec603195f3344b716c0b75f61e44e8d2e20" + integrity sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-font-variant@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" + integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== + +postcss-gap-properties@^3.0.3: + version "3.0.5" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz#f7e3cddcf73ee19e94ccf7cb77773f9560aa2fff" + integrity sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg== + +postcss-image-set-function@^4.0.6: + version "4.0.7" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz#08353bd756f1cbfb3b6e93182c7829879114481f" + integrity sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-import@14.1.0: + version "14.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.1.0.tgz#a7333ffe32f0b8795303ee9e40215dac922781f0" + integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-initial@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" + integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== + +postcss-lab-function@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz#6fe4c015102ff7cd27d1bd5385582f67ebdbdc98" + integrity sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-loader@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.1.tgz#0895f7346b1702103d30fdc66e4d494a93c008ef" + integrity sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.5" + semver "^7.3.5" + +postcss-logical@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-5.0.4.tgz#ec75b1ee54421acc04d5921576b7d8db6b0e6f73" + integrity sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g== + +postcss-media-minmax@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz#7140bddec173e2d6d657edbd8554a55794e2a5b5" + integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-nesting@^10.1.4: + version "10.1.10" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.1.10.tgz#9c396df3d8232cbedfa95baaac6b765b8fd2a817" + integrity sha512-lqd7LXCq0gWc0wKXtoKDru5wEUNjm3OryLVNRZ8OnW8km6fSNUuFrjEhU3nklxXE2jvd4qrox566acgh+xQt8w== + dependencies: + "@csstools/selector-specificity" "^2.0.0" + postcss-selector-parser "^6.0.10" + +postcss-opacity-percentage@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz#bd698bb3670a0a27f6d657cc16744b3ebf3b1145" + integrity sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w== + +postcss-overflow-shorthand@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz#7ed6486fec44b76f0eab15aa4866cda5d55d893e" + integrity sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-page-break@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" + integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== + +postcss-place@^7.0.4: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-7.0.5.tgz#95dbf85fd9656a3a6e60e832b5809914236986c4" + integrity sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-preset-env@7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.5.0.tgz#0c1f23933597d55dab4a90f61eda30b76e710658" + integrity sha512-0BJzWEfCdTtK2R3EiKKSdkE51/DI/BwnhlnicSW482Ym6/DGHud8K0wGLcdjip1epVX0HKo4c8zzTeV/SkiejQ== + dependencies: + "@csstools/postcss-color-function" "^1.1.0" + "@csstools/postcss-font-format-keywords" "^1.0.0" + "@csstools/postcss-hwb-function" "^1.0.0" + "@csstools/postcss-ic-unit" "^1.0.0" + "@csstools/postcss-is-pseudo-class" "^2.0.2" + "@csstools/postcss-normalize-display-values" "^1.0.0" + "@csstools/postcss-oklab-function" "^1.1.0" + "@csstools/postcss-progressive-custom-properties" "^1.3.0" + "@csstools/postcss-stepped-value-functions" "^1.0.0" + "@csstools/postcss-unset-value" "^1.0.0" + autoprefixer "^10.4.6" + browserslist "^4.20.3" + css-blank-pseudo "^3.0.3" + css-has-pseudo "^3.0.4" + css-prefers-color-scheme "^6.0.3" + cssdb "^6.6.1" + postcss-attribute-case-insensitive "^5.0.0" + postcss-clamp "^4.1.0" + postcss-color-functional-notation "^4.2.2" + postcss-color-hex-alpha "^8.0.3" + postcss-color-rebeccapurple "^7.0.2" + postcss-custom-media "^8.0.0" + postcss-custom-properties "^12.1.7" + postcss-custom-selectors "^6.0.0" + postcss-dir-pseudo-class "^6.0.4" + postcss-double-position-gradients "^3.1.1" + postcss-env-function "^4.0.6" + postcss-focus-visible "^6.0.4" + postcss-focus-within "^5.0.4" + postcss-font-variant "^5.0.0" + postcss-gap-properties "^3.0.3" + postcss-image-set-function "^4.0.6" + postcss-initial "^4.0.1" + postcss-lab-function "^4.2.0" + postcss-logical "^5.0.4" + postcss-media-minmax "^5.0.0" + postcss-nesting "^10.1.4" + postcss-opacity-percentage "^1.1.2" + postcss-overflow-shorthand "^3.0.3" + postcss-page-break "^3.0.4" + postcss-place "^7.0.4" + postcss-pseudo-class-any-link "^7.1.2" + postcss-replace-overflow-wrap "^4.0.0" + postcss-selector-not "^5.0.0" + postcss-value-parser "^4.2.0" + +postcss-pseudo-class-any-link@^7.1.2: + version "7.1.6" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz#2693b221902da772c278def85a4d9a64b6e617ab" + integrity sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-replace-overflow-wrap@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" + integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== + +postcss-selector-not@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-5.0.0.tgz#ac5fc506f7565dd872f82f5314c0f81a05630dc7" + integrity sha512-/2K3A4TCP9orP4TNS7u3tGdRFVKqz/E6pX3aGnriPG0jU78of8wsUcqE4QAhWEU0d+WnMSF93Ah3F//vUtK+iQ== + dependencies: + balanced-match "^1.0.0" + +postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.9: + version "6.0.10" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@8.4.13: + version "8.4.13" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.13.tgz#7c87bc268e79f7f86524235821dfdf9f73e5d575" + integrity sha512-jtL6eTBrza5MPzy8oJLFuUscHDXTV5KcLlqAWHl5q5WYRfnNRGSmOZmOZ1T6Gy7A99mOZfqungmZMpMmCVJ8ZA== + dependencies: + nanoid "^3.3.3" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +postcss@^8.2.14, postcss@^8.3.7, postcss@^8.4.7: + version "8.4.14" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" + integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +pretty-bytes@^5.3.0, pretty-bytes@^5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== + +proc-log@^2.0.0, proc-log@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-2.0.1.tgz#8f3f69a1f608de27878f91f5c688b225391cb685" + integrity sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +proxy-from-env@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + +psl@^1.1.28: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + +read-package-json-fast@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz#323ca529630da82cb34b36cc0b996693c98c2b83" + integrity sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ== + dependencies: + json-parse-even-better-errors "^2.3.0" + npm-normalize-package-bin "^1.0.1" + +read-package-json@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-5.0.1.tgz#1ed685d95ce258954596b13e2e0e76c7d0ab4c26" + integrity sha512-MALHuNgYWdGW3gKzuNMuYtcSSZbGQm94fAp16xt8VsYTLBjUSc55bLMKe6gzpWue0Tfi6CBgwCSdDAqutGDhMg== + dependencies: + glob "^8.0.1" + json-parse-even-better-errors "^2.3.1" + normalize-package-data "^4.0.0" + npm-normalize-package-bin "^1.0.1" + +readable-stream@^2.0.1: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6, readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +reflect-metadata@^0.1.2: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@0.13.9, regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +regenerator-transform@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" + integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + +regexpu-core@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d" + integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== + +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== + dependencies: + jsesc "~0.5.0" + +request-progress@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" + integrity sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg== + dependencies: + throttleit "^1.0.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url-loader@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz#ee3142fb1f1e0d9db9524d539cfa166e9314f795" + integrity sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg== + dependencies: + adjust-sourcemap-loader "^4.0.0" + convert-source-map "^1.7.0" + loader-utils "^2.0.0" + postcss "^8.2.14" + source-map "0.6.1" + +resolve@1.22.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^1.1.7, resolve@^1.14.2: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@6.6.7: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== + dependencies: + tslib "^1.9.0" + +rxjs@^7.5.1, rxjs@^7.5.5, rxjs@~7.5.0: + version "7.5.6" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" + integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw== + dependencies: + tslib "^2.1.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@^2.1.2, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass-loader@12.6.0: + version "12.6.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.6.0.tgz#5148362c8e2cdd4b950f3c63ac5d16dbfed37bcb" + integrity sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA== + dependencies: + klona "^2.0.4" + neo-async "^2.6.2" + +sass@1.51.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.51.0.tgz#25ea36cf819581fe1fe8329e8c3a4eaaf70d2845" + integrity sha512-haGdpTgywJTvHC2b91GSq+clTKGbtkkZmVAb82jZQN/wTy6qs8DdFm2lhEQbEwrY0QDRgSQ3xDurqM977C3noA== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +sax@^1.2.4, sax@~1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^2.6.5: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" + integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== + dependencies: + node-forge "^1" + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@7.3.7, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.5: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +sockjs@^0.3.21: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +socks-proxy-agent@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz#2687a31f9d7185e38d530bef1944fe1f1496d6ce" + integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks@^2.6.2: + version "2.7.0" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.0.tgz#f9225acdb841e874dca25f870e9130990f3913d0" + integrity sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-loader@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.1.tgz#9ae5edc7c2d42570934be4c95d1ccc6352eba52d" + integrity sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA== + dependencies: + abab "^2.0.5" + iconv-lite "^0.6.3" + source-map-js "^1.0.1" + +source-map-resolve@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" + integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + +source-map-support@0.5.21, source-map-support@^0.5.5, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +source-map@^0.7.3: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + +source-map@~0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +sshpk@^1.14.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^8.0.0, ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + +ssri@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" + integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== + dependencies: + minipass "^3.1.1" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +stylus-loader@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-6.2.0.tgz#0ba499e744e7fb9d9b3977784c8639728a7ced8c" + integrity sha512-5dsDc7qVQGRoc6pvCL20eYgRUxepZ9FpeK28XhdXaIPP6kXr6nI1zAAKFQgP5OBkOfKaURp4WUpJzspg1f01Gg== + dependencies: + fast-glob "^3.2.7" + klona "^2.0.4" + normalize-path "^3.0.0" + +stylus@0.57.0: + version "0.57.0" + resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.57.0.tgz#a46f04f426c19ceef54abb1a9d189fd4e886df41" + integrity sha512-yOI6G8WYfr0q8v8rRvE91wbxFU+rJPo760Va4MF6K0I6BZjO4r+xSynkvyPBP9tV1CIEUeRsiidjIs2rzb1CnQ== + dependencies: + css "^3.0.0" + debug "^4.3.2" + glob "^7.1.6" + safer-buffer "^2.1.2" + sax "~1.2.4" + source-map "^0.7.3" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0, supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +symbol-observable@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" + integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: + version "6.1.11" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" + integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +terser-webpack-plugin@^5.1.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz#8033db876dd5875487213e87c627bca323e5ed90" + integrity sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.7" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + terser "^5.7.2" + +terser@5.13.1: + version "5.13.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.13.1.tgz#66332cdc5a01b04a224c9fad449fc1a18eaa1799" + integrity sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA== + dependencies: + acorn "^8.5.0" + commander "^2.20.0" + source-map "~0.8.0-beta.0" + source-map-support "~0.5.20" + +terser@^5.7.2: + version "5.14.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +text-table@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +throttleit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" + integrity sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g== + +through@^2.3.6, through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmp@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== + dependencies: + punycode "^2.1.0" + +tree-kill@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +tslib@2.4.0, tslib@^2.1.0, tslib@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +tslib@^1.9.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typed-assert@^1.0.8: + version "1.0.9" + resolved "https://registry.yarnpkg.com/typed-assert/-/typed-assert-1.0.9.tgz#8af9d4f93432c4970ec717e3006f33f135b06213" + integrity sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg== + +typescript@~4.7.2: + version "4.7.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + +update-browserslist-db@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@8.3.2, uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +validate-npm-package-license@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validate-npm-package-name@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz#fe8f1c50ac20afdb86f177da85b3600f0ac0d747" + integrity sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q== + dependencies: + builtins "^5.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +watchpack@^2.3.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== + dependencies: + defaults "^1.0.3" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-dev-middleware@5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" + integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== + dependencies: + colorette "^2.0.10" + memfs "^3.4.1" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.0.tgz#737dbf44335bb8bde68f8f39127fc401c97a1557" + integrity sha512-+Nlb39iQSOSsFv0lWUuUTim3jDQO8nhK3E68f//J2r5rIcp4lULHXz2oZ0UVdEeWXEh5lSzYUlzarZhDAeAVQw== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.0.1" + serve-index "^1.9.1" + sockjs "^0.3.21" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" + +webpack-merge@5.8.0: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.0.0, webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack-subresource-integrity@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz#8b7606b033c6ccac14e684267cb7fb1f5c2a132a" + integrity sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q== + dependencies: + typed-assert "^1.0.8" + +webpack@5.72.1: + version "5.72.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.72.1.tgz#3500fc834b4e9ba573b9f430b2c0a61e1bb57d13" + integrity sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.9.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.3.1" + webpack-sources "^3.2.3" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which@^2.0.1, which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^8.4.2: + version "8.8.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" + integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^21.0.0: + version "21.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" + integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== + +yargs@17.4.1: + version "17.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.1.tgz#ebe23284207bb75cee7c408c33e722bfb27b5284" + integrity sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + +yargs@^17.2.1: + version "17.5.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" + integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +zone.js@~0.11.4: + version "0.11.6" + resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.6.tgz#c7cacfc298fe24bb585329ca04a44d9e2e840e74" + integrity sha512-umJqFtKyZlPli669gB1gOrRE9hxUUGkZr7mo878z+NEBJZZixJkKeVYfnoLa7g25SseUDc92OZrMKKHySyJrFg== + dependencies: + tslib "^2.3.0" diff --git a/system-tests/test/component_testing_spec.ts b/system-tests/test/component_testing_spec.ts index fbe38e3786e3..355781b8fe80 100644 --- a/system-tests/test/component_testing_spec.ts +++ b/system-tests/test/component_testing_spec.ts @@ -123,6 +123,14 @@ describe(`Angular CLI major versions`, () => { expectedExitCode: 0, }) } + + systemTests.it('angular 14 custom config with mount tests', { + project: 'angular-custom-config', + spec: 'src/app/my-component.cy.ts', + testingType: 'component', + browser: 'chrome', + expectedExitCode: 0, + }) }) describe('experimentalSingleTabRunMode', function () { From 5db08bc6ac8d68bb41e8d2ff36de987d34163ba1 Mon Sep 17 00:00:00 2001 From: Jordan Date: Tue, 23 Aug 2022 20:03:33 -0400 Subject: [PATCH 20/45] chore: rename types, add comments --- cli/types/cypress.d.ts | 4 ++-- npm/webpack-dev-server/src/devServer.ts | 2 +- npm/webpack-dev-server/src/helpers/angularHandler.ts | 6 ++---- .../angular-custom-config/src/app/my-component.cy.ts | 3 +++ system-tests/test/component_testing_spec.ts | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index d4062d96813f..de8f85ae1a1e 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -3047,7 +3047,7 @@ declare namespace Cypress { type PickConfigOpt = T extends keyof DefineDevServerConfig ? DefineDevServerConfig[T] : any - type ProjectConfig = { + type AngularDevServerProjectConfig = { root: string, sourceRoot: string, buildOptions: Record @@ -3068,7 +3068,7 @@ declare namespace Cypress { framework: 'angular', webpackConfig?: PickConfigOpt<'webpackConfig'>, options?: { - projectConfig: ProjectConfig + projectConfig: AngularDevServerProjectConfig } } diff --git a/npm/webpack-dev-server/src/devServer.ts b/npm/webpack-dev-server/src/devServer.ts index ebf9eb45694e..7c68700a70f7 100644 --- a/npm/webpack-dev-server/src/devServer.ts +++ b/npm/webpack-dev-server/src/devServer.ts @@ -25,7 +25,7 @@ export type WebpackDevServerConfig = { framework?: typeof ALL_FRAMEWORKS[number] // Add frameworks here as we implement webpackConfig?: unknown // Derived from the user's webpack options?: { - projectConfig?: Cypress.ProjectConfig + projectConfig?: Cypress.AngularDevServerProjectConfig } } diff --git a/npm/webpack-dev-server/src/helpers/angularHandler.ts b/npm/webpack-dev-server/src/helpers/angularHandler.ts index d56b69c05352..2619f1b8fdab 100644 --- a/npm/webpack-dev-server/src/helpers/angularHandler.ts +++ b/npm/webpack-dev-server/src/helpers/angularHandler.ts @@ -13,8 +13,6 @@ type Configurations = { } } -export type MyType = Extract - export type AngularJsonProjectConfig = { projectType: string root: string @@ -33,7 +31,7 @@ type AngularJson = { const dynamicImport = new Function('specifier', 'return import(specifier)') -async function getProjectConfig (projectRoot: string): Promise { +async function getProjectConfig (projectRoot: string): Promise { const angularJson = await getAngularJson(projectRoot) let { defaultProject } = angularJson @@ -199,7 +197,7 @@ export async function getAngularJson (projectRoot: string): Promise return JSON.parse(angularJson) } -function createFakeContext (projectRoot: string, defaultProjectConfig: Cypress.ProjectConfig) { +function createFakeContext (projectRoot: string, defaultProjectConfig: Cypress.AngularDevServerProjectConfig) { const logger = { createChild: () => ({}), } diff --git a/system-tests/projects/angular-custom-config/src/app/my-component.cy.ts b/system-tests/projects/angular-custom-config/src/app/my-component.cy.ts index 01c5c548bc1d..6465f17c6697 100644 --- a/system-tests/projects/angular-custom-config/src/app/my-component.cy.ts +++ b/system-tests/projects/angular-custom-config/src/app/my-component.cy.ts @@ -3,6 +3,9 @@ import { MyComponent } from './my-component' describe('MyComponent', () => { it('should mount with an h1 tag with a class of very-red', () => { cy.mount(MyComponent) + // Proves out the Angular specific `projectConfig` option. The global styles in `custom-styles.scss` would not normally be applied with how this project's `angular.json` + // is configured. By utilizing the `projectConfig` option in `component.devServer.options`, we can change the + // build options to allow this global style to be loaded cy.get('h1').should('have.css', 'color', 'rgb(255, 0, 0)') }) }) diff --git a/system-tests/test/component_testing_spec.ts b/system-tests/test/component_testing_spec.ts index 355781b8fe80..8f29b1c82ba0 100644 --- a/system-tests/test/component_testing_spec.ts +++ b/system-tests/test/component_testing_spec.ts @@ -124,7 +124,7 @@ describe(`Angular CLI major versions`, () => { }) } - systemTests.it('angular 14 custom config with mount tests', { + systemTests.it('angular 14 custom config', { project: 'angular-custom-config', spec: 'src/app/my-component.cy.ts', testingType: 'component', From 7b5e74cd5a094a06f4197f5677eff47ab869a1bc Mon Sep 17 00:00:00 2001 From: Blue F Date: Wed, 24 Aug 2022 08:45:01 -0700 Subject: [PATCH 21/45] chore: fix for regression from last refactor (#23520) --- .../driver/cypress/e2e/commands/assertions.cy.js | 13 +++++++++++++ packages/driver/src/cy/assertions.ts | 4 ++-- yarn.lock | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/driver/cypress/e2e/commands/assertions.cy.js b/packages/driver/cypress/e2e/commands/assertions.cy.js index 7e6d62e59724..2ccbb233d8d7 100644 --- a/packages/driver/cypress/e2e/commands/assertions.cy.js +++ b/packages/driver/cypress/e2e/commands/assertions.cy.js @@ -612,6 +612,19 @@ describe('src/cy/commands/assertions', () => { cy.get('button:first').should('have.class', 'does-not-have-class') }) + it('has a pending state while retrying', (done) => { + cy.on('command:retry', (command) => { + const [getLog, shouldLog] = cy.state('current').get('logs') + + expect(getLog.get('state')).to.eq('pending') + expect(shouldLog.get('state')).to.eq('pending') + + done() + }) + + cy.get('button:first', { timeout: 100 }).should('have.class', 'does-not-have-class') + }) + it('throws when the subject isnt in the DOM', function (done) { cy.$$('button:first').click(function () { $(this).addClass('foo').remove() diff --git a/packages/driver/src/cy/assertions.ts b/packages/driver/src/cy/assertions.ts index 1fee4b240db7..237ce44a1b18 100644 --- a/packages/driver/src/cy/assertions.ts +++ b/packages/driver/src/cy/assertions.ts @@ -333,12 +333,12 @@ export const create = (Cypress: ICypress, cy: $Cy) => { try { if (_.isFunction(onFail)) { // pass in the err and the upcoming assertion commands + finishAssertions() onFail.call(this, err, isDefaultAssertionErr, cmds) } } catch (e3) { - throw e3 - } finally { finishAssertions() + throw e3 } if (_.isFunction(onRetry)) { diff --git a/yarn.lock b/yarn.lock index 26bbccef00e7..b048b3221dc0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35841,4 +35841,4 @@ zone.js@~0.11.4: resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.7.tgz#262194267c7b964e8da77ce16b9fba9bea23cfdc" integrity sha512-e39K2EdK5JfA3FDuUTVRvPlYV4aBfnOOcGuILhQAT7nzeV12uSrLBzImUM9CDVoncDSX4brR/gwqu0heQ3BQ0g== dependencies: - tslib "^2.3.0" \ No newline at end of file + tslib "^2.3.0" From f88536b7ad73ff314792ca983a0a0929e6166c66 Mon Sep 17 00:00:00 2001 From: Kozlov Sergey Date: Wed, 24 Aug 2022 19:15:51 +0300 Subject: [PATCH 22/45] fix: prevent deliver global Nullable type (#23439) --- cli/types/cypress-type-helpers.d.ts | 4 +++- cli/types/cypress.d.ts | 1 + packages/driver/src/cy/keyboard.ts | 2 +- packages/driver/src/cy/testConfigOverrides.ts | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cli/types/cypress-type-helpers.d.ts b/cli/types/cypress-type-helpers.d.ts index efba383d4e52..391831e7bcbb 100644 --- a/cli/types/cypress-type-helpers.d.ts +++ b/cli/types/cypress-type-helpers.d.ts @@ -1,2 +1,4 @@ // type helpers -type Nullable = T | null +declare namespace Cypress { + type Nullable = T | null +} diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 8c6a20e487af..20b034c05a3b 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -1,5 +1,6 @@ /// /// +/// declare namespace Cypress { type FileContents = string | any[] | object diff --git a/packages/driver/src/cy/keyboard.ts b/packages/driver/src/cy/keyboard.ts index 07d25d9ecb5e..485687fb13e0 100644 --- a/packages/driver/src/cy/keyboard.ts +++ b/packages/driver/src/cy/keyboard.ts @@ -876,7 +876,7 @@ export class Keyboard { let charCode: number | undefined let keyCode: number | undefined let which: number | undefined - let data: Nullable | undefined + let data: Cypress.Nullable | undefined let location: number | undefined = keyDetails.location || 0 let key: string | undefined let code: string | undefined = keyDetails.code diff --git a/packages/driver/src/cy/testConfigOverrides.ts b/packages/driver/src/cy/testConfigOverrides.ts index 021656cb5542..5a49371c18b3 100644 --- a/packages/driver/src/cy/testConfigOverrides.ts +++ b/packages/driver/src/cy/testConfigOverrides.ts @@ -155,7 +155,7 @@ export function getResolvedTestConfigOverride (test): ResolvedTestConfigOverride } export class TestConfigOverride { - private restoreTestConfigFn: Nullable<() => void> = null + private restoreTestConfigFn: Cypress.Nullable<() => void> = null restoreAndSetTestConfigOverrides (test, config, env) { if (this.restoreTestConfigFn) this.restoreTestConfigFn() From f743a45930c530f17bc040f14aeb8dbc402864aa Mon Sep 17 00:00:00 2001 From: Emil Goldsmith Olesen Date: Wed, 24 Aug 2022 21:50:08 +0200 Subject: [PATCH 23/45] feat: Expose setSystemTime on clock object (#23329) Co-authored-by: Emily Rohrbough --- cli/types/cypress.d.ts | 20 +++++ cli/types/tests/cypress-tests.ts | 18 +++++ .../driver/cypress/e2e/commands/clock.cy.js | 79 +++++++++++++++++++ packages/driver/src/cypress/clock.ts | 6 ++ 4 files changed, 123 insertions(+) diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 20b034c05a3b..9c034ff6d826 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -5784,6 +5784,26 @@ declare namespace Cypress { * cy.clock().invoke('restore') */ restore(): void + /** + * Change the time without invoking any timers. + * + * Default value with no argument or undefined is 0. + * + * This can be useful if you need to change the time by an hour + * while there is a setInterval registered that may otherwise run thousands + * of times. + * @see https://on.cypress.io/clock + * @example + * cy.clock() + * cy.visit('/') + * ... + * cy.clock().then(clock => { + * clock.setSystemTime(60 * 60 * 1000) + * }) + * // or use this shortcut + * cy.clock().invoke('setSystemTime', 60 * 60 * 1000) + */ + setSystemTime(now?: number | Date): void } interface Cookie { diff --git a/cli/types/tests/cypress-tests.ts b/cli/types/tests/cypress-tests.ts index 2f7202713699..f13753aedc71 100644 --- a/cli/types/tests/cypress-tests.ts +++ b/cli/types/tests/cypress-tests.ts @@ -682,6 +682,24 @@ namespace CypressClockTests { }) // restoring the clock shortcut cy.clock().invoke('restore') + // setting system time with no argument + cy.clock().then(clock => { + clock.setSystemTime() + }) + // setting system time with timestamp + cy.clock().then(clock => { + clock.setSystemTime(1000) + }) + // setting system time with date object + cy.clock().then(clock => { + clock.setSystemTime(new Date(2019, 3, 2)) + }) + // setting system time with no argument and shortcut + cy.clock().invoke('setSystemTime') + // setting system time with timestamp and shortcut + cy.clock().invoke('setSystemTime', 1000) + // setting system time with date object and shortcut + cy.clock().invoke('setSystemTime', new Date(2019, 3, 2)) } namespace CypressContainsTests { diff --git a/packages/driver/cypress/e2e/commands/clock.cy.js b/packages/driver/cypress/e2e/commands/clock.cy.js index c16a8daa33eb..46f455a8b792 100644 --- a/packages/driver/cypress/e2e/commands/clock.cy.js +++ b/packages/driver/cypress/e2e/commands/clock.cy.js @@ -59,6 +59,85 @@ describe('src/cy/commands/clock', () => { }) }) + context('setSystemTime', () => { + it('takes number now arg', () => { + const now = 1111111111111 + + cy.clock().then(function (clock) { + expect(new this.window.Date().getTime()).to.equal(0) + clock.setSystemTime(now) + expect(new this.window.Date().getTime()).to.equal(now) + }) + }) + + it('takes Date now arg', () => { + // April 15, 2017 + const now = new Date(2017, 3, 15) + const nowTimestamp = now.getTime() + + cy.clock().then(function (clock) { + expect(new this.window.Date().getTime()).to.equal(0) + clock.setSystemTime(now) + expect(new this.window.Date().getTime()).to.equal(nowTimestamp) + }) + }) + + it('defaults to 0 ms with no argument', () => { + const now = 1111111111111 + + cy.clock(now).then(function (clock) { + expect(new this.window.Date().getTime()).to.equal(now) + clock.setSystemTime() + expect(new this.window.Date().getTime()).to.equal(0) + }) + }) + + it('combines correctly with tick', () => { + const now = 1111111111111 + + cy.clock().then(function (clock) { + expect(new this.window.Date().getTime()).to.equal(0) + clock.tick(4321) + expect(new this.window.Date().getTime()).to.equal(4321) + clock.setSystemTime(now) + expect(new this.window.Date().getTime()).to.equal(now) + clock.tick(4321) + expect(new this.window.Date().getTime()).to.equal(now + 4321) + }) + }) + + it('doesn\'t call timers on setSystemTime, but does on tick', function () { + cy.clock().then(function (clock) { + let callCount = 0 + + this.window.setTimeout(() => { + callCount++ + }) + + clock.setSystemTime(1111111) + expect(callCount).to.equal(0) + clock.tick() + expect(callCount).to.equal(1) + }) + }) + + it('doesn\'t shift the time left for timers to trigger', function () { + cy.clock(0).then(function (clock) { + let callCount = 0 + + this.window.setTimeout(() => { + callCount++ + }, 100) + + clock.setSystemTime(1111111) + clock.tick(99) + expect(callCount).to.equal(0) + clock.tick(1) + expect(callCount).to.equal(1) + }) + }) + }) + it('restores window time methods when calling restore', (done) => { cy.clock().then(function (clock) { this.window.setTimeout(() => { diff --git a/packages/driver/src/cypress/clock.ts b/packages/driver/src/cypress/clock.ts index 9d15b8e6982d..c6872573bf39 100644 --- a/packages/driver/src/cypress/clock.ts +++ b/packages/driver/src/cypress/clock.ts @@ -46,11 +46,17 @@ export const create = (win, now, methods) => { return _.pick(clock, 'now', 'methods') } + const setSystemTime = (now) => { + clock.setSystemTime(now) + } + return { tick, restore, + setSystemTime, + bind, details, From 9e94f561c0c11cb270478501eb941dca3c6598b1 Mon Sep 17 00:00:00 2001 From: Zachary Williams Date: Wed, 24 Aug 2022 17:33:58 -0500 Subject: [PATCH 24/45] fix tests and types --- cli/types/cypress.d.ts | 2 +- npm/webpack-dev-server/src/devServer.ts | 22 +-- .../src/helpers/angularHandler.ts | 12 +- .../helpers/sourceRelativeWebpackModules.ts | 4 +- .../test/handlers/angularHandler.spec.ts | 151 ++++++++++++------ .../test/test-helpers/scaffoldProject.ts | 2 +- 6 files changed, 126 insertions(+), 67 deletions(-) diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index de8f85ae1a1e..731a3820a193 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -3047,7 +3047,7 @@ declare namespace Cypress { type PickConfigOpt = T extends keyof DefineDevServerConfig ? DefineDevServerConfig[T] : any - type AngularDevServerProjectConfig = { + interface AngularDevServerProjectConfig { root: string, sourceRoot: string, buildOptions: Record diff --git a/npm/webpack-dev-server/src/devServer.ts b/npm/webpack-dev-server/src/devServer.ts index 7c68700a70f7..5c7a17c1b2bc 100644 --- a/npm/webpack-dev-server/src/devServer.ts +++ b/npm/webpack-dev-server/src/devServer.ts @@ -16,20 +16,24 @@ import { angularHandler } from './helpers/angularHandler' const debug = debugLib('cypress:webpack-dev-server:devServer') +export type Frameworks = Extract['framework'] + +type FrameworkConfig = { + framework?: Exclude +} | { + framework: 'angular' + options?: { + projectConfig?: Cypress.AngularDevServerProjectConfig + } +} + export type WebpackDevServerConfig = { specs: Cypress.Spec[] cypressConfig: Cypress.PluginConfigOptions devServerEvents: NodeJS.EventEmitter onConfigNotFound?: (devServer: 'webpack', cwd: string, lookedIn: string[]) => void -} & { - framework?: typeof ALL_FRAMEWORKS[number] // Add frameworks here as we implement webpackConfig?: unknown // Derived from the user's webpack - options?: { - projectConfig?: Cypress.AngularDevServerProjectConfig - } -} - -export const ALL_FRAMEWORKS = ['create-react-app', 'nuxt', 'react', 'vue-cli', 'next', 'vue', 'angular'] as const +} & FrameworkConfig /** * @internal @@ -128,7 +132,7 @@ async function getPreset (devServerConfig: WebpackDevServerConfig): Promise +export type BuildOptions = Record + +export type AngularWebpackDevServerConfig = Extract type Configurations = { configurations?: { @@ -31,7 +33,7 @@ type AngularJson = { const dynamicImport = new Function('specifier', 'return import(specifier)') -async function getProjectConfig (projectRoot: string): Promise { +export async function getProjectConfig (projectRoot: string): Promise { const angularJson = await getAngularJson(projectRoot) let { defaultProject } = angularJson @@ -106,7 +108,7 @@ export function getAngularBuildOptions (buildOptions: BuildOptions, tsConfig: st } } -export async function generateTsConfig (devServerConfig: WebpackDevServerConfig, buildOptions: BuildOptions): Promise { +export async function generateTsConfig (devServerConfig: AngularWebpackDevServerConfig, buildOptions: BuildOptions): Promise { const { cypressConfig } = devServerConfig const { projectRoot } = cypressConfig @@ -222,7 +224,7 @@ function createFakeContext (projectRoot: string, defaultProjectConfig: Cypress.A export const toPosix = (filePath: string) => filePath.split(path.sep).join(path.posix.sep) -async function getAngularCliWebpackConfig (devServerConfig: WebpackDevServerConfig) { +async function getAngularCliWebpackConfig (devServerConfig: AngularWebpackDevServerConfig) { const { projectRoot } = devServerConfig.cypressConfig const { @@ -251,7 +253,7 @@ async function getAngularCliWebpackConfig (devServerConfig: WebpackDevServerConf return config } -export async function angularHandler (devServerConfig: WebpackDevServerConfig): Promise { +export async function angularHandler (devServerConfig: AngularWebpackDevServerConfig): Promise { const webpackConfig = await getAngularCliWebpackConfig(devServerConfig) return { frameworkConfig: webpackConfig, sourceWebpackModulesResult: sourceDefaultWebpackDependencies(devServerConfig) } diff --git a/npm/webpack-dev-server/src/helpers/sourceRelativeWebpackModules.ts b/npm/webpack-dev-server/src/helpers/sourceRelativeWebpackModules.ts index 44244faadb85..839b7475e622 100644 --- a/npm/webpack-dev-server/src/helpers/sourceRelativeWebpackModules.ts +++ b/npm/webpack-dev-server/src/helpers/sourceRelativeWebpackModules.ts @@ -1,6 +1,6 @@ import Module from 'module' import path from 'path' -import type { WebpackDevServerConfig, ALL_FRAMEWORKS } from '../devServer' +import type { Frameworks, WebpackDevServerConfig } from '../devServer' import debugFn from 'debug' const debug = debugFn('cypress:webpack-dev-server:sourceRelativeWebpackModules') @@ -56,7 +56,7 @@ export const cypressWebpackPath = (config: WebpackDevServerConfig) => { }) } -type FrameworkWebpackMapper = { [Property in typeof ALL_FRAMEWORKS[number]]: string | undefined } +type FrameworkWebpackMapper = { [Property in Frameworks]: string | undefined } const frameworkWebpackMapper: FrameworkWebpackMapper = { 'create-react-app': 'react-scripts', diff --git a/npm/webpack-dev-server/test/handlers/angularHandler.spec.ts b/npm/webpack-dev-server/test/handlers/angularHandler.spec.ts index 98d69dc91922..02ef0a9fef58 100644 --- a/npm/webpack-dev-server/test/handlers/angularHandler.spec.ts +++ b/npm/webpack-dev-server/test/handlers/angularHandler.spec.ts @@ -3,14 +3,15 @@ import chaiPromise from 'chai-as-promised' import * as fs from 'fs-extra' import cloneDeep from 'lodash/cloneDeep' import * as path from 'path' -import { WebpackDevServerConfig } from '../../src/devServer' import { angularHandler, - AngularJsonProjectConfig, + AngularWebpackDevServerConfig, + BuildOptions, generateTsConfig, getAngularBuildOptions, getAngularCliModules, getAngularJson, + getProjectConfig, getTempDir, toPosix, } from '../../src/helpers/angularHandler' @@ -19,27 +20,6 @@ import { scaffoldMigrationProject } from '../test-helpers/scaffoldProject' chai.use(chaiPromise) -const projectConfig: AngularJsonProjectConfig = { - root: 'my-root', - sourceRoot: 'my-root/src', - projectType: 'application', - architect: { - build: { - options: { - aot: true, - tsConfig: 'tsconfig.json', - polyfills: 'src/polyfills.ts', - optimization: true, - }, - configurations: { - development: { - optimization: false, - }, - }, - }, - }, -} - describe('angularHandler', function () { this.timeout(1000 * 60) @@ -54,7 +34,7 @@ describe('angularHandler', function () { specPattern: 'src/**/*.cy.ts', } as Cypress.PluginConfigOptions, framework: 'angular', - } as WebpackDevServerConfig + } as AngularWebpackDevServerConfig const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = await angularHandler(devServerConfig) @@ -62,10 +42,12 @@ describe('angularHandler', function () { expect((webpackConfig?.entry as any).main).to.be.undefined expect(sourceWebpackModulesResult.framework?.importPath).to.include(path.join('@angular-devkit', 'build-angular')) + const { buildOptions } = await expectNormalizeProjectConfig(projectRoot) + await expectLoadsAngularJson(projectRoot) await expectLoadsAngularCLiModules(projectRoot) - await expectGeneratesTsConfig(devServerConfig) - expectLoadsAngularBuildOptions() + await expectGeneratesTsConfig(devServerConfig, buildOptions) + expectLoadsAngularBuildOptions(buildOptions) }) it('sources the config from angular-14', async () => { @@ -79,7 +61,58 @@ describe('angularHandler', function () { specPattern: 'src/**/*.cy.ts', } as Cypress.PluginConfigOptions, framework: 'angular', - } as WebpackDevServerConfig + } as AngularWebpackDevServerConfig + + const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = await angularHandler(devServerConfig) + + expect(webpackConfig).to.exist + expect((webpackConfig?.entry as any).main).to.be.undefined + expect(sourceWebpackModulesResult.framework?.importPath).to.include(path.join('@angular-devkit', 'build-angular')) + + const { buildOptions } = await expectNormalizeProjectConfig(projectRoot) + + await expectLoadsAngularJson(projectRoot) + await expectLoadsAngularCLiModules(projectRoot) + await expectGeneratesTsConfig(devServerConfig, buildOptions) + expectLoadsAngularBuildOptions(buildOptions) + }) + + it('allows custom project config', async () => { + const customProjectConfig = { + root: '', + sourceRoot: 'src', + buildOptions: { + outputPath: 'dist/angular', + index: 'src/index.html', + main: 'src/main.ts', + polyfills: 'src/polyfills.ts', + tsConfig: 'tsconfig.app.json', + inlineStyleLanguage: 'scss', + assets: ['src/favicon.ico', 'src/assets'], + styles: ['src/styles.scss'], + scripts: [], + buildOptimizer: false, + optimization: false, + vendorChunk: true, + extractLicenses: false, + sourceMap: true, + namedChunks: true, + }, + } + const projectRoot = await scaffoldMigrationProject('angular-custom-config') + + process.chdir(projectRoot) + + const devServerConfig = { + framework: 'angular', + cypressConfig: { + projectRoot, + specPattern: 'src/**/*.cy.ts', + } as Cypress.PluginConfigOptions, + options: { + projectConfig: customProjectConfig, + }, + } as unknown as AngularWebpackDevServerConfig const { frameworkConfig: webpackConfig, sourceWebpackModulesResult } = await angularHandler(devServerConfig) @@ -89,11 +122,39 @@ describe('angularHandler', function () { await expectLoadsAngularJson(projectRoot) await expectLoadsAngularCLiModules(projectRoot) - await expectGeneratesTsConfig(devServerConfig) - expectLoadsAngularBuildOptions() + await expectGeneratesTsConfig(devServerConfig, customProjectConfig.buildOptions) + expectLoadsAngularBuildOptions(customProjectConfig.buildOptions) }) }) +const expectNormalizeProjectConfig = async (projectRoot: string) => { + const projectConfig = await getProjectConfig(projectRoot) + + expect(projectConfig).to.deep.eq({ + root: '', + sourceRoot: 'src', + buildOptions: { + outputPath: 'dist/angular', + index: 'src/index.html', + main: 'src/main.ts', + polyfills: 'src/polyfills.ts', + tsConfig: 'tsconfig.app.json', + inlineStyleLanguage: 'scss', + assets: ['src/favicon.ico', 'src/assets'], + styles: ['src/styles.scss'], + scripts: [], + buildOptimizer: false, + optimization: false, + vendorChunk: true, + extractLicenses: false, + sourceMap: true, + namedChunks: true, + }, + }) + + return projectConfig +} + const expectLoadsAngularJson = async (projectRoot: string) => { const angularJson = await getAngularJson(projectRoot) @@ -112,29 +173,21 @@ const expectLoadsAngularCLiModules = async (projectRoot: string) => { await expect(getAngularCliModules(path.join('..', projectRoot))).to.be.rejected } -const expectLoadsAngularBuildOptions = () => { +const expectLoadsAngularBuildOptions = (buildOptions: BuildOptions) => { const tsConfig = 'tsconfig.cypress.json' - let buildOptions = getAngularBuildOptions(projectConfig, tsConfig) - - expect(buildOptions.aot).to.be.false - expect(buildOptions.optimization).to.be.false - expect(buildOptions.tsConfig).to.equal(tsConfig) - expect(buildOptions.outputHashing).to.equal('none') - expect(buildOptions.budgets).to.be.undefined - - const modifiedProjectConfig = cloneDeep(projectConfig) - - delete modifiedProjectConfig.architect.build.configurations - - buildOptions = getAngularBuildOptions(modifiedProjectConfig, tsConfig) + let finalBuildOptions = getAngularBuildOptions(buildOptions, tsConfig) - expect(buildOptions.optimization).to.be.true + expect(finalBuildOptions.aot).to.be.false + expect(finalBuildOptions.optimization).to.be.false + expect(finalBuildOptions.tsConfig).to.equal(tsConfig) + expect(finalBuildOptions.outputHashing).to.equal('none') + expect(finalBuildOptions.budgets).to.be.undefined } -const expectGeneratesTsConfig = async (devServerConfig: WebpackDevServerConfig) => { +const expectGeneratesTsConfig = async (devServerConfig: AngularWebpackDevServerConfig, buildOptions: any) => { const { projectRoot } = devServerConfig.cypressConfig - let tsConfigPath = await generateTsConfig(devServerConfig, projectConfig) + let tsConfigPath = await generateTsConfig(devServerConfig, buildOptions) const tempDir = await getTempDir() expect(tsConfigPath).to.eq(path.join(tempDir, 'tsconfig.json')) @@ -155,16 +208,16 @@ const expectGeneratesTsConfig = async (devServerConfig: WebpackDevServerConfig) ], }) - const modifiedProjectConfig = cloneDeep(projectConfig) + const modifiedBuildOptions = cloneDeep(buildOptions) - delete modifiedProjectConfig.architect.build.options.polyfills + delete modifiedBuildOptions.polyfills const modifiedDevServerConfig = cloneDeep(devServerConfig) const supportFile = path.join(projectRoot, 'cypress', 'support', 'component.ts') modifiedDevServerConfig.cypressConfig.supportFile = supportFile - tsConfigPath = await generateTsConfig(modifiedDevServerConfig, modifiedProjectConfig) + tsConfigPath = await generateTsConfig(modifiedDevServerConfig, modifiedBuildOptions) tsConfig = JSON.parse(await fs.readFile(tsConfigPath, 'utf8')) expect(tsConfig.include).to.deep.equal([ diff --git a/npm/webpack-dev-server/test/test-helpers/scaffoldProject.ts b/npm/webpack-dev-server/test/test-helpers/scaffoldProject.ts index 3f84021b2184..067e08556ec2 100644 --- a/npm/webpack-dev-server/test/test-helpers/scaffoldProject.ts +++ b/npm/webpack-dev-server/test/test-helpers/scaffoldProject.ts @@ -1,7 +1,7 @@ import Fixtures, { ProjectFixtureDir } from '@tooling/system-tests' import * as FixturesScaffold from '@tooling/system-tests/lib/dep-installer' -export async function scaffoldMigrationProject (project: ProjectFixtureDir) { +export async function scaffoldMigrationProject (project: ProjectFixtureDir): Promise { Fixtures.removeProject(project) await Fixtures.scaffoldProject(project) From 7ddcc9638860a81bede371e6b228cacf9d752718 Mon Sep 17 00:00:00 2001 From: Zachary Williams Date: Wed, 24 Aug 2022 18:31:02 -0500 Subject: [PATCH 25/45] chore: update typescript (#23523) * chore: update typescript * use String() Co-authored-by: Lachlan Miller * use String() Co-authored-by: Lachlan Miller * use String() Co-authored-by: Lachlan Miller Co-authored-by: Lachlan Miller --- npm/angular/package.json | 2 +- npm/create-cypress-tests/package.json | 2 +- npm/cypress-schematic/package.json | 2 +- npm/mount-utils/package.json | 2 +- npm/react/package.json | 2 +- npm/react18/package.json | 2 +- npm/vue/package.json | 2 +- npm/vue2/package.json | 2 +- .../package.json | 4 +- .../examples/use-ts-loader/package.json | 4 +- package.json | 2 +- .../driver/src/dom/elements/nativeProps.ts | 6 +-- packages/extension/package.json | 2 +- packages/launcher/package.json | 2 +- packages/network/package.json | 2 +- packages/proxy/package.json | 2 +- packages/scaffold-config/src/frameworks.ts | 6 +-- packages/server/package.json | 2 +- packages/types/package.json | 2 +- yarn.lock | 43 ++++--------------- 20 files changed, 32 insertions(+), 61 deletions(-) diff --git a/npm/angular/package.json b/npm/angular/package.json index f8601c9604b8..b8aa75d447ff 100644 --- a/npm/angular/package.json +++ b/npm/angular/package.json @@ -18,7 +18,7 @@ "@angular/platform-browser-dynamic": "^14.0.6", "@rollup/plugin-node-resolve": "^11.1.1", "rollup-plugin-typescript2": "^0.29.0", - "typescript": "~4.2.3", + "typescript": "^4.7.4", "zone.js": "~0.11.4" }, "peerDependencies": { diff --git a/npm/create-cypress-tests/package.json b/npm/create-cypress-tests/package.json index 6447e62beafe..7ecf5f176ef7 100644 --- a/npm/create-cypress-tests/package.json +++ b/npm/create-cypress-tests/package.json @@ -41,7 +41,7 @@ "mock-fs": "5.1.1", "shx": "0.3.3", "snap-shot-it": "7.9.3", - "typescript": "^4.2.3" + "typescript": "^4.7.4" }, "files": [ "dist", diff --git a/npm/cypress-schematic/package.json b/npm/cypress-schematic/package.json index 2c32d2ca8c5f..9e8be56964d9 100644 --- a/npm/cypress-schematic/package.json +++ b/npm/cypress-schematic/package.json @@ -24,7 +24,7 @@ "@types/node": "^18.0.6", "chai": "4.2.0", "mocha": "3.5.3", - "typescript": "~4.2.3" + "typescript": "^4.7.4" }, "peerDependencies": { "@angular/cli": ">=14.1.0", diff --git a/npm/mount-utils/package.json b/npm/mount-utils/package.json index c135296d772a..1cb2f56dbd89 100644 --- a/npm/mount-utils/package.json +++ b/npm/mount-utils/package.json @@ -12,7 +12,7 @@ }, "dependencies": {}, "devDependencies": { - "typescript": "^4.2.3" + "typescript": "^4.7.4" }, "files": [ "dist" diff --git a/npm/react/package.json b/npm/react/package.json index 40d74496c1d3..2d098d779b1c 100644 --- a/npm/react/package.json +++ b/npm/react/package.json @@ -30,7 +30,7 @@ "rollup": "^2.38.5", "rollup-plugin-typescript2": "^0.29.0", "semver": "^7.3.2", - "typescript": "^4.2.3", + "typescript": "^4.7.4", "vite": "3.0.3", "vite-plugin-require-transform": "1.0.3" }, diff --git a/npm/react18/package.json b/npm/react18/package.json index 0ebeb0dbeedf..cd7586379f2d 100644 --- a/npm/react18/package.json +++ b/npm/react18/package.json @@ -20,7 +20,7 @@ "react-dom": "^16", "rollup": "^2.38.5", "rollup-plugin-typescript2": "^0.29.0", - "typescript": "^4.2.3" + "typescript": "^4.7.4" }, "peerDependencies": { "@types/react": "^18", diff --git a/npm/vue/package.json b/npm/vue/package.json index 1ef69e4995bb..1c75bc92329b 100644 --- a/npm/vue/package.json +++ b/npm/vue/package.json @@ -29,7 +29,7 @@ "rollup-plugin-istanbul": "2.0.1", "rollup-plugin-typescript2": "^0.29.0", "tailwindcss": "1.1.4", - "typescript": "^4.2.3", + "typescript": "^4.7.4", "vite": "3.0.3", "vue": "3.2.31", "vue-i18n": "9.0.0-rc.6", diff --git a/npm/vue2/package.json b/npm/vue2/package.json index c98182dac91c..8ba42355f920 100644 --- a/npm/vue2/package.json +++ b/npm/vue2/package.json @@ -23,7 +23,7 @@ "@rollup/plugin-replace": "^2.3.1", "rollup-plugin-typescript2": "^0.29.0", "tslib": "^2.1.0", - "typescript": "^4.2.3", + "typescript": "^4.7.4", "vue": "2.6.12" }, "peerDependencies": { diff --git a/npm/webpack-batteries-included-preprocessor/package.json b/npm/webpack-batteries-included-preprocessor/package.json index 1844b995deb1..d7837ea19411 100644 --- a/npm/webpack-batteries-included-preprocessor/package.json +++ b/npm/webpack-batteries-included-preprocessor/package.json @@ -19,7 +19,7 @@ "coffee-loader": "^0.9.0", "coffeescript": "^1.12.7", "pnp-webpack-plugin": "^1.7.0", - "ts-loader": "^8.0.2", + "ts-loader": "8.4.0", "tsconfig-package": "npm:tsconfig@^7.0.0", "tsconfig-paths-webpack-plugin": "^3.3.0", "webpack": "^4.44.2" @@ -41,7 +41,7 @@ "graphql": "14.0.0", "mocha": "^8.1.1", "react": "^16.13.1", - "typescript": "^4.2.3" + "typescript": "^4.7.4" }, "peerDependencies": { "@cypress/webpack-preprocessor": "^5.4.4" diff --git a/npm/webpack-preprocessor/examples/use-ts-loader/package.json b/npm/webpack-preprocessor/examples/use-ts-loader/package.json index d268cd27e2ee..141804734873 100644 --- a/npm/webpack-preprocessor/examples/use-ts-loader/package.json +++ b/npm/webpack-preprocessor/examples/use-ts-loader/package.json @@ -9,8 +9,8 @@ "types": "tsc --noEmit --lib es2015,dom --types cypress cypress/e2e/*.ts" }, "devDependencies": { - "ts-loader": "7.0.4", - "typescript": "^4.2.3" + "ts-loader": "8.4.0", + "typescript": "^4.7.4" }, "license": "ISC", "keywords": [] diff --git a/package.json b/package.json index 11c78836947d..7c45620d535a 100644 --- a/package.json +++ b/package.json @@ -215,7 +215,7 @@ "through2": "^4.0.2", "tree-kill": "1.2.2", "ts-node": "^10.2.1", - "typescript": "^4.4.4", + "typescript": "^4.7.4", "yarn-deduplicate": "3.1.0" }, "engines": { diff --git a/packages/driver/src/dom/elements/nativeProps.ts b/packages/driver/src/dom/elements/nativeProps.ts index fbc1094dffbb..2e6407edc3b8 100644 --- a/packages/driver/src/dom/elements/nativeProps.ts +++ b/packages/driver/src/dom/elements/nativeProps.ts @@ -12,7 +12,7 @@ const descriptor = (obj: T, prop: K): T if (!nativeProp) { const props = _.keys(nativeGetters).join(', ') - throw new Error(`attempted to use a native getter prop called: ${prop}. Available props are: ${props}`) + throw new Error(`attempted to use a native getter prop called: ${String(prop)}. Available props are: ${props}`) } let retProp = nativeProp.call(obj, prop) @@ -258,7 +258,7 @@ export const setNativeProp = function (obj: T, prop: K, va if (!nativeProp) { const fns = _.keys(nativeSetters).join(', ') - throw new Error(`attempted to use a native setter prop called: ${prop}. Available props are: ${fns}`) + throw new Error(`attempted to use a native setter prop called: ${String(prop)}. Available props are: ${fns}`) } let retProp = nativeProp.call(obj, val) diff --git a/packages/extension/package.json b/packages/extension/package.json index 9d98d57a5ec0..a0a17927efcb 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -32,7 +32,7 @@ "rimraf": "3.0.2", "sinon": "7.3.2", "sinon-chai": "3.3.0", - "ts-loader": "8.0.13", + "ts-loader": "8.4.0", "webextension-polyfill": "0.4.0", "webpack": "4.44.2" }, diff --git a/packages/launcher/package.json b/packages/launcher/package.json index 5799a4bddc8b..273c284a18b7 100644 --- a/packages/launcher/package.json +++ b/packages/launcher/package.json @@ -32,7 +32,7 @@ "rimraf": "3.0.2", "sinon": "^10.0.0", "sinon-chai": "3.4.0", - "typescript": "^4.2.3" + "typescript": "^4.7.4" }, "files": [ "index.js", diff --git a/packages/network/package.json b/packages/network/package.json index 349a35f84110..d73bf492204d 100644 --- a/packages/network/package.json +++ b/packages/network/package.json @@ -35,7 +35,7 @@ "rimraf": "3.0.2", "sinon": "7.3.1", "sinon-chai": "3.3.0", - "typescript": "^4.2.3" + "typescript": "^4.7.4" }, "files": [ "lib" diff --git a/packages/proxy/package.json b/packages/proxy/package.json index 7f3f90922209..ac883fc52bc1 100644 --- a/packages/proxy/package.json +++ b/packages/proxy/package.json @@ -37,7 +37,7 @@ "express": "4.17.1", "rimraf": "3.0.2", "supertest": "6.0.1", - "typescript": "^4.2.3" + "typescript": "^4.7.4" }, "files": [ "lib" diff --git a/packages/scaffold-config/src/frameworks.ts b/packages/scaffold-config/src/frameworks.ts index f95457c11e52..4f32935b7794 100644 --- a/packages/scaffold-config/src/frameworks.ts +++ b/packages/scaffold-config/src/frameworks.ts @@ -61,11 +61,9 @@ function getBundlerDependency (bundler: WizardBundler['type'], projectPath: stri } } -export const WIZARD_MOUNT_MODULES = ['cypress/react', 'cypress/react18', 'cypress/vue', 'cypress/vue2', 'cypress/angular'] as const +export type WizardMountModule = Awaited> -export type WizardMountModule = 'cypress/react' | 'cypress/react18' | 'cypress/vue' | 'cypress/vue2' | 'cypress/angular' - -const mountModule = (mountModule: WizardMountModule) => (projectPath: string) => Promise.resolve(mountModule) +const mountModule = (mountModule: T) => (projectPath: string) => Promise.resolve(mountModule) const reactMountModule = async (projectPath: string) => { const reactPkg = await isDependencyInstalled(dependencies.WIZARD_DEPENDENCY_REACT, projectPath) diff --git a/packages/server/package.json b/packages/server/package.json index 96e807e6ba97..3294a546cd70 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -181,7 +181,7 @@ "supertest": "4.0.2", "supertest-session": "4.0.0", "through2": "2.0.5", - "ts-loader": "7.0.4", + "ts-loader": "8.4.0", "tsconfig-paths": "3.10.1", "tslint": "^6.1.3", "webpack": "^4.44.2", diff --git a/packages/types/package.json b/packages/types/package.json index 318cd0bb2837..150ae6ec63c5 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -13,7 +13,7 @@ "devDependencies": { "@types/node": "14.14.31", "rimraf": "3.0.2", - "typescript": "^4.2.3" + "typescript": "^4.7.4" }, "files": [ "src/*" diff --git a/yarn.lock b/yarn.lock index b048b3221dc0..f1470d93735a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32761,32 +32761,10 @@ tryor@~0.1.2: resolved "https://registry.yarnpkg.com/tryor/-/tryor-0.1.2.tgz#8145e4ca7caff40acde3ccf946e8b8bb75b4172b" integrity sha1-gUXkynyv9ArN48z5Rui4u3W0Fys= -ts-loader@7.0.4: - version "7.0.4" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-7.0.4.tgz#5d9b95227de5afb91fdd9668f8920eb193cfe0cc" - integrity sha512-5du6OQHl+4ZjO4crEyoYUyWSrmmo7bAO+inkaILZ68mvahqrfoa4nn0DRmpQ4ruT4l+cuJCgF0xD7SBIyLeeow== - dependencies: - chalk "^2.3.0" - enhanced-resolve "^4.0.0" - loader-utils "^1.0.2" - micromatch "^4.0.0" - semver "^6.0.0" - -ts-loader@8.0.13: - version "8.0.13" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.0.13.tgz#2bebeb833570ca46bb9338322a9a29900e988535" - integrity sha512-1o1nO6aqouA23d2nlcMSEyPMAWRhnYUU0EQUJSc60E0TUyBNX792RHFYUN1ZM29vhMUNayrsbj2UVdZwKhXCDA== - dependencies: - chalk "^2.3.0" - enhanced-resolve "^4.0.0" - loader-utils "^1.0.2" - micromatch "^4.0.0" - semver "^6.0.0" - -ts-loader@^8.0.2: - version "8.1.0" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.1.0.tgz#d6292487df279c7cc79b6d3b70bb9d31682b693e" - integrity sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A== +ts-loader@8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.4.0.tgz#e845ea0f38d140bdc3d7d60293ca18d12ff2720f" + integrity sha512-6nFY3IZ2//mrPc+ImY3hNWx1vCHyEhl6V+wLmL4CZcm6g1CqX7UKrkc6y0i4FwcfOhxyMPCfaEvh20f4r9GNpw== dependencies: chalk "^4.1.0" enhanced-resolve "^4.0.0" @@ -33115,15 +33093,10 @@ typescript-cached-transpile@^0.0.6: fs-extra "^8.1.0" tslib "^1.10.0" -typescript@^4.2.3, typescript@^4.4.4: - version "4.4.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c" - integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA== - -typescript@~4.2.3: - version "4.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" - integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== +typescript@^4.7.4: + version "4.7.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== ua-parser-js@0.7.24, ua-parser-js@^0.7.18: version "0.7.24" From 2fcecbf43e51d0648a649d096e7321c945eb2396 Mon Sep 17 00:00:00 2001 From: Tyler Biethman Date: Thu, 25 Aug 2022 09:22:47 -0500 Subject: [PATCH 26/45] chore(webkit): driver updates for clicking/typing actions and related tests (#23522) * detect playwright-webkit browser * fix: use stdio for CDP instead of TCP (#14348) * wip: begin launchin webkit * run mode works w webkit in 10.0 * reset previous cdp changes * run driver webkit tests * always detect webkit in non-prod * fix version detection * actually run new job * cleanup * fix run * try caching pw binary * npx install pw binary * install-deps * add experimentalSessionAndOrigin wk tests * wk experimentalSessionAndOrigin tests * browser icon * fix some tests * reset browsers.ts change * fix more tests * fix even more tests, skip driver CI for now * comma * fix server-unit-test * fix websockets_spec * refactor wkautomation to initialize self from static async method * fix(proxy/prerequests): fix duplicate key behavior, fallthrough * Apply suggestions from code review Co-authored-by: Blue F * simpler name for StackMap * fix proxy-logging spec, some xhr specs * fix last xhr test * update testConfigOverrides * skip webcam.cy.js * reenable driver tests * ci? * Suggestions from code review * skip remaining failures which won't be fixed here * fix/skip a couple tests * fix tests * skip crashy specs * skip hidden suites * Scoping down range of skipped type tests * Scoping down click test skips * Updating webkit contenteditable selection handling and associated test * Adding additional mouse event filtering when disabled. Validated by opening playwright-webkit outside of cypress and validating logged events when enabled/disabled. * Updating click 'mouseout coords' tests to account for default style changes * Updating a few more click 'mouse state' tests * Getting all click tests passing with no webkit skips. Fixing _most_ type tests, selection focus is troublesome. * Updating cross-origin type action test * Tweaking coords for CI rendering * Adding workaround for webkit default input selection. * Webkit -> WebKit * Adding logic and test for handling capture-phase focus event selections * Type errors tests now passing * Adding a couple more WebKit keyboard/mouse tweaks * Couple more tweaks for special_chars tests. * Updating contenteditable beforeinput event tests * Making WebKit checks more consistent * Don't expose webkit in public types * Adding comments and doing a little cleanup * PR updates * Simplifying workaround for webkit focus selection * Removing unnecessary test * Revert "Removing unnecessary test" This reverts commit 2c522935ecab7f7291f38bdaa29226d85853b36e. * Revert "Simplifying workaround for webkit focus selection" This reverts commit 47d1155219fb60948fc36f937928f05f4e9889b8. * Removing comment that is no longer applicable * Simplifying selection logic that is now functional for all supported browsers Co-authored-by: Zach Bloomquist Co-authored-by: Zach Bloomquist Co-authored-by: Blue F --- packages/app/src/runner/logger.ts | 67 +++---- .../cypress/e2e/commands/actions/click.cy.js | 42 +++-- .../cypress/e2e/commands/actions/type.cy.js | 176 ++++++++++++------ .../e2e/commands/actions/type_errors.cy.js | 3 +- .../commands/actions/type_special_chars.cy.js | 34 ++-- .../e2e/e2e/origin/commands/actions.cy.ts | 10 +- .../driver/src/cy/commands/actions/focus.ts | 13 ++ .../src/cy/commands/actions/selectFile.ts | 4 +- .../driver/src/cy/commands/actions/type.ts | 13 +- packages/driver/src/cy/focused.ts | 47 +++++ packages/driver/src/cy/keyboard.ts | 20 +- packages/driver/src/cy/mouse.ts | 15 +- packages/driver/src/dom/selection.ts | 14 +- .../server/lib/browsers/webkit-automation.ts | 4 +- packages/server/lib/browsers/webkit.ts | 6 +- 15 files changed, 315 insertions(+), 153 deletions(-) diff --git a/packages/app/src/runner/logger.ts b/packages/app/src/runner/logger.ts index 2542f89f04bc..82c04f943fcd 100644 --- a/packages/app/src/runner/logger.ts +++ b/packages/app/src/runner/logger.ts @@ -32,7 +32,7 @@ export const logger = { this._logValues(consoleProps) this._logArgs(consoleProps) this._logGroups(consoleProps) - this._logTable(consoleProps) + this._logTables(consoleProps) }, _logValues (consoleProps: any) { @@ -118,43 +118,46 @@ export const logger = { }) }, - _logTable (consoleProps: any) { - if (isMultiEntryTable(consoleProps.table)) { - _.each( - _.sortBy(consoleProps.table, (val, key) => key), - (table) => { - return this._logTable({ table }) - }, - ) + _logTables (consoleProps: any) { + const logTable = ({ name, data, columns }) => { + let tableData = data - return - } + if (Cypress.isBrowser('webkit')) { + // WebKit will hang when we attempt to log element references + // within a table. We replace the element with a simplified display + // string in this case. + // https://bugs.webkit.org/show_bug.cgi?id=244100 - const table = this._getTable(consoleProps) + const getSimplifiedElementDisplay = (element: Element) => { + let display = element.tagName.toLowerCase() - if (!table) return + if (element.id) { + display += `#${element.id}` + } - if (_.isArray(table)) { - console.table(table) - } else { - console.group(table.name) - console.table(table.data, table.columns) - console.groupEnd() - } - }, + element.classList.forEach((className) => { + display += `.${className}` + }) - _getTable (consoleProps: any): Table | Table[] | undefined { - const table = _.result(consoleProps, 'table') + return display + } - if (!table) return + tableData = data.map((rowObj) => { + return Object.entries(rowObj).reduce((acc: any, value) => { + acc[value[0]] = _.isElement(value[1]) ? getSimplifiedElementDisplay(value[1] as Element) : value[1] - return table - }, -} + return acc + }, {}) + }) + } + + console.group(name) + console.table(tableData, columns) + console.groupEnd() + } -const isMultiEntryTable = (table: Table) => { - return !_.isFunction(table) && - !_.some(_.keys(table) - .map((x) => isNaN(parseInt(x, 10))) - .filter(Boolean), true) + _.each(_.sortBy(consoleProps.table, (val, key) => key), (getTableData: () => Table) => { + return logTable(getTableData()) + }) + }, } diff --git a/packages/driver/cypress/e2e/commands/actions/click.cy.js b/packages/driver/cypress/e2e/commands/actions/click.cy.js index 1ec6075c6269..3fa9e8bf358f 100644 --- a/packages/driver/cypress/e2e/commands/actions/click.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/click.cy.js @@ -45,9 +45,9 @@ const getMidPoint = (el) => { } const isFirefox = Cypress.isBrowser('firefox') +const isWebKit = Cypress.isBrowser('webkit') -// TODO(webkit): fix+unskip for experimental webkit -describe('src/cy/commands/actions/click', { browser: '!webkit' }, () => { +describe('src/cy/commands/actions/click', () => { beforeEach(() => { cy.visit('/fixtures/dom.html') }) @@ -3596,7 +3596,8 @@ describe('src/cy/commands/actions/click', { browser: '!webkit' }, () => { cy.getAll('el', 'mousedown contextmenu mouseup').each(shouldNotBeCalled) - cy.getAll('el', 'pointerdown pointerup').each(isFirefox ? shouldNotBeCalled : shouldBeCalled) + // On disabled inputs, pointer events are still fired in chrome, not in firefox or webkit + cy.getAll('el', 'pointerdown pointerup').each(isFirefox || isWebKit ? shouldNotBeCalled : shouldBeCalled) }) it('rightclick cancel contextmenu', () => { @@ -3929,8 +3930,7 @@ describe('src/cy/commands/actions/click', { browser: '!webkit' }, () => { }) }) -// TODO(webkit): fix+unskip for experimental webkit -describe('shadow dom', { browser: '!webkit' }, () => { +describe('shadow dom', () => { beforeEach(() => { cy.visit('/fixtures/shadow-dom.html') }) @@ -3993,8 +3993,7 @@ describe('shadow dom', { browser: '!webkit' }, () => { }) }) -// TODO(webkit): fix+unskip for experimental webkit -describe('mouse state', { browser: '!webkit' }, () => { +describe('mouse state', () => { describe('mouse/pointer events', () => { beforeEach(() => { cy.visit('http://localhost:3500/fixtures/dom.html') @@ -4064,12 +4063,28 @@ describe('mouse state', { browser: '!webkit' }, () => { y: 10, } + const coordsWebKit = { + clientX: 500, + clientY: 10, + layerX: 500, + layerY: 226, + pageX: 500, + pageY: 226, + screenX: 500, + screenY: 10, + x: 500, + y: 10, + } + let coords switch (Cypress.browser.family) { case 'firefox': coords = coordsFirefox break + case 'webkit': + coords = coordsWebKit + break default: coords = coordsChrome break @@ -4498,9 +4513,10 @@ describe('mouse state', { browser: '!webkit' }, () => { // cy.wrap(onAction).should('calledOnce') cy.getAll('btn', 'pointerover pointerenter').each(shouldBeCalledOnce) - cy.getAll('btn', 'pointerdown pointerup').each(isFirefox ? shouldNotBeCalled : shouldBeCalledOnce) - cy.getAll('btn', 'mouseover mouseenter').each(isFirefox ? shouldBeCalled : shouldNotBeCalled) + // On disabled inputs, pointer events are still fired in chrome, not in firefox or webkit + cy.getAll('btn', 'pointerdown pointerup').each(isFirefox || isWebKit ? shouldNotBeCalled : shouldBeCalledOnce) + cy.getAll('btn', 'mouseover mouseenter').each(isFirefox || isWebKit ? shouldBeCalled : shouldNotBeCalled) cy.getAll('btn', 'mousedown mouseup click').each(shouldNotBeCalled) }) @@ -4524,7 +4540,9 @@ describe('mouse state', { browser: '!webkit' }, () => { cy.get('#btn').click() cy.getAll('btn', 'pointerdown mousedown').each(shouldBeCalledOnce) - cy.getAll('btn', 'pointerup').each(isFirefox ? shouldNotBeCalled : shouldBeCalledOnce) + + // On disabled inputs, pointer events are still fired in chrome, not in firefox or webkit + cy.getAll('btn', 'pointerup').each(isFirefox || isWebKit ? shouldNotBeCalled : shouldBeCalledOnce) cy.getAll('btn', 'mouseup click').each(shouldNotBeCalled) }) @@ -4599,8 +4617,8 @@ describe('mouse state', { browser: '!webkit' }, () => { cy.getAll('btn', 'mousedown mouseup click').each(shouldNotBeCalled) - // on disabled inputs, pointer events are still fired in chrome, not in firefox - cy.getAll('btn', 'pointerdown pointerup').each(isFirefox ? shouldNotBeCalled : shouldBeCalled) + // On disabled inputs, pointer events are still fired in chrome, not in firefox or webkit + cy.getAll('btn', 'pointerdown pointerup').each(isFirefox || isWebKit ? shouldNotBeCalled : shouldBeCalled) }) it('can target new element after mousedown sequence', () => { diff --git a/packages/driver/cypress/e2e/commands/actions/type.cy.js b/packages/driver/cypress/e2e/commands/actions/type.cy.js index f958043dddd9..301f660b098e 100644 --- a/packages/driver/cypress/e2e/commands/actions/type.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/type.cy.js @@ -22,8 +22,9 @@ const expectTextEndsWith = (expected) => { } } -// TODO(webkit): fix+unskip for experimental webkit -describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { +const isWebKit = Cypress.isBrowser('webkit') + +describe('src/cy/commands/actions/type - #type', () => { beforeEach(() => { cy.visit('/fixtures/dom.html') }) @@ -957,6 +958,25 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { .should('have.value', 'baroo') }) + // WebKit will select all input content on focus. This causes our + // cursor placement logic to be ignored, as we interpret the default + // selection as a user-provided selection that we do not want to override. + // We work around this by preventing the default selection on focus using + // our own capture-phase 'focus' event handler; this test ensures that user-set + // capture-phase events continue to function as expected for the purpose + // of selection updates. + it('respects changed selection in focus handler during capture phase', () => { + cy.get('#input-without-value') + .then(($el) => { + $el.val('foo') + $el.get(0).addEventListener('focus', (e) => { + e.currentTarget.setSelectionRange(0, 1) + }, { capture: true }) + }) + .type('bar') + .should('have.value', 'baroo') + }) + it('overwrites text when selectAll in mouseup handler', () => { cy.$$('#input-without-value').val('0').mouseup(function () { $(this).select() @@ -1197,7 +1217,7 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { }) }) - it('inserts text after existing text ', () => { + it('inserts text after existing text', () => { cy.get('#number-with-value').type('34').then(($text) => { expect($text).to.have.value('1234') }) @@ -1794,33 +1814,36 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { }) // https://github.com/cypress-io/cypress/issues/7088 + // In WebKit, setting the inputType is not supported by the InputEvent constructor. + // This results in the inputType being unset in any of the simulated beforeinput events. + // https://bugs.webkit.org/show_bug.cgi?id=170416 describe('beforeInput event', () => { it('sends beforeinput in text input', () => { const call1 = (e) => { expect(e.code).not.exist expect(e.data).eq(' ') - expect(e.inputType).eq('insertText') + !isWebKit && expect(e.inputType).eq('insertText') stub.callsFake(call2) } const call2 = (e) => { expect(e.code).not.exist expect(e.data).eq('f') - expect(e.inputType).eq('insertText') + !isWebKit && expect(e.inputType).eq('insertText') stub.callsFake(call3) } const call3 = (e) => { expect(e.data).eq(null) - expect(e.inputType).eq('insertLineBreak') + !isWebKit && expect(e.inputType).eq('insertLineBreak') stub.callsFake(call4) } const call4 = (e) => { expect(e.data).eq(null) - expect(e.inputType).eq('deleteContentBackward') + !isWebKit && expect(e.inputType).eq('deleteContentBackward') stub.callsFake(call5) } const call5 = (e) => { expect(e.data).eq(null) - expect(e.inputType).eq('deleteContentForward') + !isWebKit && expect(e.inputType).eq('deleteContentForward') } const stub = cy.stub() @@ -1843,28 +1866,28 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { const call1 = (e) => { expect(e.code).not.exist expect(e.data).eq(' ') - expect(e.inputType).eq('insertText') + !isWebKit && expect(e.inputType).eq('insertText') stub.callsFake(call2) } const call2 = (e) => { expect(e.code).not.exist expect(e.data).eq('f') - expect(e.inputType).eq('insertText') + !isWebKit && expect(e.inputType).eq('insertText') stub.callsFake(call3) } const call3 = (e) => { expect(e.data).eq(null) - expect(e.inputType).eq('insertLineBreak') + !isWebKit && expect(e.inputType).eq('insertLineBreak') stub.callsFake(call4) } const call4 = (e) => { expect(e.data).eq(null) - expect(e.inputType).eq('deleteContentBackward') + !isWebKit && expect(e.inputType).eq('deleteContentBackward') stub.callsFake(call5) } const call5 = (e) => { expect(e.data).eq(null) - expect(e.inputType).eq('deleteContentForward') + !isWebKit && expect(e.inputType).eq('deleteContentForward') } const stub = cy.stub() @@ -1883,6 +1906,10 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { }) }) + // In WebKit, simulated `beforeinput` events are not emitted for + // contenteditable inputs. The stubs are receiving the + // browser-emitted events, which is why the inputType values + // of these events are populated. it('sends beforeinput in [contenteditable]', () => { const call1 = (e) => { expect(e.code).not.exist @@ -1908,7 +1935,14 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { } const call5 = (e) => { expect(e.data).eq(null) - expect(e.inputType).eq('deleteContentForward') + + if (isWebKit) { + // WebKit does not distinguish between forward/backward + // deletion within a contenteditable field + expect(e.inputType).eq('deleteContentBackward') + } else { + expect(e.inputType).eq('deleteContentForward') + } } const stub = cy.stub() @@ -1927,7 +1961,7 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { }) }) - it('beforeinput special inputTypes', () => { + it('beforeinput special inputTypes in [contenteditable] (not WebKit)', { browser: '!webkit' }, () => { const call1 = (e) => { expect(e.code).not.exist expect(e.data).eq(null) @@ -1967,6 +2001,50 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { }) }) + // We do not emit simulated `beforeinput` events for the WebKit browser's + // contenteditable fields, as `execCommand('insertText')` will emit `beforeinput` + // when called. As a result, we do not emit as many events as other browsers in + // this test case, which includes no-op deletions due to a terminal cursor position. + it('beforeinput special inputTypes in [contenteditable] (WebKit)', { browser: 'webkit' }, () => { + const call1 = (e) => { + expect(e.code).not.exist + expect(e.data).eq(null) + + // WebKit does not distinguish between forward/backward + // deletion within a contenteditable field using `execCommand('delete')` + expect(e.inputType).eq('deleteContentBackward') + + stub.callsFake(call2) + } + const call2 = (e) => { + expect(e.code).not.exist + expect(e.data).eq(null) + + // WebKit does not distinguish between forward/backward + // deletion within a contenteditable field using `execCommand('delete')` + expect(e.inputType).eq('deleteContentBackward') + } + + const stub = cy.stub() + .callsFake(call1) + + cy.get('#input-types [contenteditable]') + .then(($el) => { + $el.text('foo bar baz') + $el[0].addEventListener('beforeinput', stub) + }) + // This command does not result in a change, as the cursor is in the right-most position + // and there is nothing to delete. This causes WebKit to not emit a beforeinput event. + .type('{ctrl}{del}') + // This command also does not result in a change, for the same reason. + .type('{ctrl}{shift}{del}') + .type('{ctrl}{backspace}') + .type('{ctrl}{shift}{backspace}') + .then(($el) => { + expect(stub).callCount(2) + }) + }) + it('can cancel beforeinput', () => { let callCount = 0 @@ -2356,19 +2434,16 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { .then(function ($input) { const table = this.lastLog.invoke('consoleProps').table[2]() - // eslint-disable-next-line - console.table(table.data, table.columns) - expect(table.name).to.eq('Keyboard Events') - const expectedTable = { - 1: { 'Details': '{ code: KeyH, which: 72 }', Typed: 'h', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': null, 'Prevented Default': null, 'Target Element': $input[0] }, - 2: { 'Details': '{ code: ControlLeft, which: 17 }', Typed: '{ctrl}', 'Events Fired': 'keydown', 'Active Modifiers': 'ctrl', 'Prevented Default': null, 'Target Element': $input[0] }, - 3: { 'Details': '{ code: AltLeft, which: 18 }', Typed: '{alt}', 'Events Fired': 'keydown', 'Active Modifiers': 'alt, ctrl', 'Prevented Default': null, 'Target Element': $input[0] }, - 4: { 'Details': '{ code: Equal, which: 187 }', Typed: '+', 'Events Fired': 'keydown, keyup', 'Active Modifiers': 'alt, ctrl', 'Prevented Default': null, 'Target Element': $input[0] }, - 5: { 'Details': '{ code: AltLeft, which: 18 }', Typed: '{alt}', 'Events Fired': 'keyup', 'Active Modifiers': 'ctrl', 'Prevented Default': null, 'Target Element': $input[0] }, - 6: { 'Details': '{ code: ControlLeft, which: 17 }', Typed: '{ctrl}', 'Events Fired': 'keyup', 'Active Modifiers': null, 'Prevented Default': null, 'Target Element': $input[0] }, - 7: { 'Details': '{ code: KeyI, which: 73 }', Typed: 'i', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': null, 'Prevented Default': null, 'Target Element': $input[0] }, - } + const expectedTable = [ + { 'Details': '{ code: KeyH, which: 72 }', Typed: 'h', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': null, 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: ControlLeft, which: 17 }', Typed: '{ctrl}', 'Events Fired': 'keydown', 'Active Modifiers': 'ctrl', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: AltLeft, which: 18 }', Typed: '{alt}', 'Events Fired': 'keydown', 'Active Modifiers': 'alt, ctrl', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: Equal, which: 187 }', Typed: '+', 'Events Fired': 'keydown, keyup', 'Active Modifiers': 'alt, ctrl', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: AltLeft, which: 18 }', Typed: '{alt}', 'Events Fired': 'keyup', 'Active Modifiers': 'ctrl', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: ControlLeft, which: 17 }', Typed: '{ctrl}', 'Events Fired': 'keyup', 'Active Modifiers': null, 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: KeyI, which: 73 }', Typed: 'i', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': null, 'Prevented Default': null, 'Target Element': $input[0] }, + ] // uncomment for debugging // _.each(table.data, (v, i) => expect(v).containSubset(expectedTable[i])) @@ -2934,27 +3009,23 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { .then(function ($input) { const table = this.lastLog.invoke('consoleProps').table[2]() - // eslint-disable-next-line - console.table(table.data, table.columns) - expect(table.name).to.eq('Keyboard Events') - const expectedTable = { - 1: { 'Details': '{ code: MetaLeft, which: 91 }', Typed: '{cmd}', 'Events Fired': 'keydown', 'Active Modifiers': 'meta', 'Prevented Default': null, 'Target Element': $input[0] }, - 2: { 'Details': '{ code: AltLeft, which: 18 }', Typed: '{option}', 'Events Fired': 'keydown', 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, - 3: { 'Details': '{ code: KeyF, which: 70 }', Typed: 'f', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, - 4: { 'Details': '{ code: KeyO, which: 79 }', Typed: 'o', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, - 5: { 'Details': '{ code: KeyO, which: 79 }', Typed: 'o', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, - 6: { 'Details': '{ code: Enter, which: 13 }', Typed: '{enter}', 'Events Fired': `keydown, keypress, beforeinput, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, - 7: { 'Details': '{ code: KeyB, which: 66 }', Typed: 'b', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, - 8: { 'Details': '{ code: ArrowLeft, which: 37 }', Typed: '{leftarrow}', 'Events Fired': 'keydown, keyup', 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, - 9: { 'Details': '{ code: Delete, which: 46 }', Typed: '{del}', 'Events Fired': `keydown, beforeinput, input, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, - 10: { 'Details': '{ code: Enter, which: 13 }', Typed: '{enter}', 'Events Fired': `keydown, keypress, beforeinput, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, - 11: { 'Details': '{ code: MetaLeft, which: 91 }', Typed: '{cmd}', 'Events Fired': 'keyup', 'Active Modifiers': 'alt', 'Prevented Default': null, 'Target Element': $input[0] }, - 12: { 'Details': '{ code: AltLeft, which: 18 }', Typed: '{option}', 'Events Fired': 'keyup', 'Active Modifiers': null, 'Prevented Default': null, 'Target Element': $input[0] }, - } + const expectedTable = [ + { 'Details': '{ code: MetaLeft, which: 91 }', Typed: '{cmd}', 'Events Fired': 'keydown', 'Active Modifiers': 'meta', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: AltLeft, which: 18 }', Typed: '{option}', 'Events Fired': 'keydown', 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: KeyF, which: 70 }', Typed: 'f', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: KeyO, which: 79 }', Typed: 'o', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: KeyO, which: 79 }', Typed: 'o', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: Enter, which: 13 }', Typed: '{enter}', 'Events Fired': `keydown, keypress, beforeinput, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: KeyB, which: 66 }', Typed: 'b', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: ArrowLeft, which: 37 }', Typed: '{leftarrow}', 'Events Fired': 'keydown, keyup', 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: Delete, which: 46 }', Typed: '{del}', 'Events Fired': `keydown, beforeinput, input, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: Enter, which: 13 }', Typed: '{enter}', 'Events Fired': `keydown, keypress, beforeinput, keyup`, 'Active Modifiers': 'alt, meta', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: MetaLeft, which: 91 }', Typed: '{cmd}', 'Events Fired': 'keyup', 'Active Modifiers': 'alt', 'Prevented Default': null, 'Target Element': $input[0] }, + { 'Details': '{ code: AltLeft, which: 18 }', Typed: '{option}', 'Events Fired': 'keyup', 'Active Modifiers': null, 'Prevented Default': null, 'Target Element': $input[0] }, + ] // uncomment for debugging - // _.each(table.data, (v, i) => expect(v).containSubset(expectedTable[i])) expect(table.data).to.deep.eq(expectedTable) expect($input.val()).eq('foo') }) @@ -2964,9 +3035,9 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { cy.get(':text:first').type('f').then(function ($el) { const table = this.lastLog.invoke('consoleProps').table[2]() - expect(table.data).to.deep.eq({ - 1: { Typed: 'f', 'Events Fired': `keydown, keypress, beforeinput, textInput, input, keyup`, 'Active Modifiers': null, Details: '{ code: KeyF, which: 70 }', 'Prevented Default': null, 'Target Element': $el[0] }, - }) + expect(table.data).to.deep.eq([ + { Typed: 'f', 'Events Fired': 'keydown, keypress, beforeinput, textInput, input, keyup', 'Active Modifiers': null, Details: '{ code: KeyF, which: 70 }', 'Prevented Default': null, 'Target Element': $el[0] }, + ]) }) }) @@ -2978,12 +3049,9 @@ describe('src/cy/commands/actions/type - #type', { browser: '!webkit' }, () => { cy.get(':text:first').type('f').then(function ($el) { const table = this.lastLog.invoke('consoleProps').table[2]() - // eslint-disable-next-line - console.table(table.data, table.columns) - - expect(table.data).to.deep.eq({ - 1: { Typed: 'f', 'Events Fired': 'keydown, keyup', 'Active Modifiers': null, Details: '{ code: KeyF, which: 70 }', 'Prevented Default': true, 'Target Element': $el[0] }, - }) + expect(table.data).to.deep.eq([ + { Typed: 'f', 'Events Fired': 'keydown, keyup', 'Active Modifiers': null, Details: '{ code: KeyF, which: 70 }', 'Prevented Default': true, 'Target Element': $el[0] }, + ]) }) }) }) diff --git a/packages/driver/cypress/e2e/commands/actions/type_errors.cy.js b/packages/driver/cypress/e2e/commands/actions/type_errors.cy.js index 00225dc4c44d..b5c864ee7a4e 100644 --- a/packages/driver/cypress/e2e/commands/actions/type_errors.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/type_errors.cy.js @@ -1,8 +1,7 @@ const { assertLogLength } = require('../../../support/utils') const { _, $ } = Cypress -// TODO(webkit): fix+unskip for experimental webkit release -describe('src/cy/commands/actions/type - #type errors', { browser: '!webkit' }, () => { +describe('src/cy/commands/actions/type - #type errors', () => { beforeEach(() => { cy.visit('/fixtures/dom.html') }) diff --git a/packages/driver/cypress/e2e/commands/actions/type_special_chars.cy.js b/packages/driver/cypress/e2e/commands/actions/type_special_chars.cy.js index 847ba0b64cf6..405857a55713 100644 --- a/packages/driver/cypress/e2e/commands/actions/type_special_chars.cy.js +++ b/packages/driver/cypress/e2e/commands/actions/type_special_chars.cy.js @@ -6,8 +6,7 @@ const { trimInnerText, } = require('../../../support/utils') -// TODO(webkit): fix+unskip for experimental webkit release -describe('src/cy/commands/actions/type - #type special chars', { browser: '!webkit' }, () => { +describe('src/cy/commands/actions/type - #type special chars', () => { before(function () { cy .visit('/fixtures/dom.html') @@ -114,7 +113,13 @@ describe('src/cy/commands/actions/type - #type special chars', { browser: '!webk it('fires textInput event with e.data', (done) => { cy.$$(':text:first').on('textInput', (e) => { - expect(e.originalEvent.data).to.eq('{') + if (Cypress.isBrowser('webkit')) { + // For WebKit, the simulated textInput event is not + // emitted with the char data to prevent double entry. + expect(e.originalEvent.data).to.eq('') + } else { + expect(e.originalEvent.data).to.eq('{') + } done() }) @@ -309,8 +314,8 @@ describe('src/cy/commands/actions/type - #type special chars', { browser: '!webk attachKeyListeners({ input }) cy.get(':text:first').invoke('val', 'ab') - .then(($input) => $input[0].setSelectionRange(0, 0)) .focus() + .then(($input) => $input[0].setSelectionRange(0, 0)) .type('{backspace}') .should('have.value', 'ab') @@ -352,8 +357,8 @@ describe('src/cy/commands/actions/type - #type special chars', { browser: '!webk attachKeyListeners({ input }) cy.get('textarea:first').invoke('val', 'ab') - .then(($textarea) => $textarea[0].setSelectionRange(0, 0)) .focus() + .then(($textarea) => $textarea[0].setSelectionRange(0, 0)) .type('{backspace}') .should('have.value', 'ab') @@ -447,9 +452,8 @@ describe('src/cy/commands/actions/type - #type special chars', { browser: '!webk attachKeyListeners({ input }) cy.get(':text:first').invoke('val', 'ab') - - .then(($input) => $input[0].setSelectionRange(0, 0)) .focus() + .then(($input) => $input[0].setSelectionRange(0, 0)) .type('{del}') .should('have.value', 'b') @@ -493,8 +497,8 @@ describe('src/cy/commands/actions/type - #type special chars', { browser: '!webk attachKeyListeners({ textarea }) cy.get('textarea:first').invoke('val', 'ab') - .then(($textarea) => $textarea[0].setSelectionRange(0, 0)) .focus() + .then(($textarea) => $textarea[0].setSelectionRange(0, 0)) .type('{del}') .should('have.value', 'b') @@ -999,7 +1003,10 @@ describe('src/cy/commands/actions/type - #type special chars', { browser: '!webk cy.get('input[type="number"]:first') .invoke('val', '12.34') .type('{uparrow}{uparrow}') - .should('have.value', '14') + // WebKit does not round to the step value when calling stepUp/stepDown, + // as we do here for the ArrowUp handler. + // https://bugs.webkit.org/show_bug.cgi?id=244206 + .should('have.value', Cypress.isBrowser('webkit') ? '14.34' : '14') }) }) @@ -1057,7 +1064,10 @@ describe('src/cy/commands/actions/type - #type special chars', { browser: '!webk cy.get('input[type="number"]:first') .invoke('val', '12.34') .type('{downarrow}{downarrow}') - .should('have.value', '11') + // WebKit does not round to the step value when calling stepUp/stepDown, + // as we do here for the ArrowDown handler + // https://bugs.webkit.org/show_bug.cgi?id=244206 + .should('have.value', Cypress.isBrowser('webkit') ? '10.34' : '11') }) it('downarrow ignores current selection', () => { @@ -1292,7 +1302,6 @@ describe('src/cy/commands/actions/type - #type special chars', { browser: '!webk this.$forms.find('#single-input').submit((e) => { e.preventDefault() - events.push('submit') }) @@ -1736,7 +1745,8 @@ describe('src/cy/commands/actions/type - #type special chars', { browser: '!webk }) }) - it('will not submit the form', function (done) { + // WebKit still emits the submit event on the form in this configuration. + it('will not submit the form', { browser: '!webkit' }, function (done) { this.$forms.find('#multiple-inputs-and-multiple-submits').submit(() => { done(new Error('should not receive submit event')) }) diff --git a/packages/driver/cypress/e2e/e2e/origin/commands/actions.cy.ts b/packages/driver/cypress/e2e/e2e/origin/commands/actions.cy.ts index 3d6819a00e74..23495075d7f7 100644 --- a/packages/driver/cypress/e2e/e2e/origin/commands/actions.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/commands/actions.cy.ts @@ -455,14 +455,14 @@ context('cy.origin actions', () => { expect(datum).to.have.property('Target Element').that.deep.equals(consoleProps['Applied To']) }) - expect(KeyboardEventsTable.data[1]).to.have.property('Details').that.equals('{ code: KeyF, which: 70 }') - expect(KeyboardEventsTable.data[1]).to.have.property('Typed').that.equals('f') + expect(KeyboardEventsTable.data[0]).to.have.property('Details').that.equals('{ code: KeyF, which: 70 }') + expect(KeyboardEventsTable.data[0]).to.have.property('Typed').that.equals('f') + + expect(KeyboardEventsTable.data[1]).to.have.property('Details').that.equals('{ code: KeyO, which: 79 }') + expect(KeyboardEventsTable.data[1]).to.have.property('Typed').that.equals('o') expect(KeyboardEventsTable.data[2]).to.have.property('Details').that.equals('{ code: KeyO, which: 79 }') expect(KeyboardEventsTable.data[2]).to.have.property('Typed').that.equals('o') - - expect(KeyboardEventsTable.data[3]).to.have.property('Details').that.equals('{ code: KeyO, which: 79 }') - expect(KeyboardEventsTable.data[3]).to.have.property('Typed').that.equals('o') }) }) diff --git a/packages/driver/src/cy/commands/actions/focus.ts b/packages/driver/src/cy/commands/actions/focus.ts index e866def4c133..414c336c9891 100644 --- a/packages/driver/src/cy/commands/actions/focus.ts +++ b/packages/driver/src/cy/commands/actions/focus.ts @@ -4,6 +4,7 @@ import $dom from '../../../dom' import $utils from '../../../cypress/utils' import $errUtils from '../../../cypress/error_utils' import $elements from '../../../dom/elements' +import $selection from '../../../dom/selection' import type { Log } from '../../../cypress/log' interface InternalFocusOptions extends Partial { @@ -89,6 +90,18 @@ export default (Commands, Cypress, cy) => { cy.fireFocus(el) + if (Cypress.isBrowser('webkit') && ( + $elements.isInput(el) || $elements.isTextarea(el) + )) { + // Force selection to end in WebKit, unless selection + // has been set by user. + // It's a curried function, so the 2 arguments are valid. + // @ts-ignore + $selection.moveSelectionToEnd(el, { + onlyIfEmptySelection: true, + }) + } + const verifyAssertions = () => { return cy.verifyUpcomingAssertions(options.$el, options, { onRetry: verifyAssertions, diff --git a/packages/driver/src/cy/commands/actions/selectFile.ts b/packages/driver/src/cy/commands/actions/selectFile.ts index a946250bc529..946587b68894 100644 --- a/packages/driver/src/cy/commands/actions/selectFile.ts +++ b/packages/driver/src/cy/commands/actions/selectFile.ts @@ -20,7 +20,7 @@ import { addEventCoords, dispatch } from './trigger' * override webkitGetAsEntry() throws an error. * */ -const tryMockWebkit = (item) => { +const tryMockWebKit = (item) => { try { item.webkitGetAsEntry = () => { return { @@ -58,7 +58,7 @@ const createDataTransfer = (files: Cypress.FileReferenceObject[], eventTarget: J // also cannot be constructed, so we have to use an array instead. Object.defineProperty(dataTransfer, 'items', { get () { - return _.map(oldItems, tryMockWebkit) + return _.map(oldItems, tryMockWebKit) }, }) diff --git a/packages/driver/src/cy/commands/actions/type.ts b/packages/driver/src/cy/commands/actions/type.ts index 9b083b55fdf8..e42400c62eb4 100644 --- a/packages/driver/src/cy/commands/actions/type.ts +++ b/packages/driver/src/cy/commands/actions/type.ts @@ -87,14 +87,8 @@ export default function (Commands, Cypress, cy, state, config) { } } - // transform table object into object with zero based index as keys const getTableData = () => { - return _.reduce(_.values(table), (memo, value, index) => { - memo[index + 1] = value - - return memo - } - , {}) + return _.values(table) } options._log = Cypress.log({ @@ -255,7 +249,10 @@ export default function (Commands, Cypress, cy, state, config) { // when we send {Enter} KeyboardEvent to the input fields. // Because of that, we don't have to click the submit buttons. // Otherwise, we trigger submit events twice. - if (!isFirefoxBefore98) { + // + // WebKit will send the submit with an Enter keypress event, + // so we do need to click the default button in this case. + if (!isFirefoxBefore98 && !Cypress.isBrowser('webkit')) { // issue the click event to the 'default button' of the form // we need this to be synchronous so not going through our // own click command diff --git a/packages/driver/src/cy/focused.ts b/packages/driver/src/cy/focused.ts index d1592919bbfa..730cac177c6a 100644 --- a/packages/driver/src/cy/focused.ts +++ b/packages/driver/src/cy/focused.ts @@ -123,12 +123,17 @@ export const create = (state: StateFunc) => ({ const $focused = this.getFocused(el.ownerDocument) let hasFocused = false + let onFocusCapture // we need to bind to the focus event here // because some browsers will not ever fire // the focus event if the window itself is not // currently focused const cleanup = () => { + if (onFocusCapture) { + $elements.callNativeMethod(el, 'removeEventListener', 'focus', onFocusCapture, { capture: true }) + } + return $elements.callNativeMethod(el, 'removeEventListener', 'focus', onFocus) } @@ -136,6 +141,48 @@ export const create = (state: StateFunc) => ({ return hasFocused = true } + if (Cypress.isBrowser('webkit')) { + // By default, WebKit will select the contents of an input element when the input is focused. + // This is problematic, as we use the existence of any selection to determine whether + // we adjust the input's cursor and prepare the input for receiving additional content. + // Without intervention, we will always interpret this default selection as a user-performed selection + // and persist it, leaving the selection contents to be overwritten rather than appended to + // on subsequent actions. + // + // In order to avoid this behavior, we use a focus event during the capture phase to set + // our own initial blank selection. This short-circuits WebKit's default behavior and ensures + // that any user-performed selections performed during the focus event's bubble phase are still applied. + + onFocusCapture = (event: FocusEvent) => { + const eventTarget = event.currentTarget as HTMLInputElement + + if (!eventTarget.setSelectionRange) { + return + } + + try { + // Prior to being focused, the element's selectionStart/End will be at 0. + // Even so, we need to explicitly call setSelectionRange here to prevent WebKit + // from selecting the contents after being focused. + // + // By re-setting the selection at the current start/end values, + // we ensure that any selection values set by previous event handlers + // are persisted. + eventTarget.setSelectionRange( + eventTarget.selectionStart, + eventTarget.selectionEnd, + ) + } catch (e) { + // Some input types do not support selections and will throw when + // setSelectionRange is called. We can ignore these errors, + // as these elements wouldn't have a selection to we need to + // prevent anyway. + } + } + + $elements.callNativeMethod(el, 'addEventListener', 'focus', onFocusCapture, { capture: true }) + } + $elements.callNativeMethod(el, 'addEventListener', 'focus', onFocus) $elements.callNativeMethod(el, 'focus', opts) diff --git a/packages/driver/src/cy/keyboard.ts b/packages/driver/src/cy/keyboard.ts index 485687fb13e0..6bf3660a5f89 100644 --- a/packages/driver/src/cy/keyboard.ts +++ b/packages/driver/src/cy/keyboard.ts @@ -912,7 +912,18 @@ export class Keyboard { keyCode = 0 which = 0 location = undefined - data = text === '\r' ? '↵' : text + + // WebKit will insert characters on a textInput event, resulting + // in double char entry when the default handler is executed. But values + // inserted by textInput aren't always correct/aren't filtered + // through our shouldUpdateValue logic, so we prevent textInput's + // default logic by removing the key data from the event. + if (Cypress.isBrowser('webkit')) { + data = '' + } else { + data = text === '\r' ? '↵' : text + } + break case 'beforeinput': @@ -1162,6 +1173,13 @@ export class Keyboard { if ($elements.isContentEditable(elToType)) { key.events.input = false + + if (Cypress.isBrowser('webkit')) { + // WebKit will emit beforeinput itself when the text is + // inserted into a contenteditable input using `execCommand('insertText')`. + // We prevent the simulated event from firing to avoid duplicative events. + key.events.beforeinput = false + } } else if ($elements.isReadOnlyInputOrTextarea(elToType)) { key.events.textInput = false } diff --git a/packages/driver/src/cy/mouse.ts b/packages/driver/src/cy/mouse.ts index 3ba3ac914881..2958b03881a8 100644 --- a/packages/driver/src/cy/mouse.ts +++ b/packages/driver/src/cy/mouse.ts @@ -57,6 +57,7 @@ type DefaultMouseOptions = ModifiersEventOptions & CoordsEventOptions & { export const create = (state: StateFunc, keyboard: Keyboard, focused: IFocused, Cypress: ICypress) => { const isFirefox = Cypress.browser.family === 'firefox' + const isWebKit = Cypress.isBrowser('webkit') const sendPointerEvent = (el, evtOptions, evtName, bubbles = false, cancelable = false) => { const constructor = el.ownerDocument.defaultView.PointerEvent @@ -72,14 +73,14 @@ export const create = (state: StateFunc, keyboard: Keyboard, focused: IFocused, } const sendPointerup = (el, evtOptions) => { - if (isFirefox && el.disabled) { + if ((isFirefox || isWebKit) && el.disabled) { return {} } return sendPointerEvent(el, evtOptions, 'pointerup', true, true) } const sendPointerdown = (el, evtOptions): {} | SentEvent => { - if (isFirefox && el.disabled) { + if ((isFirefox || isWebKit) && el.disabled) { return {} } @@ -102,14 +103,14 @@ export const create = (state: StateFunc, keyboard: Keyboard, focused: IFocused, } const sendMouseup = (el, evtOptions) => { - if (isFirefox && el.disabled) { + if ((isFirefox || isWebKit) && el.disabled) { return {} } return sendMouseEvent(el, evtOptions, 'mouseup', true, true) } const sendMousedown = (el, evtOptions): {} | SentEvent => { - if (isFirefox && el.disabled) { + if ((isFirefox || isWebKit) && el.disabled) { return {} } @@ -132,21 +133,21 @@ export const create = (state: StateFunc, keyboard: Keyboard, focused: IFocused, } const sendClick = (el, evtOptions, opts: { force?: boolean } = {}) => { // send the click event if firefox and force (needed for force check checkbox) - if (!opts.force && isFirefox && el.disabled) { + if (!opts.force && (isFirefox || isWebKit) && el.disabled) { return {} } return sendMouseEvent(el, evtOptions, 'click', true, true) } const sendDblclick = (el, evtOptions) => { - if (isFirefox && el.disabled) { + if ((isFirefox || isWebKit) && el.disabled) { return {} } return sendMouseEvent(el, evtOptions, 'dblclick', true, true) } const sendContextmenu = (el, evtOptions) => { - if (isFirefox && el.disabled) { + if ((isFirefox || isWebKit) && el.disabled) { return {} } diff --git a/packages/driver/src/dom/selection.ts b/packages/driver/src/dom/selection.ts index 649a3cfabd2a..a4ad9af6593a 100644 --- a/packages/driver/src/dom/selection.ts +++ b/packages/driver/src/dom/selection.ts @@ -575,19 +575,7 @@ const _moveSelectionTo = function (toStart: boolean, el: HTMLElement, options = $elements.callNativeMethod(doc, 'execCommand', 'selectAll', false, null) } } else { - let range - - // Sometimes, selection.rangeCount is 0 when there is no selection. - // In that case, it fails in Chrome. - // We're creating a new range and add it to the selection to avoid the case. - if (selection.rangeCount === 0) { - range = doc.createRange() - selection.addRange(range) - } else { - range = selection.getRangeAt(0) - } - - range.selectNodeContents(el) + selection.selectAllChildren(el) } toStart ? selection.collapseToStart() : selection.collapseToEnd() diff --git a/packages/server/lib/browsers/webkit-automation.ts b/packages/server/lib/browsers/webkit-automation.ts index 0ebac526187a..cccf6b52caa7 100644 --- a/packages/server/lib/browsers/webkit-automation.ts +++ b/packages/server/lib/browsers/webkit-automation.ts @@ -83,7 +83,7 @@ const _cookieMatches = (cookie: any, filter: Record) => { let requestIdCounter = 1 const requestIdMap = new WeakMap() -export class WebkitAutomation { +export class WebKitAutomation { private context!: playwright.BrowserContext private page!: playwright.Page @@ -91,7 +91,7 @@ export class WebkitAutomation { // static initializer to avoid "not definitively declared" static async create (automation: Automation, browser: playwright.Browser, initialUrl: string) { - const wkAutomation = new WebkitAutomation(automation, browser) + const wkAutomation = new WebKitAutomation(automation, browser) await wkAutomation.reset(initialUrl) diff --git a/packages/server/lib/browsers/webkit.ts b/packages/server/lib/browsers/webkit.ts index e236a7ecfcf4..58c7661856c6 100644 --- a/packages/server/lib/browsers/webkit.ts +++ b/packages/server/lib/browsers/webkit.ts @@ -3,11 +3,11 @@ import { EventEmitter } from 'events' import type playwright from 'playwright-webkit' import type { Browser, BrowserInstance } from './types' import type { Automation } from '../automation' -import { WebkitAutomation } from './webkit-automation' +import { WebKitAutomation } from './webkit-automation' const debug = Debug('cypress:server:browsers:webkit') -let wkAutomation: WebkitAutomation | undefined +let wkAutomation: WebKitAutomation | undefined export async function connectToNewSpec (browser: Browser, options, automation: Automation) { if (!wkAutomation) throw new Error('connectToNewSpec called without wkAutomation') @@ -31,7 +31,7 @@ export async function open (browser: Browser, url, options: any = {}, automation headless: browser.isHeadless, }) - wkAutomation = await WebkitAutomation.create(automation, pwBrowser, url) + wkAutomation = await WebKitAutomation.create(automation, pwBrowser, url) automation.use(wkAutomation) class WkInstance extends EventEmitter implements BrowserInstance { From 305b38eba099a722e4244c094348f4176bc22b32 Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 25 Aug 2022 10:55:10 -0400 Subject: [PATCH 27/45] Update npm/webpack-dev-server/src/helpers/angularHandler.ts remove optional chaining on buildOptions Co-authored-by: Zachary Williams --- npm/webpack-dev-server/src/helpers/angularHandler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/webpack-dev-server/src/helpers/angularHandler.ts b/npm/webpack-dev-server/src/helpers/angularHandler.ts index b904700c4a00..3fb19982fb48 100644 --- a/npm/webpack-dev-server/src/helpers/angularHandler.ts +++ b/npm/webpack-dev-server/src/helpers/angularHandler.ts @@ -122,8 +122,8 @@ export async function generateTsConfig (devServerConfig: AngularWebpackDevServer includePaths.push(toPosix(cypressConfig.supportFile)) } - if (buildOptions?.polyfills) { - const polyfills = getProjectFilePath(buildOptions?.polyfills) + if (buildOptions.polyfills) { + const polyfills = getProjectFilePath(buildOptions.polyfills) includePaths.push(polyfills) } From 133d6aa1c40b0505cff1eded103d11ccdc6b389a Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 25 Aug 2022 11:49:09 -0400 Subject: [PATCH 28/45] chore: make projectConfig required prop --- npm/webpack-dev-server/src/devServer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/webpack-dev-server/src/devServer.ts b/npm/webpack-dev-server/src/devServer.ts index 5c7a17c1b2bc..1a358937e989 100644 --- a/npm/webpack-dev-server/src/devServer.ts +++ b/npm/webpack-dev-server/src/devServer.ts @@ -23,7 +23,7 @@ type FrameworkConfig = { } | { framework: 'angular' options?: { - projectConfig?: Cypress.AngularDevServerProjectConfig + projectConfig: Cypress.AngularDevServerProjectConfig } } From bd0d38f352b4a239e25b7d5b967502780bcf0877 Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 25 Aug 2022 13:20:53 -0400 Subject: [PATCH 29/45] chore(server): convert modes/run to typescript (#23536) Co-authored-by: Emily Rohrbough --- .../src/actions/ProjectActions.ts | 8 +- .../src/sources/ProjectDataSource.ts | 10 +- packages/server/lib/automation/automation.ts | 2 +- packages/server/lib/makeDataContext.ts | 2 +- packages/server/lib/modes/index.ts | 4 +- packages/server/lib/modes/run.js | 1700 ----------------- packages/server/lib/modes/run.ts | 1661 ++++++++++++++++ packages/server/lib/open_project.ts | 2 +- packages/server/lib/project-base.ts | 3 +- packages/server/lib/video_capture.ts | 4 +- .../server/test/integration/cypress_spec.js | 73 +- packages/server/test/unit/modes/run_spec.js | 966 ---------- packages/types/src/config.ts | 2 +- packages/types/src/server.ts | 3 +- packages/types/src/spec.ts | 4 + 15 files changed, 1717 insertions(+), 2727 deletions(-) delete mode 100644 packages/server/lib/modes/run.js create mode 100644 packages/server/lib/modes/run.ts delete mode 100644 packages/server/test/unit/modes/run_spec.js diff --git a/packages/data-context/src/actions/ProjectActions.ts b/packages/data-context/src/actions/ProjectActions.ts index a24a15309c24..cc8b32e74d98 100644 --- a/packages/data-context/src/actions/ProjectActions.ts +++ b/packages/data-context/src/actions/ProjectActions.ts @@ -1,5 +1,5 @@ import type { CodeGenType, MutationSetProjectPreferencesInGlobalCacheArgs, NexusGenObjects, NexusGenUnions } from '@packages/graphql/src/gen/nxs.gen' -import type { InitializeProjectOptions, FoundBrowser, FoundSpec, LaunchOpts, OpenProjectLaunchOptions, Preferences, TestingType, ReceivedCypressOptions, AddProject, FullConfig, AllowedState } from '@packages/types' +import type { InitializeProjectOptions, FoundBrowser, FoundSpec, LaunchOpts, OpenProjectLaunchOptions, Preferences, TestingType, ReceivedCypressOptions, AddProject, FullConfig, AllowedState, SpecWithRelativeRoot } from '@packages/types' import type { EventEmitter } from 'events' import execa from 'execa' import path from 'path' @@ -40,7 +40,7 @@ export interface ProjectApiShape { setProjectPreferences(stated: AllowedState): void makeProjectSavedState(projectRoot: string): void getDevServer (): { - updateSpecs(specs: FoundSpec[]): void + updateSpecs(specs: SpecWithRelativeRoot[]): void start(options: {specs: Cypress.Spec[], config: FullConfig}): Promise<{port: number}> close(): void emitter: EventEmitter @@ -313,7 +313,7 @@ export class ProjectActions { this.api.setPromptShown(slug) } - setSpecs (specs: FoundSpec[]) { + setSpecs (specs: SpecWithRelativeRoot[]) { this.ctx.project.setSpecs(specs) this.refreshSpecs(specs) @@ -324,7 +324,7 @@ export class ProjectActions { this.ctx.emitter.specsChange() } - refreshSpecs (specs: FoundSpec[]) { + refreshSpecs (specs: SpecWithRelativeRoot[]) { this.ctx.lifecycleManager.git?.setSpecs(specs.map((s) => s.absolute)) } diff --git a/packages/data-context/src/sources/ProjectDataSource.ts b/packages/data-context/src/sources/ProjectDataSource.ts index fab5fd97d693..5e447b622b39 100644 --- a/packages/data-context/src/sources/ProjectDataSource.ts +++ b/packages/data-context/src/sources/ProjectDataSource.ts @@ -1,6 +1,6 @@ import os from 'os' import chokidar from 'chokidar' -import type { ResolvedFromConfig, RESOLVED_FROM, FoundSpec, TestingType } from '@packages/types' +import type { ResolvedFromConfig, RESOLVED_FROM, TestingType, SpecWithRelativeRoot } from '@packages/types' import minimatch from 'minimatch' import _ from 'lodash' import path from 'path' @@ -23,8 +23,6 @@ import type { ProjectShape } from '../data' import type { FindSpecs } from '../actions' import { getDefaultSpecFileName } from './migration/utils' -export type SpecWithRelativeRoot = FoundSpec & { relativeToCommonRoot: string } - interface MatchedSpecs { projectRoot: string testingType: Cypress.TestingType @@ -199,7 +197,7 @@ export function getPathFromSpecPattern ({ export class ProjectDataSource { private _specWatcher: FSWatcher | null = null - private _specs: FoundSpec[] = [] + private _specs: SpecWithRelativeRoot[] = [] constructor (private ctx: DataContext) {} @@ -227,7 +225,7 @@ export class ProjectDataSource { return this._specs } - setSpecs (specs: FoundSpec[]) { + setSpecs (specs: SpecWithRelativeRoot[]) { this._specs = specs } @@ -256,7 +254,7 @@ export class ProjectDataSource { configSpecPattern, excludeSpecPattern, additionalIgnorePattern, - }: FindSpecs): Promise { + }: FindSpecs): Promise { let specAbsolutePaths = await this.ctx.file.getFilesByGlob( projectRoot, specPattern, { diff --git a/packages/server/lib/automation/automation.ts b/packages/server/lib/automation/automation.ts index 1f22001d7c83..7651a2b9965b 100644 --- a/packages/server/lib/automation/automation.ts +++ b/packages/server/lib/automation/automation.ts @@ -184,7 +184,7 @@ export class Automation { } } - get = (fn: keyof AutomationMiddleware) => { + get = (fn: K): AutomationMiddleware[K] => { return this.middleware[fn] } } diff --git a/packages/server/lib/makeDataContext.ts b/packages/server/lib/makeDataContext.ts index c054682dadfb..2fcc8be88fb1 100644 --- a/packages/server/lib/makeDataContext.ts +++ b/packages/server/lib/makeDataContext.ts @@ -118,7 +118,7 @@ export function makeDataContext (options: MakeDataContextOptions): DataContext { return openProject.closeActiveProject() }, getCurrentBrowser () { - return (openProject?.projectBase?.browser) ?? undefined + return (openProject?.getProject()?.browser) ?? undefined }, getConfig () { return openProject.getConfig() diff --git a/packages/server/lib/modes/index.ts b/packages/server/lib/modes/index.ts index 942eb6b39d12..a1389911bd66 100644 --- a/packages/server/lib/modes/index.ts +++ b/packages/server/lib/modes/index.ts @@ -32,11 +32,11 @@ export = (mode, options) => { // a testingType, we default to e2e options.testingType = options.testingType || 'e2e' - return require('./run').run(options, loadingPromise) + return (require('./run') as typeof import('./run')).run(options, loadingPromise) } if (mode === 'interactive') { // Either launchpad or straight to e2e tests - return require('./interactive').run(options, loadingPromise) + return (require('./interactive') as typeof import('./interactive')).run(options, loadingPromise) } } diff --git a/packages/server/lib/modes/run.js b/packages/server/lib/modes/run.js deleted file mode 100644 index 79f38bf3b934..000000000000 --- a/packages/server/lib/modes/run.js +++ /dev/null @@ -1,1700 +0,0 @@ -/* eslint-disable no-console, @cypress/dev/arrow-body-multiline-braces */ -const _ = require('lodash') -const la = require('lazy-ass') -const pkg = require('@packages/root') -const path = require('path') -const chalk = require('chalk') -const human = require('human-interval') -const debug = require('debug')('cypress:server:run') -const Promise = require('bluebird') -const logSymbols = require('log-symbols') -const assert = require('assert') - -const recordMode = require('./record') -const errors = require('../errors') -const Reporter = require('../reporter') -const browserUtils = require('../browsers') -const { openProject } = require('../open_project') -const videoCapture = require('../video_capture') -const { fs } = require('../util/fs') -const runEvents = require('../plugins/run_events') -const env = require('../util/env') -const trash = require('../util/trash') -const random = require('../util/random') -const system = require('../util/system') -const duration = require('../util/duration') -const newlines = require('../util/newlines') -const terminal = require('../util/terminal') -const humanTime = require('../util/human_time') -const chromePolicyCheck = require('../util/chrome_policy_check') -const experiments = require('../experiments') -const objUtils = require('../util/obj_utils') - -const DELAY_TO_LET_VIDEO_FINISH_MS = 1000 - -const color = (val, c) => { - return chalk[c](val) -} - -const gray = (val) => { - return color(val, 'gray') -} - -const colorIf = function (val, c) { - if (val === 0 || val == null) { - val = '-' - c = 'gray' - } - - return color(val, c) -} - -const getSymbol = function (num) { - if (num) { - return logSymbols.error - } - - return logSymbols.success -} - -const getWidth = (table, index) => { - // get the true width of a table's column, - // based off of calculated table options for that column - const columnWidth = table.options.colWidths[index] - - if (columnWidth) { - return columnWidth - (table.options.style['padding-left'] + table.options.style['padding-right']) - } -} - -const relativeSpecPattern = (projectRoot, pattern) => { - if (typeof pattern === 'string') { - return pattern.replace(`${projectRoot}/`, '') - } - - return pattern.map((x) => x.replace(`${projectRoot}/`, '')) -} - -const formatBrowser = (browser) => { - // TODO: finish browser - return _.compact([ - browser.displayName, - browser.majorVersion, - browser.isHeadless && gray('(headless)'), - ]).join(' ') -} - -const formatFooterSummary = (results) => { - const { totalFailed, runs } = results - - const isCanceled = _.some(results.runs, { skippedSpec: true }) - - // pass or fail color - const c = isCanceled ? 'magenta' : totalFailed ? 'red' : 'green' - - const phrase = (() => { - if (isCanceled) { - return 'The run was canceled' - } - - // if we have any specs failing... - if (!totalFailed) { - return 'All specs passed!' - } - - // number of specs - const total = runs.length - const failingRuns = _.filter(runs, 'stats.failures').length - const percent = Math.round((failingRuns / total) * 100) - - return `${failingRuns} of ${total} failed (${percent}%)` - })() - - return [ - isCanceled ? '-' : formatSymbolSummary(totalFailed), - color(phrase, c), - gray(duration.format(results.totalDuration)), - colorIf(results.totalTests, 'reset'), - colorIf(results.totalPassed, 'green'), - colorIf(totalFailed, 'red'), - colorIf(results.totalPending, 'cyan'), - colorIf(results.totalSkipped, 'blue'), - ] -} - -const formatSymbolSummary = (failures) => { - return getSymbol(failures) -} - -const macOSRemovePrivate = (str) => { - // consistent snapshots when running system tests on macOS - if (process.platform === 'darwin' && str.startsWith('/private')) { - return str.slice(8) - } - - return str -} - -const formatPath = (name, n, colour = 'reset', caller) => { - if (!name) return '' - - const fakeCwdPath = env.get('FAKE_CWD_PATH') - - if (fakeCwdPath && env.get('CYPRESS_INTERNAL_ENV') === 'test') { - // if we're testing within Cypress, we want to strip out - // the current working directory before calculating the stdout tables - // this will keep our snapshots consistent everytime we run - const cwdPath = process.cwd() - - name = name - .split(cwdPath) - .join(fakeCwdPath) - - name = macOSRemovePrivate(name) - } - - // add newLines at each n char and colorize the path - if (n) { - let nameWithNewLines = newlines.addNewlineAtEveryNChar(name, n) - - return `${color(nameWithNewLines, colour)}` - } - - return `${color(name, colour)}` -} - -const formatNodeVersion = ({ resolvedNodeVersion, resolvedNodePath }, width) => { - debug('formatting Node version. %o', { version: resolvedNodeVersion, path: resolvedNodePath }) - - if (resolvedNodePath) { - return formatPath(`v${resolvedNodeVersion} ${gray(`(${resolvedNodePath})`)}`, width) - } -} - -const formatRecordParams = function (runUrl, parallel, group, tag) { - if (runUrl) { - if (!group) { - group = false - } - - if (!tag) { - tag = false - } - - return `Tag: ${tag}, Group: ${group}, Parallel: ${Boolean(parallel)}` - } -} - -const displayRunStarting = function (options = {}) { - const { browser, config, group, parallel, runUrl, specPattern, specs, tag } = options - - console.log('') - - terminal.divider('=') - - console.log('') - - terminal.header('Run Starting', { - color: ['reset'], - }) - - console.log('') - - const experimental = experiments.getExperimentsFromResolved(config.resolved) - const enabledExperiments = _.pickBy(experimental, _.property('enabled')) - const hasExperiments = !_.isEmpty(enabledExperiments) - - // if we show Node Version, then increase 1st column width - // to include wider 'Node Version:'. - // Without Node version, need to account for possible "Experiments" label - const colWidths = config.resolvedNodePath ? [16, 84] : ( - hasExperiments ? [14, 86] : [12, 88] - ) - - const table = terminal.table({ - colWidths, - type: 'outsideBorder', - }) - - const formatSpecPattern = (projectRoot, specPattern) => { - // foo.spec.js, bar.spec.js, baz.spec.js - // also inserts newlines at col width - if (typeof specPattern === 'string') { - specPattern = [specPattern] - } - - specPattern = relativeSpecPattern(projectRoot, specPattern) - - if (specPattern) { - return formatPath(specPattern.join(', '), getWidth(table, 1)) - } - } - - const formatSpecs = (specs) => { - // 25 found: (foo.spec.js, bar.spec.js, baz.spec.js) - const names = _.map(specs, 'baseName') - const specsTruncated = _.truncate(names.join(', '), { length: 250 }) - - const stringifiedSpecs = [ - `${names.length} found `, - '(', - specsTruncated, - ')', - ] - .join('') - - return formatPath(stringifiedSpecs, getWidth(table, 1)) - } - - const data = _ - .chain([ - [gray('Cypress:'), pkg.version], - [gray('Browser:'), formatBrowser(browser)], - [gray('Node Version:'), formatNodeVersion(config, getWidth(table, 1))], - [gray('Specs:'), formatSpecs(specs)], - [gray('Searched:'), formatSpecPattern(config.projectRoot, specPattern)], - [gray('Params:'), formatRecordParams(runUrl, parallel, group, tag)], - [gray('Run URL:'), runUrl ? formatPath(runUrl, getWidth(table, 1)) : ''], - [gray('Experiments:'), hasExperiments ? experiments.formatExperiments(enabledExperiments) : ''], - ]) - .filter(_.property(1)) - .value() - - table.push(...data) - - const heading = table.toString() - - console.log(heading) - - console.log('') - - return heading -} - -const displaySpecHeader = function (name, curr, total, estimated) { - console.log('') - - const PADDING = 2 - - const table = terminal.table({ - colWidths: [10, 70, 20], - colAligns: ['left', 'left', 'right'], - type: 'pageDivider', - style: { - 'padding-left': PADDING, - 'padding-right': 0, - }, - }) - - table.push(['', '']) - table.push([ - 'Running:', - `${formatPath(name, getWidth(table, 1), 'gray')}`, - gray(`(${curr} of ${total})`), - ]) - - console.log(table.toString()) - - if (estimated) { - const estimatedLabel = `${' '.repeat(PADDING)}Estimated:` - - return console.log(estimatedLabel, gray(humanTime.long(estimated))) - } -} - -const collectTestResults = (obj = {}, estimated) => { - return { - name: _.get(obj, 'spec.name'), - baseName: _.get(obj, 'spec.baseName'), - tests: _.get(obj, 'stats.tests'), - passes: _.get(obj, 'stats.passes'), - pending: _.get(obj, 'stats.pending'), - failures: _.get(obj, 'stats.failures'), - skipped: _.get(obj, 'stats.skipped'), - duration: humanTime.long(_.get(obj, 'stats.wallClockDuration')), - estimated: estimated && humanTime.long(estimated), - screenshots: obj.screenshots && obj.screenshots.length, - video: Boolean(obj.video), - } -} - -const renderSummaryTable = (runUrl) => { - return function (results) { - const { runs } = results - - console.log('') - - terminal.divider('=') - - console.log('') - - terminal.header('Run Finished', { - color: ['reset'], - }) - - if (runs && runs.length) { - const colAligns = ['left', 'left', 'right', 'right', 'right', 'right', 'right', 'right'] - const colWidths = [3, 41, 11, 9, 9, 9, 9, 9] - - const table1 = terminal.table({ - colAligns, - colWidths, - type: 'noBorder', - head: [ - '', - gray('Spec'), - '', - gray('Tests'), - gray('Passing'), - gray('Failing'), - gray('Pending'), - gray('Skipped'), - ], - }) - - const table2 = terminal.table({ - colAligns, - colWidths, - type: 'border', - }) - - const table3 = terminal.table({ - colAligns, - colWidths, - type: 'noBorder', - head: formatFooterSummary(results), - }) - - _.each(runs, (run) => { - const { spec, stats } = run - - const ms = duration.format(stats.wallClockDuration || 0) - - const formattedSpec = formatPath(spec.baseName, getWidth(table2, 1)) - - if (run.skippedSpec) { - return table2.push([ - '-', - formattedSpec, color('SKIPPED', 'gray'), - '-', '-', '-', '-', '-', - ]) - } - - return table2.push([ - formatSymbolSummary(stats.failures), - formattedSpec, - color(ms, 'gray'), - colorIf(stats.tests, 'reset'), - colorIf(stats.passes, 'green'), - colorIf(stats.failures, 'red'), - colorIf(stats.pending, 'cyan'), - colorIf(stats.skipped, 'blue'), - ]) - }) - - console.log('') - console.log('') - console.log(terminal.renderTables(table1, table2, table3)) - console.log('') - - if (runUrl) { - console.log('') - - const table4 = terminal.table({ - colWidths: [100], - type: 'pageDivider', - style: { - 'padding-left': 2, - }, - }) - - table4.push(['', '']) - console.log(terminal.renderTables(table4)) - - console.log(` Recorded Run: ${formatPath(runUrl, undefined, 'gray')}`) - console.log('') - } - } - } -} - -const iterateThroughSpecs = function (options = {}) { - const { specs, runEachSpec, beforeSpecRun, afterSpecRun, config } = options - - const serial = () => { - return Promise.mapSeries(specs, runEachSpec) - } - - const ranSpecs = [] - const parallelAndSerialWithRecord = (runs) => { - return beforeSpecRun() - .then(({ spec, claimedInstances, totalInstances, estimated, shouldFallbackToOfflineOrder }) => { - // if (!parallel) { - // // NOTE: if we receive the old API which always sends {spec: null}, - // // that would instantly end the run with a 0 exit code if we act like parallel mode. - // // so instead we check length of ran specs just to make sure we have run all the specs. - // // However, this means the api can't end a run early for us without some other logic being added. - - // if (shouldFallbackToOfflineOrder) { - // spec = _.without(specs, ...ranSpecs)[0]?.relative - // } - // } - - // no more specs to run? - if (!spec) { - // then we're done! - return runs - } - - // find the actual spec object amongst - // our specs array since the API sends us - // the relative name - spec = _.find(specs, { relative: spec }) - ranSpecs.push(spec) - - return runEachSpec( - spec, - claimedInstances - 1, - totalInstances, - estimated, - ) - .tap((results) => { - runs.push(results) - - return afterSpecRun(spec, results, config) - }) - .then(() => { - // // no need to make an extra request if we know we've run all the specs - // if (!parallel && ranSpecs.length === specs.length) { - // return runs - // } - - // recurse - return parallelAndSerialWithRecord(runs) - }) - }) - } - - if (beforeSpecRun) { - // if we are running in parallel - // then ask the server for the next spec - return parallelAndSerialWithRecord([]) - } - - // else iterate in serial - return serial() -} - -const getProjectId = Promise.method((project, id) => { - if (id == null) { - id = env.get('CYPRESS_PROJECT_ID') - } - - // if we have an ID just use it - if (id) { - return id - } - - return project.getProjectId() - .catch(() => { - // no id no problem - return null - }) -}) - -const getDefaultBrowserOptsByFamily = (browser, project, writeVideoFrame, onError) => { - la(browserUtils.isBrowserFamily(browser.family), 'invalid browser family in', browser) - - if (browser.name === 'electron') { - return getElectronProps(browser.isHeaded, writeVideoFrame, onError) - } - - if (browser.family === 'chromium') { - return getChromeProps(writeVideoFrame) - } - - if (browser.family === 'firefox') { - return getFirefoxProps(project, writeVideoFrame) - } - - return {} -} - -const getFirefoxProps = (project, writeVideoFrame) => { - debug('setting Firefox properties') - - return _ - .chain({}) - .tap((props) => { - if (writeVideoFrame) { - const onScreencastFrame = (data) => { - writeVideoFrame(data) - } - - project.on('capture:video:frames', onScreencastFrame) - - props.onScreencastFrame = true - } - }) - .value() -} - -const getCdpVideoPropSetter = (writeVideoFrame) => { - if (!writeVideoFrame) { - return _.noop - } - - return (props) => { - props.onScreencastFrame = (e) => { - // https://chromedevtools.github.io/devtools-protocol/tot/Page#event-screencastFrame - writeVideoFrame(Buffer.from(e.data, 'base64')) - } - } -} - -const getChromeProps = (writeVideoFrame) => { - const shouldWriteVideo = Boolean(writeVideoFrame) - - debug('setting Chrome properties %o', { shouldWriteVideo }) - - return _ - .chain({}) - .tap(getCdpVideoPropSetter(writeVideoFrame)) - .value() -} - -const getElectronProps = (isHeaded, writeVideoFrame, onError) => { - return _ - .chain({ - width: 1280, - height: 720, - show: isHeaded, - onCrashed () { - const err = errors.get('RENDERER_CRASHED') - - errors.log(err) - - onError(err) - }, - onNewWindow (e, url, frameName, disposition, options) { - // force new windows to automatically open with show: false - // this prevents window.open inside of javascript client code - // to cause a new BrowserWindow instance to open - // https://github.com/cypress-io/cypress/issues/123 - options.show = false - }, - }) - .tap(getCdpVideoPropSetter(writeVideoFrame)) - .value() -} - -const sumByProp = (runs, prop) => { - return _.sumBy(runs, prop) || 0 -} - -const getRun = (run, prop) => { - return _.get(run, prop) -} - -const writeOutput = (outputPath, results) => { - return Promise.try(() => { - if (!outputPath) { - return - } - - debug('saving output results %o', { outputPath }) - - return fs.outputJsonAsync(outputPath, results) - }) -} - -const onWarning = (err) => { - console.log(chalk.yellow(err.message)) -} - -const openProjectCreate = (projectRoot, socketId, args) => { - // now open the project to boot the server - // putting our web client app in headless mode - // - NO display server logs (via morgan) - // - YES display reporter results (via mocha reporter) - const options = { - socketId, - morgan: false, - report: true, - isTextTerminal: args.isTextTerminal, - // pass the list of browsers we have detected when opening a project - // to give user's plugins file a chance to change it - browsers: args.browsers, - onWarning, - spec: args.spec, - onError: args.onError, - } - - return openProject.create(projectRoot, args, options, args.browsers) -} - -async function checkAccess (folderPath) { - return fs.access(folderPath, fs.W_OK).catch((err) => { - if (['EACCES', 'EPERM'].includes(err.code)) { - // we cannot write due to folder permissions - return errors.warning('FOLDER_NOT_WRITABLE', folderPath) - } - - throw err - }) -} - -const createAndOpenProject = async (options) => { - const { projectRoot, projectId, socketId } = options - - await checkAccess(projectRoot) - - const open_project = await openProjectCreate(projectRoot, socketId, options) - const project = open_project.getProject() - - const [_project, _config, _projectId] = await Promise.all([ - project, - project.getConfig(), - getProjectId(project, projectId), - ]) - - return { - project: _project, - config: _config, - projectId: _projectId, - // Lazy require'd here, so as to not execute until we're in the electron process - configFile: require('@packages/data-context').getCtx().lifecycleManager.configFile, - } -} - -const removeOldProfiles = (browser) => { - return browserUtils.removeOldProfiles(browser) - .catch((err) => { - // dont make removing old browsers profiles break the build - return errors.warning('CANNOT_REMOVE_OLD_BROWSER_PROFILES', err) - }) -} - -const trashAssets = Promise.method((config = {}) => { - if (config.trashAssetsBeforeRuns !== true) { - return - } - - return Promise.all([ - trash.folder(config.videosFolder), - trash.folder(config.screenshotsFolder), - trash.folder(config.downloadsFolder), - ]) - .catch((err) => { - // dont make trashing assets fail the build - return errors.warning('CANNOT_TRASH_ASSETS', err) - }) -}) - -const createVideoRecording = function (videoName, options = {}) { - const outputDir = path.dirname(videoName) - - const onError = _.once((err) => { - // catch video recording failures and log them out - // but don't let this affect the run at all - return errors.warning('VIDEO_RECORDING_FAILED', err) - }) - - return fs - .ensureDirAsync(outputDir) - .catch(onError) - .then(() => { - return videoCapture - .start(videoName, _.extend({}, options, { onError })) - }) -} - -const getVideoRecordingDelay = function (startedVideoCapture) { - if (startedVideoCapture) { - return DELAY_TO_LET_VIDEO_FINISH_MS - } - - return 0 -} - -const maybeStartVideoRecording = Promise.method(function (options = {}) { - const { spec, browser, video, videosFolder } = options - - debug(`video recording has been ${video ? 'enabled' : 'disabled'}. video: %s`, video) - // bail if we've been told not to capture - // a video recording - if (!video) { - return - } - - // make sure we have a videosFolder - if (!videosFolder) { - throw new Error('Missing videoFolder for recording') - } - - const videoPath = (suffix) => { - return path.join(videosFolder, spec.relativeToCommonRoot + suffix) - } - - const videoName = videoPath('.mp4') - const compressedVideoName = videoPath('-compressed.mp4') - - return this.createVideoRecording(videoName, { webmInput: browser.family === 'firefox' }) - .then((props = {}) => { - return { - videoName, - compressedVideoName, - endVideoCapture: props.endVideoCapture, - writeVideoFrame: props.writeVideoFrame, - startedVideoCapture: props.startedVideoCapture, - } - }) -}) - -const warnVideoRecordingFailed = (err) => { - // log that post processing was attempted - // but failed and dont let this change the run exit code - errors.warning('VIDEO_POST_PROCESSING_FAILED', err) -} - -module.exports = { - getProjectId, - - writeOutput, - - openProjectCreate, - - createVideoRecording, - - getVideoRecordingDelay, - - maybeStartVideoRecording, - - getChromeProps, - - getElectronProps, - - displayRunStarting, - - navigateToNextSpec (spec) { - debug('navigating to next spec %s', spec) - - return openProject.changeUrlToSpec(spec) - }, - - exitEarly (err) { - debug('set early exit error: %s', err.stack) - - this.earlyExitErr = err - }, - - displayResults (obj = {}, estimated) { - const results = collectTestResults(obj, estimated) - - const c = results.failures ? 'red' : 'green' - - console.log('') - - terminal.header('Results', { - color: [c], - }) - - const table = terminal.table({ - colWidths: [14, 86], - type: 'outsideBorder', - }) - - const data = _.chain([ - ['Tests:', results.tests], - ['Passing:', results.passes], - ['Failing:', results.failures], - ['Pending:', results.pending], - ['Skipped:', results.skipped], - ['Screenshots:', results.screenshots], - ['Video:', results.video], - ['Duration:', results.duration], - estimated ? ['Estimated:', results.estimated] : undefined, - ['Spec Ran:', formatPath(results.baseName, getWidth(table, 1), c)], - ]) - .compact() - .map((arr) => { - const [key, val] = arr - - return [color(key, 'gray'), color(val, c)] - }) - .value() - - table.push(...data) - - console.log('') - console.log(table.toString()) - console.log('') - }, - - displayScreenshots (screenshots = []) { - console.log('') - - terminal.header('Screenshots', { color: ['yellow'] }) - - console.log('') - - const table = terminal.table({ - colWidths: [3, 82, 15], - colAligns: ['left', 'left', 'right'], - type: 'noBorder', - style: { - 'padding-right': 0, - }, - chars: { - 'left': ' ', - 'right': '', - }, - }) - - screenshots.forEach((screenshot) => { - const dimensions = gray(`(${screenshot.width}x${screenshot.height})`) - - table.push([ - '-', - formatPath(`${screenshot.path}`, getWidth(table, 1)), - gray(dimensions), - ]) - }) - - console.log(table.toString()) - - console.log('') - }, - - async postProcessRecording (name, cname, videoCompression, shouldUploadVideo, quiet, ffmpegChaptersConfig) { - debug('ending the video recording %o', { name, videoCompression, shouldUploadVideo }) - - // once this ended promises resolves - // then begin processing the file - // dont process anything if videoCompress is off - // or we've been told not to upload the video - if (videoCompression === false || shouldUploadVideo === false) { - return - } - - function continueProcessing (onProgress = undefined) { - return videoCapture.process(name, cname, videoCompression, ffmpegChaptersConfig, onProgress) - } - - if (quiet) { - return continueProcessing() - } - - console.log('') - - terminal.header('Video', { - color: ['cyan'], - }) - - console.log('') - - const table = terminal.table({ - colWidths: [3, 21, 76], - colAligns: ['left', 'left', 'left'], - type: 'noBorder', - style: { - 'padding-right': 0, - }, - chars: { - 'left': ' ', - 'right': '', - }, - }) - - table.push([ - gray('-'), - gray('Started processing:'), - chalk.cyan(`Compressing to ${videoCompression} CRF`), - ]) - - console.log(table.toString()) - - const started = Date.now() - let progress = Date.now() - const throttle = env.get('VIDEO_COMPRESSION_THROTTLE') || human('10 seconds') - - const onProgress = function (float) { - if (float === 1) { - const finished = Date.now() - started - const dur = `(${humanTime.long(finished)})` - - const table = terminal.table({ - colWidths: [3, 21, 61, 15], - colAligns: ['left', 'left', 'left', 'right'], - type: 'noBorder', - style: { - 'padding-right': 0, - }, - chars: { - 'left': ' ', - 'right': '', - }, - }) - - table.push([ - gray('-'), - gray('Finished processing:'), - `${formatPath(name, getWidth(table, 2), 'cyan')}`, - gray(dur), - ]) - - console.log(table.toString()) - - console.log('') - } - - if (Date.now() - progress > throttle) { - // bump up the progress so we dont - // continuously get notifications - progress += throttle - const percentage = `${Math.ceil(float * 100)}%` - - console.log(' Compression progress: ', chalk.cyan(percentage)) - } - } - - return continueProcessing(onProgress) - }, - - launchBrowser (options = {}) { - const { browser, spec, writeVideoFrame, setScreenshotMetadata, project, screenshots, projectRoot, shouldLaunchNewTab, onError } = options - - const browserOpts = getDefaultBrowserOptsByFamily(browser, project, writeVideoFrame, onError) - - browserOpts.automationMiddleware = { - onBeforeRequest (message, data) { - if (message === 'take:screenshot') { - return setScreenshotMetadata(data) - } - }, - onAfterResponse: (message, data, resp) => { - if (message === 'take:screenshot' && resp) { - const existingScreenshot = _.findIndex(screenshots, { path: resp.path }) - - if (existingScreenshot !== -1) { - // NOTE: saving screenshots to the same path will overwrite the previous one - // so we shouldn't report more screenshots than exist on disk. - // this happens when cy.screenshot is used in a retried test - screenshots.splice(existingScreenshot, 1, this.screenshotMetadata(data, resp)) - } else { - screenshots.push(this.screenshotMetadata(data, resp)) - } - } - - return resp - }, - } - - const warnings = {} - - browserOpts.projectRoot = projectRoot - browserOpts.shouldLaunchNewTab = shouldLaunchNewTab - - browserOpts.onWarning = (err) => { - const { message } = err - - // if this warning has already been - // seen for this browser launch then - // suppress it - if (warnings[message]) { - return - } - - warnings[message] = err - - return project.onWarning - } - - debug('browser launched') - - return openProject.launch(browser, spec, browserOpts) - }, - - listenForProjectEnd (project, exit) { - return new Promise((resolve, reject) => { - if (exit === false) { - resolve = () => { - console.log('not exiting due to options.exit being false') - } - } - - const onEarlyExit = function (err) { - if (err.isFatalApiErr) { - return reject(err) - } - - console.log('') - errors.log(err) - - // probably should say we ended - // early too: (Ended Early: true) - // in the stats - const obj = { - error: errors.stripAnsi(err.message), - stats: { - failures: 1, - tests: 0, - passes: 0, - pending: 0, - suites: 0, - skipped: 0, - wallClockDuration: 0, - wallClockStartedAt: new Date().toJSON(), - wallClockEndedAt: new Date().toJSON(), - }, - } - - return resolve(obj) - } - - const onEnd = (obj) => { - return resolve(obj) - } - - // when our project fires its end event - // resolve the promise - project.once('end', onEnd) - - // if we already received a reason to exit early, go ahead and do it - if (this.earlyExitErr) { - return onEarlyExit(this.earlyExitErr) - } - - // otherwise override exitEarly so we exit as soon as there is a reason - this.exitEarly = (err) => { - onEarlyExit(err) - } - }) - }, - - /** - * In CT mode, browser do not relaunch. - * In browser laucnh is where we wire the new video - * recording callback. - * This has the effect of always hitting the first specs - * video callback. - * - * This allows us, if we need to, to call a different callback - * in the same browser - */ - writeVideoFrameCallback () { - return this.currentWriteVideoFrameCallback(...arguments) - }, - - waitForBrowserToConnect (options = {}) { - const { project, socketId, timeout, onError, writeVideoFrame, spec } = options - const browserTimeout = process.env.CYPRESS_INTERNAL_BROWSER_CONNECT_TIMEOUT || timeout || 60000 - let attempts = 0 - - // short circuit current browser callback so that we - // can rewire it without relaunching the browser - if (writeVideoFrame) { - this.currentWriteVideoFrameCallback = writeVideoFrame - options.writeVideoFrame = this.writeVideoFrameCallback.bind(this) - } - - // without this the run mode is only setting new spec - // path for next spec in launch browser. - // we need it to run on every spec even in single browser mode - this.currentSetScreenshotMetadata = (data) => { - data.specName = spec.relativeToCommonRoot - - return data - } - - options.setScreenshotMetadata = (data) => { - return this.currentSetScreenshotMetadata(data) - } - - if (options.experimentalSingleTabRunMode && options.testingType === 'component' && !options.isFirstSpec) { - // reset browser state to match default behavior when opening/closing a new tab - return openProject.resetBrowserState().then(() => { - // If we do not launch the browser, - // we tell it that we are ready - // to receive the next spec - return this.navigateToNextSpec(options.spec) - }) - } - - const wait = () => { - debug('waiting for socket to connect and browser to launch...') - - return Promise.join( - this.waitForSocketConnection(project, socketId) - .tap(() => { - debug('socket connected', { socketId }) - }), - this.launchBrowser(options), - ) - .timeout(browserTimeout) - .catch(Promise.TimeoutError, (err) => { - attempts += 1 - - console.log('') - - // always first close the open browsers - // before retrying or dieing - return openProject.closeBrowser() - .then(() => { - if (attempts === 1 || attempts === 2) { - // try again up to 3 attempts - const word = attempts === 1 ? 'Retrying...' : 'Retrying again...' - - errors.warning('TESTS_DID_NOT_START_RETRYING', word) - - return wait() - } - - err = errors.get('TESTS_DID_NOT_START_FAILED') - errors.log(err) - - onError(err) - }) - }) - } - - return wait() - }, - - waitForSocketConnection (project, id) { - debug('waiting for socket connection... %o', { id }) - - return new Promise((resolve, reject) => { - const fn = function (socketId) { - debug('got socket connection %o', { id: socketId }) - - if (socketId === id) { - // remove the event listener if we've connected - project.removeListener('socket:connected', fn) - - // resolve the promise - return resolve() - } - } - - // when a socket connects verify this - // is the one that matches our id! - return project.on('socket:connected', fn) - }) - }, - - waitForTestsToFinishRunning (options = {}) { - const { project, screenshots, startedVideoCapture, endVideoCapture, videoName, compressedVideoName, videoCompression, videoUploadOnPasses, exit, spec, estimated, quiet, config, shouldKeepTabOpen, testingType } = options - - // https://github.com/cypress-io/cypress/issues/2370 - // delay 1 second if we're recording a video to give - // the browser padding to render the final frames - // to avoid chopping off the end of the video - const delay = this.getVideoRecordingDelay(startedVideoCapture) - - return this.listenForProjectEnd(project, exit) - .delay(delay) - .then(async (results) => { - _.defaults(results, { - error: null, - hooks: null, - tests: null, - video: null, - screenshots: null, - reporterStats: null, - }) - - // dashboard told us to skip this spec - const skippedSpec = results.skippedSpec - - if (startedVideoCapture) { - results.video = videoName - } - - if (screenshots) { - results.screenshots = screenshots - } - - results.spec = spec - - const { tests, stats } = results - const attempts = _.flatMap(tests, (test) => test.attempts) - - // if we have a video recording - if (startedVideoCapture && tests && tests.length) { - // always set the video timestamp on tests - Reporter.setVideoTimestamp(startedVideoCapture, attempts) - } - - let videoCaptureFailed = false - - if (endVideoCapture) { - await endVideoCapture() - .tapCatch(() => videoCaptureFailed = true) - .catch(warnVideoRecordingFailed) - } - - await runEvents.execute('after:spec', config, spec, results) - - const videoExists = videoName ? await fs.pathExists(videoName) : false - - if (startedVideoCapture && !videoExists) { - // the video file no longer exists at the path where we expect it, - // likely because the user deleted it in the after:spec event - debug(`No video found after spec ran - skipping processing. Video path: ${videoName}`) - - results.video = null - } - - const hasFailingTests = _.get(stats, 'failures') > 0 - // we should upload the video if we upload on passes (by default) - // or if we have any failures and have started the video - const shouldUploadVideo = !skippedSpec && videoUploadOnPasses === true || Boolean((startedVideoCapture && hasFailingTests)) - - results.shouldUploadVideo = shouldUploadVideo - - if (!quiet && !skippedSpec) { - this.displayResults(results, estimated) - if (screenshots && screenshots.length) { - this.displayScreenshots(screenshots) - } - } - - const usingExperimentalSingleTabMode = testingType === 'component' && config.experimentalSingleTabRunMode - - if (usingExperimentalSingleTabMode) { - await openProject.projectBase.server.destroyAut() - } - - // we do not support experimentalSingleTabRunMode for e2e - if (!usingExperimentalSingleTabMode) { - debug('attempting to close the browser tab') - - await openProject.resetBrowserTabsForNextTest(shouldKeepTabOpen) - - debug('resetting server state') - - openProject.projectBase.server.reset() - } - - if (videoExists && !skippedSpec && endVideoCapture && !videoCaptureFailed) { - const ffmpegChaptersConfig = videoCapture.generateFfmpegChaptersConfig(results.tests) - - await this.postProcessRecording( - videoName, - compressedVideoName, - videoCompression, - shouldUploadVideo, - quiet, - ffmpegChaptersConfig, - ) - .catch(warnVideoRecordingFailed) - } - - return results - }) - }, - - screenshotMetadata (data, resp) { - return { - screenshotId: random.id(), - name: data.name || null, - testId: data.testId, - testAttemptIndex: data.testAttemptIndex, - takenAt: resp.takenAt, - path: resp.path, - height: resp.dimensions.height, - width: resp.dimensions.width, - } - }, - - runSpecs (options = {}) { - const { config, browser, sys, headed, outputPath, specs, specPattern, beforeSpecRun, afterSpecRun, runUrl, parallel, group, tag, testingType } = options - - const isHeadless = !headed - - browser.isHeadless = isHeadless - browser.isHeaded = !isHeadless - - const results = { - startedTestsAt: null, - endedTestsAt: null, - totalDuration: null, - totalSuites: null, - totalTests: null, - totalFailed: null, - totalPassed: null, - totalPending: null, - totalSkipped: null, - runs: null, - browserPath: browser.path, - browserName: browser.name, - browserVersion: browser.version, - osName: sys.osName, - osVersion: sys.osVersion, - cypressVersion: pkg.version, - runUrl, - config, - } - - if (!options.quiet) { - displayRunStarting({ - config, - specs, - group, - tag, - runUrl, - browser, - parallel, - specPattern, - }) - } - - let isFirstSpec = true - - const runEachSpec = (spec, index, length, estimated) => { - if (!options.quiet) { - displaySpecHeader(spec.baseName, index + 1, length, estimated) - } - - return this.runSpec(config, spec, options, estimated, isFirstSpec, index === length - 1) - .tap(() => { - isFirstSpec = false - }) - .get('results') - .tap((results) => { - return debug('spec results %o', results) - }) - } - - const beforeRunDetails = { - browser, - config, - cypressVersion: pkg.version, - group, - parallel, - runUrl, - specs, - specPattern, - system: _.pick(sys, 'osName', 'osVersion'), - tag, - } - - return runEvents.execute('before:run', config, beforeRunDetails) - .then(() => { - return iterateThroughSpecs({ - specs, - config, - parallel, - runEachSpec, - afterSpecRun, - beforeSpecRun, - }) - }) - .then((runs = []) => { - results.status = 'finished' - results.startedTestsAt = getRun(_.first(runs), 'stats.wallClockStartedAt') - results.endedTestsAt = getRun(_.last(runs), 'stats.wallClockEndedAt') - results.totalDuration = sumByProp(runs, 'stats.wallClockDuration') - results.totalSuites = sumByProp(runs, 'stats.suites') - results.totalTests = sumByProp(runs, 'stats.tests') - results.totalPassed = sumByProp(runs, 'stats.passes') - results.totalPending = sumByProp(runs, 'stats.pending') - results.totalFailed = sumByProp(runs, 'stats.failures') - results.totalSkipped = sumByProp(runs, 'stats.skipped') - results.runs = runs - - debug('final results of all runs: %o', results) - - const { each, remapKeys, remove, renameKey, setValue } = objUtils - - // Remap results for module API/after:run to remove private props and - // rename props to make more user-friendly - const moduleAPIResults = remapKeys(results, { - runs: each((run) => ({ - tests: each((test) => ({ - attempts: each((attempt, i) => ({ - timings: remove, - failedFromHookId: remove, - wallClockDuration: renameKey('duration'), - wallClockStartedAt: renameKey('startedAt'), - wallClockEndedAt: renameKey('endedAt'), - screenshots: setValue( - _(run.screenshots) - .filter({ testId: test.testId, testAttemptIndex: i }) - .map((screenshot) => _.omit(screenshot, - ['screenshotId', 'testId', 'testAttemptIndex'])) - .value(), - ), - })), - testId: remove, - })), - hooks: each({ - hookId: remove, - }), - stats: { - wallClockDuration: renameKey('duration'), - wallClockStartedAt: renameKey('startedAt'), - wallClockEndedAt: renameKey('endedAt'), - }, - screenshots: remove, - })), - }) - - return Promise.try(() => { - return testingType === 'component' && - openProject.closeBrowser() - }) - .then(() => { - return runEvents.execute('after:run', config, moduleAPIResults) - }) - .then(() => { - return writeOutput(outputPath, moduleAPIResults) - }) - .return(results) - }) - }, - - runSpec (config, spec = {}, options = {}, estimated, isFirstSpec, isLastSpec) { - const { project, browser, onError } = options - - const { isHeadless } = browser - - debug('about to run spec %o', { - spec, - isHeadless, - browser, - }) - - if (browser.family !== 'chromium' && !options.config.chromeWebSecurity) { - console.log('') - errors.warning('CHROME_WEB_SECURITY_NOT_SUPPORTED', browser.family) - } - - const screenshots = [] - - return runEvents.execute('before:spec', config, spec) - .then(() => { - // we know we're done running headlessly - // when the renderer has connected and - // finishes running all of the tests. - // we're using an event emitter interface - // to gracefully handle this in promise land - return this.maybeStartVideoRecording({ - spec, - browser, - video: options.video, - videosFolder: options.videosFolder, - }) - }) - .then((videoRecordProps = {}) => { - return Promise.props({ - results: this.waitForTestsToFinishRunning({ - spec, - config, - project, - estimated, - screenshots, - videoName: videoRecordProps.videoName, - compressedVideoName: videoRecordProps.compressedVideoName, - endVideoCapture: videoRecordProps.endVideoCapture, - startedVideoCapture: videoRecordProps.startedVideoCapture, - exit: options.exit, - testingType: options.testingType, - videoCompression: options.videoCompression, - videoUploadOnPasses: options.videoUploadOnPasses, - quiet: options.quiet, - browser, - shouldKeepTabOpen: !isLastSpec, - }), - - connection: this.waitForBrowserToConnect({ - spec, - project, - browser, - screenshots, - onError, - writeVideoFrame: videoRecordProps.writeVideoFrame, - socketId: options.socketId, - webSecurity: options.webSecurity, - projectRoot: options.projectRoot, - testingType: options.testingType, - isFirstSpec, - experimentalSingleTabRunMode: config.experimentalSingleTabRunMode, - shouldLaunchNewTab: !isFirstSpec, // !process.env.CYPRESS_INTERNAL_FORCE_BROWSER_RELAUNCH && !isFirstSpec, - }), - }) - }) - }, - - ready (options = {}) { - debug('run mode ready with options %o', options) - - if (process.env.ELECTRON_RUN_AS_NODE && !process.env.DISPLAY) { - debug('running electron as a node process without xvfb') - } - - _.defaults(options, { - isTextTerminal: true, - browser: 'electron', - quiet: false, - }) - - const { projectRoot, record, key, ciBuildId, parallel, group, browser: browserName, tag, testingType, socketId } = options - - assert(socketId) - - // this needs to be a closure over `this.exitEarly` and not a reference - // because `this.exitEarly` gets overwritten in `this.listenForProjectEnd` - const onError = options.onError = (err) => { - this.exitEarly(err) - } - - // alias and coerce to null - let specPatternFromCli = options.spec || null - - // ensure the project exists - // and open up the project - return browserUtils.getAllBrowsersWith() - .then((browsers) => { - debug('found all system browsers %o', browsers) - options.browsers = browsers - - return createAndOpenProject(options) - .then(({ project, projectId, config, configFile }) => { - debug('project created and opened with config %o', config) - - // if we have a project id and a key but record hasnt been given - recordMode.warnIfProjectIdButNoRecordOption(projectId, options) - recordMode.throwIfRecordParamsWithoutRecording(record, ciBuildId, parallel, group, tag) - - if (record) { - recordMode.throwIfNoProjectId(projectId, configFile) - recordMode.throwIfIncorrectCiBuildIdUsage(ciBuildId, parallel, group) - recordMode.throwIfIndeterminateCiBuildId(ciBuildId, parallel, group) - } - - // user code might have modified list of allowed browsers - // but be defensive about it - const userBrowsers = _.get(config, 'resolved.browsers.value', browsers) - - let specPattern = specPatternFromCli || config.specPattern - - specPattern = relativeSpecPattern(projectRoot, specPattern) - - return Promise.all([ - system.info(), - (async () => { - const browsers = await browserUtils.ensureAndGetByNameOrPath(browserName, false, userBrowsers) - - await removeOldProfiles(browsers) - - return browsers - })(), - trashAssets(config), - ]) - .spread(async (sys = {}, browser = {}) => { - if (!project.ctx.project.specs.length) { - errors.throwErr('NO_SPECS_FOUND', projectRoot, specPattern) - } - - const specs = project.ctx.project.specs - - if (browser.unsupportedVersion && browser.warning) { - errors.throwErr('UNSUPPORTED_BROWSER_VERSION', browser.warning) - } - - if (browser.family === 'chromium') { - chromePolicyCheck.run(onWarning) - } - - const runAllSpecs = ({ beforeSpecRun, afterSpecRun, runUrl, parallel }) => { - return this.runSpecs({ - beforeSpecRun, - afterSpecRun, - projectRoot, - socketId, - parallel, - onError, - browser, - project, - runUrl, - group, - config, - specs, - sys, - tag, - specPattern, - videosFolder: config.videosFolder, - video: config.video, - videoCompression: config.videoCompression, - videoUploadOnPasses: config.videoUploadOnPasses, - headed: options.headed, - quiet: options.quiet, - outputPath: options.outputPath, - testingType: options.testingType, - exit: options.exit, - }) - .tap((runSpecs) => { - if (!options.quiet) { - renderSummaryTable(runUrl)(runSpecs) - } - }) - } - - if (record) { - const { projectName } = config - - return recordMode.createRunAndRecordSpecs({ - tag, - key, - sys, - specs, - group, - config, - browser, - parallel, - ciBuildId, - testingType, - project, - projectId, - projectRoot, - projectName, - specPattern, - runAllSpecs, - onError, - quiet: options.quiet, - }) - } - - // not recording, can't be parallel - return runAllSpecs({ - parallel: false, - }) - }) - }) - }) - }, - - async run (options, loading = Promise.resolve()) { - if (require('../util/electron-app').isRunningAsElectronProcess({ debug })) { - const app = require('electron').app - - // electron >= 5.0.0 will exit the app if all browserwindows are closed, - // this is obviously undesirable in run mode - // https://github.com/cypress-io/cypress/pull/4720#issuecomment-514316695 - app.on('window-all-closed', () => { - debug('all BrowserWindows closed, not exiting') - }) - - await app.whenReady() - } - - await loading - try { - return this.ready(options) - } catch (e) { - return this.exitEarly(e) - } - }, -} diff --git a/packages/server/lib/modes/run.ts b/packages/server/lib/modes/run.ts new file mode 100644 index 000000000000..6d2f7ab0b464 --- /dev/null +++ b/packages/server/lib/modes/run.ts @@ -0,0 +1,1661 @@ +/* eslint-disable no-console, @cypress/dev/arrow-body-multiline-braces */ +import _ from 'lodash' +import la from 'lazy-ass' +import pkg from '@packages/root' +import path from 'path' +import chalk from 'chalk' +import human from 'human-interval' +import Debug from 'debug' +import Bluebird from 'bluebird' +import logSymbols from 'log-symbols' +import assert from 'assert' + +import recordMode from './record' +import * as errors from '../errors' +import Reporter from '../reporter' +import browserUtils from '../browsers' +import { openProject } from '../open_project' +import * as videoCapture from '../video_capture' +import { fs } from '../util/fs' +import runEvents from '../plugins/run_events' +import env from '../util/env' +import trash from '../util/trash' +import random from '../util/random' +import system from '../util/system' +import duration from '../util/duration' +import newlines from '../util/newlines' +import terminal from '../util/terminal' +import humanTime from '../util/human_time' +import chromePolicyCheck from '../util/chrome_policy_check' +import * as experiments from '../experiments' +import * as objUtils from '../util/obj_utils' +import type { SpecWithRelativeRoot, LaunchOpts, SpecFile, TestingType } from '@packages/types' +import type { Cfg } from '../project-base' +import type { Browser } from '../browsers/types' + +type Screenshot = { + width: number + height: number + path: string + specName: string +} +type SetScreenshotMetadata = (data: Screenshot) => void +type ScreenshotMetadata = ReturnType +type RunEachSpec = any +type BeforeSpecRun = any +type AfterSpecRun = any +type Project = NonNullable> + +let exitEarly = (err) => { + debug('set early exit error: %s', err.stack) + + earlyExitErr = err +} +let earlyExitErr: Error +let currentWriteVideoFrameCallback: videoCapture.WriteVideoFrame +let currentSetScreenshotMetadata: SetScreenshotMetadata + +const debug = Debug('cypress:server:run') + +const DELAY_TO_LET_VIDEO_FINISH_MS = 1000 + +const color = (val, c) => { + return chalk[c](val) +} + +const gray = (val) => { + return color(val, 'gray') +} + +const colorIf = function (val, c) { + if (val === 0 || val == null) { + val = '-' + c = 'gray' + } + + return color(val, c) +} + +const getSymbol = function (num?: number) { + if (num) { + return logSymbols.error + } + + return logSymbols.success +} + +const getWidth = (table, index) => { + // get the true width of a table's column, + // based off of calculated table options for that column + const columnWidth = table.options.colWidths[index] + + if (columnWidth) { + return columnWidth - (table.options.style['padding-left'] + table.options.style['padding-right']) + } + + throw new Error('Unable to get width for column') +} + +const relativeSpecPattern = (projectRoot, pattern) => { + if (typeof pattern === 'string') { + return pattern.replace(`${projectRoot}/`, '') + } + + return pattern.map((x) => x.replace(`${projectRoot}/`, '')) +} + +const formatBrowser = (browser) => { + // TODO: finish browser + return _.compact([ + browser.displayName, + browser.majorVersion, + browser.isHeadless && gray('(headless)'), + ]).join(' ') +} + +const formatFooterSummary = (results) => { + const { totalFailed, runs } = results + + const isCanceled = _.some(results.runs, { skippedSpec: true }) + + // pass or fail color + const c = isCanceled ? 'magenta' : totalFailed ? 'red' : 'green' + + const phrase = (() => { + if (isCanceled) { + return 'The run was canceled' + } + + // if we have any specs failing... + if (!totalFailed) { + return 'All specs passed!' + } + + // number of specs + const total = runs.length + const failingRuns = _.filter(runs, 'stats.failures').length + const percent = Math.round((failingRuns / total) * 100) + + return `${failingRuns} of ${total} failed (${percent}%)` + })() + + return [ + isCanceled ? '-' : formatSymbolSummary(totalFailed), + color(phrase, c), + gray(duration.format(results.totalDuration)), + colorIf(results.totalTests, 'reset'), + colorIf(results.totalPassed, 'green'), + colorIf(totalFailed, 'red'), + colorIf(results.totalPending, 'cyan'), + colorIf(results.totalSkipped, 'blue'), + ] +} + +const formatSymbolSummary = (failures) => { + return getSymbol(failures) +} + +const macOSRemovePrivate = (str: string): string => { + // consistent snapshots when running system tests on macOS + if (process.platform === 'darwin' && str.startsWith('/private')) { + return str.slice(8) + } + + return str +} + +const formatPath = (name, n, colour = 'reset', caller?) => { + if (!name) return '' + + const fakeCwdPath = env.get('FAKE_CWD_PATH') + + if (fakeCwdPath && env.get('CYPRESS_INTERNAL_ENV') === 'test') { + // if we're testing within Cypress, we want to strip out + // the current working directory before calculating the stdout tables + // this will keep our snapshots consistent everytime we run + const cwdPath = process.cwd() + + name = name + .split(cwdPath) + .join(fakeCwdPath) + + name = macOSRemovePrivate(name) + } + + // add newLines at each n char and colorize the path + if (n) { + let nameWithNewLines = newlines.addNewlineAtEveryNChar(name, n) + + return `${color(nameWithNewLines, colour)}` + } + + return `${color(name, colour)}` +} + +const formatNodeVersion = ({ resolvedNodeVersion, resolvedNodePath }: Pick, width) => { + debug('formatting Node version. %o', { version: resolvedNodeVersion, path: resolvedNodePath }) + + if (resolvedNodePath) return formatPath(`v${resolvedNodeVersion} ${gray(`(${resolvedNodePath})`)}`, width) + + return +} + +const formatRecordParams = function (runUrl, parallel, group, tag) { + if (runUrl) { + if (!group) { + group = false + } + + if (!tag) { + tag = false + } + + return `Tag: ${tag}, Group: ${group}, Parallel: ${Boolean(parallel)}` + } + + return +} + +const displayRunStarting = function (options: { browser: Browser, config: Cfg, group: string | undefined, parallel?: boolean, runUrl?: string, specPattern: string | RegExp | string[], specs: SpecFile[], tag: string | undefined }) { + const { browser, config, group, parallel, runUrl, specPattern, specs, tag } = options + + console.log('') + + terminal.divider('=') + + console.log('') + + terminal.header('Run Starting', { + color: ['reset'], + }) + + console.log('') + + const experimental = experiments.getExperimentsFromResolved(config.resolved) + const enabledExperiments = _.pickBy(experimental, _.property('enabled')) + const hasExperiments = !_.isEmpty(enabledExperiments) + + // if we show Node Version, then increase 1st column width + // to include wider 'Node Version:'. + // Without Node version, need to account for possible "Experiments" label + const colWidths = config.resolvedNodePath ? [16, 84] : ( + hasExperiments ? [14, 86] : [12, 88] + ) + + const table = terminal.table({ + colWidths, + type: 'outsideBorder', + }) + + const formatSpecPattern = (projectRoot, specPattern) => { + // foo.spec.js, bar.spec.js, baz.spec.js + // also inserts newlines at col width + if (typeof specPattern === 'string') { + specPattern = [specPattern] + } + + specPattern = relativeSpecPattern(projectRoot, specPattern) + + if (specPattern) { + return formatPath(specPattern.join(', '), getWidth(table, 1)) + } + + throw new Error('No specPattern in formatSpecPattern') + } + + const formatSpecs = (specs) => { + // 25 found: (foo.spec.js, bar.spec.js, baz.spec.js) + const names = _.map(specs, 'baseName') + const specsTruncated = _.truncate(names.join(', '), { length: 250 }) + + const stringifiedSpecs = [ + `${names.length} found `, + '(', + specsTruncated, + ')', + ] + .join('') + + return formatPath(stringifiedSpecs, getWidth(table, 1)) + } + + const data = _ + .chain([ + [gray('Cypress:'), pkg.version], + [gray('Browser:'), formatBrowser(browser)], + [gray('Node Version:'), formatNodeVersion(config, getWidth(table, 1))], + [gray('Specs:'), formatSpecs(specs)], + [gray('Searched:'), formatSpecPattern(config.projectRoot, specPattern)], + [gray('Params:'), formatRecordParams(runUrl, parallel, group, tag)], + [gray('Run URL:'), runUrl ? formatPath(runUrl, getWidth(table, 1)) : ''], + [gray('Experiments:'), hasExperiments ? experiments.formatExperiments(enabledExperiments) : ''], + ]) + .filter(_.property(1)) + .value() + + table.push(...data) + + const heading = table.toString() + + console.log(heading) + + console.log('') + + return heading +} + +const displaySpecHeader = function (name, curr, total, estimated) { + console.log('') + + const PADDING = 2 + + const table = terminal.table({ + colWidths: [10, 70, 20], + colAligns: ['left', 'left', 'right'], + type: 'pageDivider', + style: { + 'padding-left': PADDING, + 'padding-right': 0, + }, + }) + + table.push(['', '']) + table.push([ + 'Running:', + `${formatPath(name, getWidth(table, 1), 'gray')}`, + gray(`(${curr} of ${total})`), + ]) + + console.log(table.toString()) + + if (estimated) { + const estimatedLabel = `${' '.repeat(PADDING)}Estimated:` + + return console.log(estimatedLabel, gray(humanTime.long(estimated))) + } +} + +const collectTestResults = (obj: { video?: boolean, screenshots?: Screenshot[] }, estimated) => { + return { + name: _.get(obj, 'spec.name'), + baseName: _.get(obj, 'spec.baseName'), + tests: _.get(obj, 'stats.tests'), + passes: _.get(obj, 'stats.passes'), + pending: _.get(obj, 'stats.pending'), + failures: _.get(obj, 'stats.failures'), + skipped: _.get(obj, 'stats.skipped'), + duration: humanTime.long(_.get(obj, 'stats.wallClockDuration')), + estimated: estimated && humanTime.long(estimated), + screenshots: obj.screenshots && obj.screenshots.length, + video: Boolean(obj.video), + } +} + +const renderSummaryTable = (runUrl) => { + return function (results) { + const { runs } = results + + console.log('') + + terminal.divider('=') + + console.log('') + + terminal.header('Run Finished', { + color: ['reset'], + }) + + if (runs && runs.length) { + const colAligns = ['left', 'left', 'right', 'right', 'right', 'right', 'right', 'right'] + const colWidths = [3, 41, 11, 9, 9, 9, 9, 9] + + const table1 = terminal.table({ + colAligns, + colWidths, + type: 'noBorder', + head: [ + '', + gray('Spec'), + '', + gray('Tests'), + gray('Passing'), + gray('Failing'), + gray('Pending'), + gray('Skipped'), + ], + }) + + const table2 = terminal.table({ + colAligns, + colWidths, + type: 'border', + }) + + const table3 = terminal.table({ + colAligns, + colWidths, + type: 'noBorder', + head: formatFooterSummary(results), + }) + + _.each(runs, (run) => { + const { spec, stats } = run + + const ms = duration.format(stats.wallClockDuration || 0) + + const formattedSpec = formatPath(spec.baseName, getWidth(table2, 1)) + + if (run.skippedSpec) { + return table2.push([ + '-', + formattedSpec, color('SKIPPED', 'gray'), + '-', '-', '-', '-', '-', + ]) + } + + return table2.push([ + formatSymbolSummary(stats.failures), + formattedSpec, + color(ms, 'gray'), + colorIf(stats.tests, 'reset'), + colorIf(stats.passes, 'green'), + colorIf(stats.failures, 'red'), + colorIf(stats.pending, 'cyan'), + colorIf(stats.skipped, 'blue'), + ]) + }) + + console.log('') + console.log('') + console.log(terminal.renderTables(table1, table2, table3)) + console.log('') + + if (runUrl) { + console.log('') + + const table4 = terminal.table({ + colWidths: [100], + type: 'pageDivider', + style: { + 'padding-left': 2, + }, + }) + + table4.push(['', '']) + console.log(terminal.renderTables(table4)) + + console.log(` Recorded Run: ${formatPath(runUrl, undefined, 'gray')}`) + console.log('') + } + } + } +} + +const iterateThroughSpecs = function (options: { specs: SpecFile[], runEachSpec: RunEachSpec, beforeSpecRun?: BeforeSpecRun, afterSpecRun?: AfterSpecRun, config: Cfg }) { + const { specs, runEachSpec, beforeSpecRun, afterSpecRun, config } = options + + const serial = () => { + return Bluebird.mapSeries(specs, runEachSpec) + } + + const ranSpecs: SpecFile[] = [] + + async function parallelAndSerialWithRecord (runs) { + const { spec, claimedInstances, totalInstances, estimated } = await beforeSpecRun() + + // no more specs to run? then we're done! + if (!spec) return runs + + // find the actual spec object amongst + // our specs array since the API sends us + // the relative name + const specObject = _.find(specs, { relative: spec }) + + if (!specObject) throw new Error(`Unable to find specObject for spec '${spec}'`) + + ranSpecs.push(specObject) + + const results = await runEachSpec( + specObject, + claimedInstances - 1, + totalInstances, + estimated, + ) + + runs.push(results) + + await afterSpecRun(specObject, results, config) + + // recurse + return parallelAndSerialWithRecord(runs) + } + + if (beforeSpecRun) { + // if we are running in parallel + // then ask the server for the next spec + return parallelAndSerialWithRecord([]) + } + + // else iterate in serial + return serial() +} + +async function getProjectId (project, id) { + if (id == null) { + id = env.get('CYPRESS_PROJECT_ID') + } + + // if we have an ID just use it + if (id) return id + + try { + return project.getProjectId() + } catch (err) { + // no id no problem + return null + } +} + +const getDefaultBrowserOptsByFamily = (browser, project, writeVideoFrame, onError) => { + la(browserUtils.isBrowserFamily(browser.family), 'invalid browser family in', browser) + + if (browser.name === 'electron') { + return getElectronProps(browser.isHeaded, writeVideoFrame, onError) + } + + if (browser.family === 'chromium') { + return getChromeProps(writeVideoFrame) + } + + if (browser.family === 'firefox') { + return getFirefoxProps(project, writeVideoFrame) + } + + return {} +} + +const getFirefoxProps = (project, writeVideoFrame) => { + if (writeVideoFrame) { + project.on('capture:video:frames', writeVideoFrame) + + return { onScreencastFrame: true } + } + + return {} +} + +const getCdpVideoPropSetter = (writeVideoFrame) => { + if (!writeVideoFrame) { + return _.noop + } + + return (props) => { + props.onScreencastFrame = (e) => { + // https://chromedevtools.github.io/devtools-protocol/tot/Page#event-screencastFrame + writeVideoFrame(Buffer.from(e.data, 'base64')) + } + } +} + +const getChromeProps = (writeVideoFrame) => { + const shouldWriteVideo = Boolean(writeVideoFrame) + + debug('setting Chrome properties %o', { shouldWriteVideo }) + + return _ + .chain({}) + .tap(getCdpVideoPropSetter(writeVideoFrame)) + .value() +} + +const getElectronProps = (isHeaded, writeVideoFrame, onError) => { + return _ + .chain({ + width: 1280, + height: 720, + show: isHeaded, + onCrashed () { + const err = errors.get('RENDERER_CRASHED') + + errors.log(err) + + onError(err) + }, + onNewWindow (e, url, frameName, disposition, options) { + // force new windows to automatically open with show: false + // this prevents window.open inside of javascript client code + // to cause a new BrowserWindow instance to open + // https://github.com/cypress-io/cypress/issues/123 + options.show = false + }, + }) + .tap(getCdpVideoPropSetter(writeVideoFrame)) + .value() +} + +const sumByProp = (runs, prop) => { + return _.sumBy(runs, prop) || 0 +} + +const getRun = (run, prop) => { + return _.get(run, prop) +} + +async function writeOutput (outputPath, results) { + if (!outputPath) { + return + } + + debug('saving output results %o', { outputPath }) + + return fs.outputJson(outputPath, results) +} + +const onWarning = (err) => { + console.log(chalk.yellow(err.message)) +} + +const openProjectCreate = (projectRoot, socketId, args) => { + // now open the project to boot the server + // putting our web client app in headless mode + // - NO display server logs (via morgan) + // - YES display reporter results (via mocha reporter) + const options = { + socketId, + morgan: false, + report: true, + isTextTerminal: args.isTextTerminal, + // pass the list of browsers we have detected when opening a project + // to give user's plugins file a chance to change it + browsers: args.browsers, + onWarning, + spec: args.spec, + onError: args.onError, + } + + return openProject.create(projectRoot, args, options) +} + +async function checkAccess (folderPath) { + return fs.access(folderPath, fs.constants.W_OK).catch((err) => { + if (['EACCES', 'EPERM'].includes(err.code)) { + // we cannot write due to folder permissions + return errors.warning('FOLDER_NOT_WRITABLE', folderPath) + } + + throw err + }) +} + +const createAndOpenProject = async (options) => { + const { projectRoot, projectId, socketId } = options + + await checkAccess(projectRoot) + + const open_project = await openProjectCreate(projectRoot, socketId, options) + const project = open_project.getProject() + + if (!project) throw new Error('Missing project after openProjectCreate!') + + const [config, _projectId] = await Promise.all([ + project.getConfig(), + getProjectId(project, projectId), + ]) + + return { + project, + config, + projectId: _projectId, + // Lazy require'd here, so as to not execute until we're in the electron process + configFile: require('@packages/data-context').getCtx().lifecycleManager.configFile, + } +} + +const removeOldProfiles = (browser) => { + return browserUtils.removeOldProfiles(browser) + .catch((err) => { + // dont make removing old browsers profiles break the build + return errors.warning('CANNOT_REMOVE_OLD_BROWSER_PROFILES', err) + }) +} + +async function trashAssets (config: Cfg) { + if (config.trashAssetsBeforeRuns !== true) { + return + } + + try { + await Promise.all([ + trash.folder(config.videosFolder), + trash.folder(config.screenshotsFolder), + trash.folder(config.downloadsFolder), + ]) + } catch (err) { + // dont make trashing assets fail the build + errors.warning('CANNOT_TRASH_ASSETS', err) + } +} + +async function createVideoRecording (videoName, options = {}) { + const outputDir = path.dirname(videoName) + + const onError = _.once((err) => { + // catch video recording failures and log them out + // but don't let this affect the run at all + return errors.warning('VIDEO_RECORDING_FAILED', err) + }) + + try { + await fs.ensureDir(outputDir) + } catch (err) { + onError(err) + } + + return videoCapture.start(videoName, _.extend({}, options, { onError })) +} + +const getVideoRecordingDelay = function (startedVideoCapture) { + if (startedVideoCapture) { + return DELAY_TO_LET_VIDEO_FINISH_MS + } + + return 0 +} + +async function maybeStartVideoRecording (options: { spec: SpecWithRelativeRoot, browser: Browser, video: boolean, videosFolder: string }) { + const { spec, browser, video, videosFolder } = options + + debug(`video recording has been ${video ? 'enabled' : 'disabled'}. video: %s`, video) + // bail if we've been told not to capture + // a video recording + if (!video) { + return + } + + // make sure we have a videosFolder + if (!videosFolder) { + throw new Error('Missing videoFolder for recording') + } + + const videoPath = (suffix) => { + return path.join(videosFolder, spec.relativeToCommonRoot + suffix) + } + + const videoName = videoPath('.mp4') + const compressedVideoName = videoPath('-compressed.mp4') + const props = await createVideoRecording(videoName, { webmInput: browser.family === 'firefox' }) + + return { + videoName, + compressedVideoName, + endVideoCapture: props.endVideoCapture, + writeVideoFrame: props.writeVideoFrame, + startedVideoCapture: props.startedVideoCapture, + } +} + +const warnVideoRecordingFailed = (err) => { + // log that post processing was attempted + // but failed and dont let this change the run exit code + errors.warning('VIDEO_POST_PROCESSING_FAILED', err) +} + +function navigateToNextSpec (spec) { + debug('navigating to next spec %s', spec) + + return openProject.changeUrlToSpec(spec) +} + +function displayResults (obj = {}, estimated) { + const results = collectTestResults(obj, estimated) + + const c = results.failures ? 'red' : 'green' + + console.log('') + + terminal.header('Results', { + color: [c], + }) + + const table = terminal.table({ + colWidths: [14, 86], + type: 'outsideBorder', + }) + + const data = _.chain([ + ['Tests:', results.tests], + ['Passing:', results.passes], + ['Failing:', results.failures], + ['Pending:', results.pending], + ['Skipped:', results.skipped], + ['Screenshots:', results.screenshots], + ['Video:', results.video], + ['Duration:', results.duration], + estimated ? ['Estimated:', results.estimated] : undefined, + ['Spec Ran:', formatPath(results.baseName, getWidth(table, 1), c)], + ]) + .compact() + .map((arr) => { + const [key, val] = arr + + return [color(key, 'gray'), color(val, c)] + }) + .value() + + table.push(...data) + + console.log('') + console.log(table.toString()) + console.log('') +} + +function displayScreenshots (screenshots: Screenshot[] = []) { + console.log('') + + terminal.header('Screenshots', { color: ['yellow'] }) + + console.log('') + + const table = terminal.table({ + colWidths: [3, 82, 15], + colAligns: ['left', 'left', 'right'], + type: 'noBorder', + style: { + 'padding-right': 0, + }, + chars: { + 'left': ' ', + 'right': '', + }, + }) + + screenshots.forEach((screenshot) => { + const dimensions = gray(`(${screenshot.width}x${screenshot.height})`) + + table.push([ + '-', + formatPath(`${screenshot.path}`, getWidth(table, 1)), + gray(dimensions), + ]) + }) + + console.log(table.toString()) + + console.log('') +} + +async function postProcessRecording (name, cname, videoCompression, shouldUploadVideo, quiet, ffmpegChaptersConfig) { + debug('ending the video recording %o', { name, videoCompression, shouldUploadVideo }) + + // once this ended promises resolves + // then begin processing the file + // dont process anything if videoCompress is off + // or we've been told not to upload the video + if (videoCompression === false || shouldUploadVideo === false) { + return + } + + function continueProcessing (onProgress?: (progress: number) => void) { + return videoCapture.process(name, cname, videoCompression, ffmpegChaptersConfig, onProgress) + } + + if (quiet) { + return continueProcessing() + } + + console.log('') + + terminal.header('Video', { + color: ['cyan'], + }) + + console.log('') + + const table = terminal.table({ + colWidths: [3, 21, 76], + colAligns: ['left', 'left', 'left'], + type: 'noBorder', + style: { + 'padding-right': 0, + }, + chars: { + 'left': ' ', + 'right': '', + }, + }) + + table.push([ + gray('-'), + gray('Started processing:'), + chalk.cyan(`Compressing to ${videoCompression} CRF`), + ]) + + console.log(table.toString()) + + const started = Date.now() + let progress = Date.now() + const throttle = env.get('VIDEO_COMPRESSION_THROTTLE') || human('10 seconds') + + const onProgress = function (float) { + if (float === 1) { + const finished = Date.now() - started + const dur = `(${humanTime.long(finished)})` + + const table = terminal.table({ + colWidths: [3, 21, 61, 15], + colAligns: ['left', 'left', 'left', 'right'], + type: 'noBorder', + style: { + 'padding-right': 0, + }, + chars: { + 'left': ' ', + 'right': '', + }, + }) + + table.push([ + gray('-'), + gray('Finished processing:'), + `${formatPath(name, getWidth(table, 2), 'cyan')}`, + gray(dur), + ]) + + console.log(table.toString()) + + console.log('') + } + + if (Date.now() - progress > throttle) { + // bump up the progress so we dont + // continuously get notifications + progress += throttle + const percentage = `${Math.ceil(float * 100)}%` + + console.log(' Compression progress: ', chalk.cyan(percentage)) + } + } + + return continueProcessing(onProgress) +} + +function launchBrowser (options: { browser: Browser, spec: SpecWithRelativeRoot, writeVideoFrame?: videoCapture.WriteVideoFrame, setScreenshotMetadata: SetScreenshotMetadata, project: Project, screenshots: ScreenshotMetadata[], projectRoot: string, shouldLaunchNewTab: boolean, onError: (err: Error) => void }) { + const { browser, spec, writeVideoFrame, setScreenshotMetadata, project, screenshots, projectRoot, shouldLaunchNewTab, onError } = options + + const warnings = {} + + const browserOpts: LaunchOpts = { + ...getDefaultBrowserOptsByFamily(browser, project, writeVideoFrame, onError), + projectRoot, + shouldLaunchNewTab, + automationMiddleware: { + onBeforeRequest (message, data) { + if (message === 'take:screenshot') { + return setScreenshotMetadata(data) + } + }, + onAfterResponse: (message, data, resp) => { + if (message === 'take:screenshot' && resp) { + const existingScreenshot = _.findIndex(screenshots, { path: resp.path }) + + if (existingScreenshot !== -1) { + // NOTE: saving screenshots to the same path will overwrite the previous one + // so we shouldn't report more screenshots than exist on disk. + // this happens when cy.screenshot is used in a retried test + screenshots.splice(existingScreenshot, 1, screenshotMetadata(data, resp)) + } else { + screenshots.push(screenshotMetadata(data, resp)) + } + } + + return resp + }, + }, + onWarning: (err) => { + const { message } = err + + // if this warning has already been + // seen for this browser launch then + // suppress it + if (warnings[message]) return + + warnings[message] = err + }, + } + + return openProject.launch(browser, spec, browserOpts) +} + +function listenForProjectEnd (project, exit): Bluebird { + if (globalThis.CY_TEST_MOCK?.listenForProjectEnd) return Bluebird.resolve(globalThis.CY_TEST_MOCK.listenForProjectEnd) + + return new Bluebird((resolve, reject) => { + if (exit === false) { + resolve = () => { + console.log('not exiting due to options.exit being false') + } + } + + const onEarlyExit = function (err) { + if (err.isFatalApiErr) { + return reject(err) + } + + console.log('') + errors.log(err) + + const obj = { + error: errors.stripAnsi(err.message), + stats: { + failures: 1, + tests: 0, + passes: 0, + pending: 0, + suites: 0, + skipped: 0, + wallClockDuration: 0, + wallClockStartedAt: new Date().toJSON(), + wallClockEndedAt: new Date().toJSON(), + }, + } + + return resolve(obj) + } + + project.once('end', (results) => resolve(results)) + + // if we already received a reason to exit early, go ahead and do it + if (earlyExitErr) { + return onEarlyExit(earlyExitErr) + } + + // otherwise override exitEarly so we exit as soon as there is a reason + exitEarly = (err) => { + onEarlyExit(err) + } + }) +} + +/** + * In CT mode, browser do not relaunch. + * In browser laucnh is where we wire the new video + * recording callback. + * This has the effect of always hitting the first specs + * video callback. + * + * This allows us, if we need to, to call a different callback + * in the same browser + */ +function writeVideoFrameCallback (data: Buffer) { + return currentWriteVideoFrameCallback(data) +} + +function waitForBrowserToConnect (options: { project: Project, socketId: string, onError: (err: Error) => void, writeVideoFrame?: videoCapture.WriteVideoFrame, spec: SpecWithRelativeRoot, isFirstSpec: boolean, testingType: string, experimentalSingleTabRunMode: boolean, browser: Browser, screenshots: ScreenshotMetadata[], projectRoot: string, shouldLaunchNewTab: boolean, webSecurity: boolean }) { + if (globalThis.CY_TEST_MOCK?.waitForBrowserToConnect) return Promise.resolve() + + const { project, socketId, onError, writeVideoFrame, spec } = options + const browserTimeout = Number(process.env.CYPRESS_INTERNAL_BROWSER_CONNECT_TIMEOUT || 60000) + let attempts = 0 + + // short circuit current browser callback so that we + // can rewire it without relaunching the browser + if (writeVideoFrame) { + currentWriteVideoFrameCallback = writeVideoFrame + options.writeVideoFrame = writeVideoFrameCallback + } + + // without this the run mode is only setting new spec + // path for next spec in launch browser. + // we need it to run on every spec even in single browser mode + currentSetScreenshotMetadata = (data) => { + data.specName = spec.relativeToCommonRoot + + return data + } + + // TODO: remove the need to extend options and avoid the type error + // @ts-expect-error + options.setScreenshotMetadata = (data) => { + return currentSetScreenshotMetadata(data) + } + + if (options.experimentalSingleTabRunMode && options.testingType === 'component' && !options.isFirstSpec) { + // reset browser state to match default behavior when opening/closing a new tab + return openProject.resetBrowserState().then(() => { + // If we do not launch the browser, + // we tell it that we are ready + // to receive the next spec + return navigateToNextSpec(options.spec) + }) + } + + const wait = () => { + debug('waiting for socket to connect and browser to launch...') + + return Bluebird.join( + waitForSocketConnection(project, socketId), + // TODO: remove the need to extend options and coerce this type + launchBrowser(options as typeof options & { setScreenshotMetadata: SetScreenshotMetadata }), + ) + .timeout(browserTimeout) + .catch(Bluebird.TimeoutError, async (err) => { + attempts += 1 + + console.log('') + + // always first close the open browsers + // before retrying or dieing + await openProject.closeBrowser() + + if (attempts === 1 || attempts === 2) { + // try again up to 3 attempts + const word = attempts === 1 ? 'Retrying...' : 'Retrying again...' + + errors.warning('TESTS_DID_NOT_START_RETRYING', word) + + return await wait() + } + + err = errors.get('TESTS_DID_NOT_START_FAILED') + errors.log(err) + + onError(err) + }) + } + + return wait() +} + +function waitForSocketConnection (project, id) { + if (globalThis.CY_TEST_MOCK?.waitForSocketConnection) return + + debug('waiting for socket connection... %o', { id }) + + return new Promise((resolve, reject) => { + const fn = function (socketId) { + debug('got socket connection %o', { id: socketId }) + + if (socketId === id) { + // remove the event listener if we've connected + project.removeListener('socket:connected', fn) + + debug('socket connected', { socketId }) + + // resolve the promise + return resolve() + } + } + + // when a socket connects verify this + // is the one that matches our id! + return project.on('socket:connected', fn) + }) +} + +function waitForTestsToFinishRunning (options: { project: Project, screenshots: Screenshot[], startedVideoCapture?: any, endVideoCapture?: () => Promise, videoName?: string, compressedVideoName?: string, videoCompression: number | false, videoUploadOnPasses: boolean, exit: boolean, spec: SpecWithRelativeRoot, estimated: number, quiet: boolean, config: Cfg, shouldKeepTabOpen: boolean, testingType: TestingType}) { + if (globalThis.CY_TEST_MOCK?.waitForTestsToFinishRunning) return Promise.resolve(globalThis.CY_TEST_MOCK.waitForTestsToFinishRunning) + + const { project, screenshots, startedVideoCapture, endVideoCapture, videoName, compressedVideoName, videoCompression, videoUploadOnPasses, exit, spec, estimated, quiet, config, shouldKeepTabOpen, testingType } = options + + // https://github.com/cypress-io/cypress/issues/2370 + // delay 1 second if we're recording a video to give + // the browser padding to render the final frames + // to avoid chopping off the end of the video + const delay = getVideoRecordingDelay(startedVideoCapture) + + return listenForProjectEnd(project, exit) + .delay(delay) + .then(async (results) => { + _.defaults(results, { + error: null, + hooks: null, + tests: null, + video: null, + screenshots: null, + reporterStats: null, + }) + + // dashboard told us to skip this spec + const skippedSpec = results.skippedSpec + + if (startedVideoCapture) { + results.video = videoName + } + + if (screenshots) { + results.screenshots = screenshots + } + + results.spec = spec + + const { tests, stats } = results + const attempts = _.flatMap(tests, (test) => test.attempts) + + // if we have a video recording + if (startedVideoCapture && tests && tests.length) { + // always set the video timestamp on tests + Reporter.setVideoTimestamp(startedVideoCapture, attempts) + } + + let videoCaptureFailed = false + + if (endVideoCapture) { + try { + await endVideoCapture() + } catch (err) { + videoCaptureFailed = true + warnVideoRecordingFailed(err) + } + } + + await runEvents.execute('after:spec', config, spec, results) + + const videoExists = videoName ? await fs.pathExists(videoName) : false + + if (startedVideoCapture && !videoExists) { + // the video file no longer exists at the path where we expect it, + // likely because the user deleted it in the after:spec event + debug(`No video found after spec ran - skipping processing. Video path: ${videoName}`) + + results.video = null + } + + const hasFailingTests = _.get(stats, 'failures') > 0 + // we should upload the video if we upload on passes (by default) + // or if we have any failures and have started the video + const shouldUploadVideo = !skippedSpec && videoUploadOnPasses === true || Boolean((startedVideoCapture && hasFailingTests)) + + results.shouldUploadVideo = shouldUploadVideo + + if (!quiet && !skippedSpec) { + displayResults(results, estimated) + if (screenshots && screenshots.length) { + displayScreenshots(screenshots) + } + } + + const project = openProject.getProject() + + if (!project) throw new Error('Missing project!') + + // @ts-expect-error experimentalSingleTabRunMode only exists on the CT-specific config type + const usingExperimentalSingleTabMode = testingType === 'component' && config.experimentalSingleTabRunMode + + if (usingExperimentalSingleTabMode) { + await project.server.destroyAut() + } + + // we do not support experimentalSingleTabRunMode for e2e + if (!usingExperimentalSingleTabMode) { + debug('attempting to close the browser tab') + + await openProject.resetBrowserTabsForNextTest(shouldKeepTabOpen) + + debug('resetting server state') + + project.server.reset() + } + + if (videoExists && !skippedSpec && endVideoCapture && !videoCaptureFailed) { + const ffmpegChaptersConfig = videoCapture.generateFfmpegChaptersConfig(results.tests) + + await postProcessRecording( + videoName, + compressedVideoName, + videoCompression, + shouldUploadVideo, + quiet, + ffmpegChaptersConfig, + ) + .catch(warnVideoRecordingFailed) + } + + return results + }) +} + +function screenshotMetadata (data, resp) { + return { + screenshotId: random.id(), + name: data.name || null, + testId: data.testId, + testAttemptIndex: data.testAttemptIndex, + takenAt: resp.takenAt, + path: resp.path, + height: resp.dimensions.height, + width: resp.dimensions.width, + } +} + +async function runSpecs (options: { config: Cfg, browser: Browser, sys: any, headed: boolean, outputPath: string, specs: SpecWithRelativeRoot[], specPattern: string | RegExp | string[], beforeSpecRun?: BeforeSpecRun, afterSpecRun?: AfterSpecRun, runUrl?: string, parallel?: boolean, group?: string, tag?: string, testingType: TestingType, quiet: boolean, project: Project, onError: (err: Error) => void, exit: boolean, socketId: string, webSecurity: boolean, projectRoot: string } & Pick) { + if (globalThis.CY_TEST_MOCK?.runSpecs) return globalThis.CY_TEST_MOCK.runSpecs + + const { config, browser, sys, headed, outputPath, specs, specPattern, beforeSpecRun, afterSpecRun, runUrl, parallel, group, tag, testingType } = options + + const isHeadless = !headed + + browser.isHeadless = isHeadless + browser.isHeaded = !isHeadless + + if (!options.quiet) { + displayRunStarting({ + config, + specs, + group, + tag, + runUrl, + browser, + parallel, + specPattern, + }) + } + + let isFirstSpec = true + + async function runEachSpec (spec: SpecWithRelativeRoot, index: number, length: number, estimated: number) { + if (!options.quiet) { + displaySpecHeader(spec.baseName, index + 1, length, estimated) + } + + const { results } = await runSpec(config, spec, options, estimated, isFirstSpec, index === length - 1) + + isFirstSpec = false + + debug('spec results %o', results) + + return results + } + + const beforeRunDetails = { + browser, + config, + cypressVersion: pkg.version, + group, + parallel, + runUrl, + specs, + specPattern, + system: _.pick(sys, 'osName', 'osVersion'), + tag, + } + + await runEvents.execute('before:run', config, beforeRunDetails) + + const runs = await iterateThroughSpecs({ + specs, + config, + runEachSpec, + afterSpecRun, + beforeSpecRun, + }) + + const results: CypressCommandLine.CypressRunResult = { + status: 'finished', + startedTestsAt: getRun(_.first(runs), 'stats.wallClockStartedAt'), + endedTestsAt: getRun(_.last(runs), 'stats.wallClockEndedAt'), + totalDuration: sumByProp(runs, 'stats.wallClockDuration'), + totalSuites: sumByProp(runs, 'stats.suites'), + totalTests: sumByProp(runs, 'stats.tests'), + totalPassed: sumByProp(runs, 'stats.passes'), + totalPending: sumByProp(runs, 'stats.pending'), + totalFailed: sumByProp(runs, 'stats.failures'), + totalSkipped: sumByProp(runs, 'stats.skipped'), + runs, + browserPath: browser.path, + browserName: browser.name, + browserVersion: browser.version, + osName: sys.osName, + osVersion: sys.osVersion, + cypressVersion: pkg.version, + runUrl, + // @ts-expect-error slight type mismatch in public types vs internal types + config, + } + + debug('final results of all runs: %o', results) + + const { each, remapKeys, remove, renameKey, setValue } = objUtils + + // Remap results for module API/after:run to remove private props and + // rename props to make more user-friendly + const moduleAPIResults = remapKeys(results, { + runs: each((run) => ({ + tests: each((test) => ({ + attempts: each((attempt, i) => ({ + timings: remove, + failedFromHookId: remove, + wallClockDuration: renameKey('duration'), + wallClockStartedAt: renameKey('startedAt'), + wallClockEndedAt: renameKey('endedAt'), + screenshots: setValue( + _(run.screenshots) + .filter({ testId: test.testId, testAttemptIndex: i }) + .map((screenshot) => _.omit(screenshot, + ['screenshotId', 'testId', 'testAttemptIndex'])) + .value(), + ), + })), + testId: remove, + })), + hooks: each({ + hookId: remove, + }), + stats: { + wallClockDuration: renameKey('duration'), + wallClockStartedAt: renameKey('startedAt'), + wallClockEndedAt: renameKey('endedAt'), + }, + screenshots: remove, + })), + }) + + if (testingType === 'component') { + await openProject.closeBrowser() + } + + await runEvents.execute('after:run', config, moduleAPIResults) + await writeOutput(outputPath, moduleAPIResults) + + return results +} + +async function runSpec (config, spec: SpecWithRelativeRoot, options: { project: Project, browser: Browser, onError: (err: Error) => void, config: Cfg, quiet: boolean, exit: boolean, testingType: TestingType, socketId: string, webSecurity: boolean, projectRoot: string } & Pick, estimated, isFirstSpec, isLastSpec) { + const { project, browser, onError } = options + + const { isHeadless } = browser + + debug('about to run spec %o', { + spec, + isHeadless, + browser, + }) + + if (browser.family !== 'chromium' && !options.config.chromeWebSecurity) { + console.log('') + errors.warning('CHROME_WEB_SECURITY_NOT_SUPPORTED', browser.family) + } + + const screenshots = [] + + await runEvents.execute('before:spec', config, spec) + + const videoRecordProps = await maybeStartVideoRecording({ + spec, + browser, + video: options.video, + videosFolder: options.videosFolder, + }) + + // we know we're done running headlessly + // when the renderer has connected and + // finishes running all of the tests. + + const [results] = await Promise.all([ + waitForTestsToFinishRunning({ + spec, + config, + project, + estimated, + screenshots, + videoName: videoRecordProps?.videoName, + compressedVideoName: videoRecordProps?.compressedVideoName, + endVideoCapture: videoRecordProps?.endVideoCapture, + startedVideoCapture: videoRecordProps?.startedVideoCapture, + exit: options.exit, + testingType: options.testingType, + videoCompression: options.videoCompression, + videoUploadOnPasses: options.videoUploadOnPasses, + quiet: options.quiet, + shouldKeepTabOpen: !isLastSpec, + }), + + waitForBrowserToConnect({ + spec, + project, + browser, + screenshots, + onError, + writeVideoFrame: videoRecordProps?.writeVideoFrame, + socketId: options.socketId, + webSecurity: options.webSecurity, + projectRoot: options.projectRoot, + testingType: options.testingType, + isFirstSpec, + experimentalSingleTabRunMode: config.experimentalSingleTabRunMode, + shouldLaunchNewTab: !isFirstSpec, + }), + ]) + + return { results } +} + +async function ready (options: { projectRoot: string, record: boolean, key: string, ciBuildId: string, parallel: boolean, group: string, browser: string, tag: string, testingType: TestingType, socketId: string, spec: string | RegExp | string[], headed: boolean, outputPath: string, exit: boolean, quiet: boolean, onError?: (err: Error) => void, browsers?: Browser[], webSecurity: boolean }) { + debug('run mode ready with options %o', options) + + if (process.env.ELECTRON_RUN_AS_NODE && !process.env.DISPLAY) { + debug('running electron as a node process without xvfb') + } + + _.defaults(options, { + isTextTerminal: true, + browser: 'electron', + quiet: false, + }) + + const { projectRoot, record, key, ciBuildId, parallel, group, browser: browserName, tag, testingType, socketId } = options + + assert(socketId) + + // this needs to be a closure over `exitEarly` and not a reference + // because `exitEarly` gets overwritten in `listenForProjectEnd` + // TODO: refactor this so we don't need to extend options + const onError = options.onError = (err) => exitEarly(err) + + // alias and coerce to null + let specPatternFromCli = options.spec || null + + // ensure the project exists + // and open up the project + const browsers = await browserUtils.getAllBrowsersWith() + + debug('found all system browsers %o', browsers) + // TODO: refactor this so we don't need to extend options + options.browsers = browsers + + const { project, projectId, config, configFile } = await createAndOpenProject(options) + + debug('project created and opened with config %o', config) + + // if we have a project id and a key but record hasnt been given + recordMode.warnIfProjectIdButNoRecordOption(projectId, options) + recordMode.throwIfRecordParamsWithoutRecording(record, ciBuildId, parallel, group, tag) + + if (record) { + recordMode.throwIfNoProjectId(projectId, configFile) + recordMode.throwIfIncorrectCiBuildIdUsage(ciBuildId, parallel, group) + recordMode.throwIfIndeterminateCiBuildId(ciBuildId, parallel, group) + } + + // user code might have modified list of allowed browsers + // but be defensive about it + const userBrowsers = _.get(config, 'resolved.browsers.value', browsers) + + let specPattern = specPatternFromCli || config.specPattern + + specPattern = relativeSpecPattern(projectRoot, specPattern) + + const [sys, browser] = await Promise.all([ + system.info(), + (async () => { + const browsers = await browserUtils.ensureAndGetByNameOrPath(browserName, false, userBrowsers) + + await removeOldProfiles(browsers) + + return browsers + })(), + trashAssets(config), + ]) + + // @ts-expect-error ctx is protected + const specs = project.ctx.project.specs + + if (!specs.length) { + errors.throwErr('NO_SPECS_FOUND', projectRoot, String(specPattern)) + } + + if (browser.unsupportedVersion && browser.warning) { + errors.throwErr('UNSUPPORTED_BROWSER_VERSION', browser.warning) + } + + if (browser.family === 'chromium') { + chromePolicyCheck.run(onWarning) + } + + async function runAllSpecs ({ beforeSpecRun, afterSpecRun, runUrl, parallel }: { beforeSpecRun?: BeforeSpecRun, afterSpecRun?: AfterSpecRun, runUrl?: string, parallel?: boolean}) { + const results = await runSpecs({ + beforeSpecRun, + afterSpecRun, + projectRoot, + socketId, + parallel, + onError, + browser, + project, + runUrl, + group, + config, + specs, + sys, + tag, + specPattern, + videosFolder: config.videosFolder, + video: config.video, + videoCompression: config.videoCompression, + videoUploadOnPasses: config.videoUploadOnPasses, + headed: options.headed, + quiet: options.quiet, + outputPath: options.outputPath, + testingType: options.testingType, + exit: options.exit, + webSecurity: options.webSecurity, + }) + + if (!options.quiet) { + renderSummaryTable(runUrl)(results) + } + + return results + } + + if (record) { + const { projectName } = config + + return recordMode.createRunAndRecordSpecs({ + tag, + key, + sys, + specs, + group, + config, + browser, + parallel, + ciBuildId, + testingType, + project, + projectId, + projectRoot, + projectName, + specPattern, + runAllSpecs, + onError, + quiet: options.quiet, + }) + } + + // not recording, can't be parallel + return runAllSpecs({ + parallel: false, + }) +} + +export async function run (options, loading: Promise) { + if (require('../util/electron-app').isRunningAsElectronProcess({ debug })) { + const app = require('electron').app + + // electron >= 5.0.0 will exit the app if all browserwindows are closed, + // this is obviously undesirable in run mode + // https://github.com/cypress-io/cypress/pull/4720#issuecomment-514316695 + app.on('window-all-closed', () => { + debug('all BrowserWindows closed, not exiting') + }) + + await app.whenReady() + } + + await loading + try { + return ready(options) + } catch (e) { + return exitEarly(e) + } +} diff --git a/packages/server/lib/open_project.ts b/packages/server/lib/open_project.ts index 8c10e92b7c6b..6c5fce26d398 100644 --- a/packages/server/lib/open_project.ts +++ b/packages/server/lib/open_project.ts @@ -19,7 +19,7 @@ import { autoBindDebug } from '@packages/data-context/src/util' const debug = Debug('cypress:server:open_project') export class OpenProject { - projectBase: ProjectBase | null = null + private projectBase: ProjectBase | null = null relaunchBrowser: ((...args: unknown[]) => Bluebird) | null = null constructor () { diff --git a/packages/server/lib/project-base.ts b/packages/server/lib/project-base.ts index 1f11b533922e..94315d6f636b 100644 --- a/packages/server/lib/project-base.ts +++ b/packages/server/lib/project-base.ts @@ -20,7 +20,7 @@ import { SocketE2E } from './socket-e2e' import { ensureProp } from './util/class-helpers' import system from './util/system' -import type { BannersState, FoundBrowser, FoundSpec, OpenProjectLaunchOptions, ReceivedCypressOptions, TestingType } from '@packages/types' +import type { BannersState, FoundBrowser, FoundSpec, OpenProjectLaunchOptions, ReceivedCypressOptions, ResolvedConfigurationOptions, TestingType } from '@packages/types' import { DataContext, getCtx } from '@packages/data-context' import { createHmac } from 'crypto' @@ -39,6 +39,7 @@ export interface Cfg extends ReceivedCypressOptions { e2e: Partial component: Partial additionalIgnorePattern?: string | string[] + resolved: ResolvedConfigurationOptions } const localCwd = process.cwd() diff --git a/packages/server/lib/video_capture.ts b/packages/server/lib/video_capture.ts index c67f1af81c7d..9d25331978d4 100644 --- a/packages/server/lib/video_capture.ts +++ b/packages/server/lib/video_capture.ts @@ -8,6 +8,8 @@ import { path as ffmpegPath } from '@ffmpeg-installer/ffmpeg' import BlackHoleStream from 'black-hole-stream' import { fs } from './util/fs' +export type WriteVideoFrame = (data: Buffer) => void + const debug = Debug('cypress:server:video') const debugVerbose = Debug('cypress-verbose:server:video') // extra verbose logs for logging individual frames @@ -150,7 +152,7 @@ export function start (name, options: StartOptions = {}) { const lengths = {} - const writeVideoFrame = function (data) { + const writeVideoFrame: WriteVideoFrame = function (data) { // make sure we haven't ended // our stream yet because paint // events can linger beyond diff --git a/packages/server/test/integration/cypress_spec.js b/packages/server/test/integration/cypress_spec.js index 0efbbd0c6eb0..caa4fa28d6dd 100644 --- a/packages/server/test/integration/cypress_spec.js +++ b/packages/server/test/integration/cypress_spec.js @@ -1,3 +1,4 @@ +/*global globalThis*/ require('../spec_helper') const _ = require('lodash') const path = require('path') @@ -22,7 +23,6 @@ const ciProvider = require(`../../lib/util/ci_provider`) const settings = require(`../../lib/util/settings`) const Windows = require(`../../lib/gui/windows`) const interactiveMode = require(`../../lib/modes/interactive`) -const runMode = require(`../../lib/modes/run`) const api = require(`../../lib/api`) const cwd = require(`../../lib/cwd`) const user = require(`../../lib/user`) @@ -226,6 +226,7 @@ describe('lib/cypress', () => { } Fixtures.remove() + delete globalThis['CY_TEST_MOCK'] }) context('test browsers', () => { @@ -338,8 +339,11 @@ describe('lib/cypress', () => { await clearCtx() sinon.stub(electron.app, 'on').withArgs('ready').yieldsAsync() - sinon.stub(runMode, 'waitForSocketConnection').resolves() - sinon.stub(runMode, 'listenForProjectEnd').resolves({ stats: { failures: 0 } }) + globalThis.CY_TEST_MOCK = { + waitForSocketConnection: true, + listenForProjectEnd: { stats: { failures: 0 } }, + } + sinon.stub(browsers, 'open') sinon.stub(browsers, 'connectToNewSpec') sinon.stub(commitInfo, 'getRemoteOrigin').resolves('remoteOrigin') @@ -404,7 +408,7 @@ describe('lib/cypress', () => { }) it('runs project headlessly and exits with exit code 10', function () { - sinon.stub(runMode, 'runSpecs').resolves({ totalFailed: 10 }) + globalThis.CY_TEST_MOCK.runSpecs = { totalFailed: 10 } return cypress.start([`--run-project=${this.todosPath}`]) .then(() => { @@ -1029,7 +1033,7 @@ describe('lib/cypress', () => { describe('--port', () => { beforeEach(() => { - return runMode.listenForProjectEnd.resolves({ stats: { failures: 0 } }) + globalThis.CY_TEST_MOCK.listenForProjectEnd = { stats: { failures: 0 } } }) it('can change the default port to 5544', function () { @@ -1065,7 +1069,7 @@ describe('lib/cypress', () => { beforeEach(() => { process.env = _.omit(process.env, 'CYPRESS_DEBUG') - return runMode.listenForProjectEnd.resolves({ stats: { failures: 0 } }) + globalThis.CY_TEST_MOCK.listenForProjectEnd = { stats: { failures: 0 } } }) it('can set specific environment variables', function () { @@ -1159,43 +1163,28 @@ describe('lib/cypress', () => { sinon.stub(electron.app, 'on').withArgs('ready').yieldsAsync() sinon.stub(browsers, 'open') - sinon.stub(runMode, 'waitForSocketConnection').resolves() - - sinon.stub(runMode, 'waitForBrowserToConnect').resolves({ - stats: { - tests: 1, - passes: 2, - failures: 3, - pending: 4, - skipped: 5, - wallClockDuration: 6, - }, - tests: [], - hooks: [], - video: 'path/to/video', - shouldUploadVideo: true, - screenshots: [], - config: {}, - spec: {}, - }) - - sinon.stub(runMode, 'waitForTestsToFinishRunning').resolves({ - stats: { - tests: 1, - passes: 2, - failures: 3, - pending: 4, - skipped: 5, - wallClockDuration: 6, + + globalThis.CY_TEST_MOCK = { + waitForSocketConnection: true, + waitForBrowserToConnect: true, + waitForTestsToFinishRunning: { + stats: { + tests: 1, + passes: 2, + failures: 3, + pending: 4, + skipped: 5, + wallClockDuration: 6, + }, + tests: [], + hooks: [], + video: 'path/to/video', + shouldUploadVideo: true, + screenshots: [], + config: {}, + spec: {}, }, - tests: [], - hooks: [], - video: 'path/to/video', - shouldUploadVideo: true, - screenshots: [], - config: {}, - spec: {}, - }) + } return Promise.all([ // make sure we have no user object diff --git a/packages/server/test/unit/modes/run_spec.js b/packages/server/test/unit/modes/run_spec.js deleted file mode 100644 index 59a1ba022304..000000000000 --- a/packages/server/test/unit/modes/run_spec.js +++ /dev/null @@ -1,966 +0,0 @@ -require('../../spec_helper') - -const _ = require('lodash') -const Promise = require('bluebird') -const electron = require('electron') -const stripAnsi = require('strip-ansi') -const snapshot = require('snap-shot-it') -const pkg = require('@packages/root') -const { fs } = require(`../../../lib/util/fs`) -const user = require(`../../../lib/user`) -const errors = require(`../../../lib/errors`) -const ProjectBase = require(`../../../lib/project-base`).ProjectBase -const browsers = require(`../../../lib/browsers`) -const Reporter = require(`../../../lib/reporter`) -const runMode = require(`../../../lib/modes/run`) -const { openProject } = require(`../../../lib/open_project`) -const videoCapture = require(`../../../lib/video_capture`) -const env = require(`../../../lib/util/env`) -const random = require(`../../../lib/util/random`) -const system = require(`../../../lib/util/system`) -const { experimental } = require(`../../../lib/experiments`) - -// NOTE: Covered by e2e/integration tests -describe.skip('lib/modes/run', () => { - beforeEach(function () { - this.projectInstance = new ProjectBase({ projectRoot: '/_test-output/path/to/project-e2e', testingType: 'e2e' }) - }) - - context('.getProjectId', () => { - it('resolves if id', () => { - return runMode.getProjectId('project', 'id123') - .then((ret) => { - expect(ret).to.eq('id123') - }) - }) - - it('resolves if CYPRESS_PROJECT_ID set', () => { - sinon.stub(env, 'get').withArgs('CYPRESS_PROJECT_ID').returns('envId123') - - return runMode.getProjectId('project') - .then((ret) => { - expect(ret).to.eq('envId123') - }) - }) - - it('is null when no projectId', () => { - const project = { - getProjectId: sinon.stub().rejects(new Error), - } - - return runMode.getProjectId(project) - .then((ret) => { - expect(ret).to.be.null - }) - }) - }) - - context('.openProjectCreate', () => { - let onError - - beforeEach(() => { - sinon.stub(openProject, 'create').resolves() - - onError = sinon.spy() - const options = { - onError, - port: 8080, - env: { foo: 'bar' }, - isTextTerminal: true, - projectRoot: '/_test-output/path/to/project/foo', - } - - return runMode.openProjectCreate(options.projectRoot, 1234, options) - }) - - it('calls openProject.create with projectRoot + options', () => { - expect(openProject.create).to.be.calledWithMatch('/_test-output/path/to/project/foo', { - port: 8080, - projectRoot: '/_test-output/path/to/project/foo', - env: { foo: 'bar' }, - }, { - morgan: false, - socketId: 1234, - report: true, - isTextTerminal: true, - }) - }) - - it('calls options.onError with error message onError', () => { - const error = { message: 'the message' } - - expect(openProject.create.lastCall.args[2].onError).to.be.a('function') - openProject.create.lastCall.args[2].onError(error) - expect(onError).to.be.calledWith(error) - }) - }) - - context('.getElectronProps', () => { - it('sets width and height', () => { - const props = runMode.getElectronProps() - - expect(props.width).to.eq(1280) - - expect(props.height).to.eq(720) - }) - - it('sets show to boolean', () => { - let props = runMode.getElectronProps(false) - - expect(props.show).to.be.false - - props = runMode.getElectronProps(true) - - expect(props.show).to.be.true - }) - - it('sets onScreencastFrame when write is true', () => { - const write = sinon.stub() - - const image = { - data: '', - } - - const props = runMode.getElectronProps(true, write) - - props.onScreencastFrame(image) - - expect(write).to.be.calledOnce - }) - - it('does not set onScreencastFrame when write is falsy', () => { - const props = runMode.getElectronProps(true, false) - - expect(props).not.to.have.property('recordFrameRate') - expect(props).not.to.have.property('onScreencastFrame') - }) - - it('sets options.show = false onNewWindow callback', () => { - const options = { show: true } - - const props = runMode.getElectronProps() - - props.onNewWindow(null, null, null, null, options) - - expect(options.show).to.eq(false) - }) - - it('calls options.onError when webContents crashes', function () { - sinon.spy(errors, 'get') - sinon.spy(errors, 'log') - - const onError = sinon.spy() - const props = runMode.getElectronProps(true, this.projectInstance, onError) - - props.onCrashed() - - expect(errors.get).to.be.calledWith('RENDERER_CRASHED') - expect(errors.log).to.be.calledOnce - - expect(onError).to.be.called - expect(onError.lastCall.args[0].message).to.include('We detected that the Chromium Renderer process just crashed.') - }) - }) - - context('.launchBrowser', () => { - beforeEach(function () { - this.launch = sinon.stub(openProject, 'launch') - sinon.stub(runMode, 'screenshotMetadata').returns({ a: 'a' }) - }) - - it('can launch electron', function () { - const screenshots = [] - - const spec = { - absolute: '/path/to/spec', - } - - const browser = { - name: 'electron', - family: 'chromium', - isHeaded: false, - } - - runMode.launchBrowser({ - spec, - browser, - project: this.projectInstance, - writeVideoFrame: 'write', - screenshots, - }) - - expect(this.launch).to.be.calledWithMatch(browser, spec) - - const browserOpts = this.launch.firstCall.args[2] - - const { onAfterResponse } = browserOpts.automationMiddleware - - expect(onAfterResponse).to.be.a('function') - - onAfterResponse('take:screenshot', {}, {}) - onAfterResponse('get:cookies') - - expect(screenshots).to.deep.eq([{ a: 'a' }]) - }) - - it('can launch chrome', function () { - const spec = { - absolute: '/path/to/spec', - } - - const browser = { - name: 'chrome', - family: 'chromium', - isHeaded: true, - } - - runMode.launchBrowser({ - spec, - browser, - project: {}, - }) - - expect(this.launch).to.be.calledWithMatch(browser, spec, {}) - }) - }) - - context('.postProcessRecording', () => { - beforeEach(() => { - sinon.stub(videoCapture, 'process').resolves() - }) - - it('calls video process with name, cname and videoCompression', () => { - return runMode.postProcessRecording('foo', 'foo-compress', 32, true) - .then(() => { - expect(videoCapture.process).to.be.calledWith('foo', 'foo-compress', 32) - }) - }) - - it('does not call video process when videoCompression is false', () => { - return runMode.postProcessRecording('foo', 'foo-compress', false, true) - .then(() => { - expect(videoCapture.process).not.to.be.called - }) - }) - - it('calls video process if we have been told to upload videos', () => { - return runMode.postProcessRecording('foo', 'foo-compress', 32, true) - .then(() => { - expect(videoCapture.process).to.be.calledWith('foo', 'foo-compress', 32) - }) - }) - - it('does not call video process if there are no failing tests and we have set not to upload video on passing', () => { - return runMode.postProcessRecording('foo', 'foo-compress', 32, false) - .then(() => { - expect(videoCapture.process).not.to.be.called - }) - }) - }) - - context('.waitForBrowserToConnect', () => { - it('throws TESTS_DID_NOT_START_FAILED after 3 connection attempts', function () { - sinon.spy(errors, 'warning') - sinon.spy(errors, 'get') - sinon.spy(openProject, 'closeBrowser') - sinon.stub(runMode, 'launchBrowser').resolves() - sinon.stub(runMode, 'waitForSocketConnection').callsFake(() => { - return Promise.delay(1000) - }) - - const onError = sinon.spy() - - return runMode.waitForBrowserToConnect({ project: this.projectInstance, timeout: 10, onError }) - .then(() => { - expect(openProject.closeBrowser).to.be.calledThrice - expect(runMode.launchBrowser).to.be.calledThrice - expect(runMode.launchBrowser.firstCall.args[0]).not.property('writeVideoFrame') - expect(errors.warning).to.be.calledWith('TESTS_DID_NOT_START_RETRYING', 'Retrying...') - expect(errors.warning).to.be.calledWith('TESTS_DID_NOT_START_RETRYING', 'Retrying again...') - expect(errors.get).to.be.calledWith('TESTS_DID_NOT_START_FAILED') - - expect(onError).to.be.called - expect(onError.lastCall.args[0].message).to.include('The browser never connected. Something is wrong. The tests cannot run. Aborting...') - }) - }) - }) - - context('.waitForSocketConnection', () => { - beforeEach(function () { - this.projectStub = sinon.stub({ - on () {}, - removeListener () {}, - }) - }) - - it('attaches fn to \'socket:connected\' event', function () { - runMode.waitForSocketConnection(this.projectStub, 1234) - - expect(this.projectStub.on).to.be.calledWith('socket:connected') - }) - - it('calls removeListener if socketId matches id', function () { - this.projectStub.on.yields(1234) - - return runMode.waitForSocketConnection(this.projectStub, 1234) - .then(() => { - expect(this.projectStub.removeListener).to.be.calledWith('socket:connected') - }) - }) - - describe('integration', () => { - it('resolves undefined when socket:connected fires', function () { - process.nextTick(() => { - return this.projectInstance.emit('socket:connected', 1234) - }) - - return runMode.waitForSocketConnection(this.projectInstance, 1234) - .then((ret) => { - expect(ret).to.be.undefined - }) - }) - - it('does not resolve if socketId does not match id', function () { - process.nextTick(() => { - return this.projectInstance.emit('socket:connected', 12345) - }) - - return runMode - .waitForSocketConnection(this.projectInstance, 1234) - .timeout(50) - .then(() => { - throw new Error('should time out and not resolve') - }).catch(Promise.TimeoutError, (err) => {}) - }) - - it('actually removes the listener', function () { - process.nextTick(() => { - this.projectInstance.emit('socket:connected', 12345) - expect(this.projectInstance.listeners('socket:connected')).to.have.length(1) - this.projectInstance.emit('socket:connected', '1234') - expect(this.projectInstance.listeners('socket:connected')).to.have.length(1) - this.projectInstance.emit('socket:connected', 1234) - - expect(this.projectInstance.listeners('socket:connected')).to.have.length(0) - }) - - return runMode.waitForSocketConnection(this.projectInstance, 1234) - }) - }) - }) - - context('.waitForTestsToFinishRunning', () => { - beforeEach(function () { - sinon.stub(fs, 'pathExists').resolves(true) - sinon.stub(this.projectInstance, 'getConfig').resolves({}) - sinon.spy(runMode, 'getVideoRecordingDelay') - sinon.spy(errors, 'warning') - - this.setupProjectEnd = (results) => { - results = results || { - stats: { - failures: 0, - }, - } - - process.nextTick(() => { - this.projectInstance.emit('end', results) - }) - } - }) - - it('end event resolves with obj, displays stats, displays screenshots, sets video timestamps', function () { - const startedVideoCapture = new Date - const screenshots = [{}, {}, {}] - const endVideoCapture = sinon.stub().resolves() - const results = { - tests: [{ attempts: [1] }, { attempts: [2] }, { attempts: [3] }], - stats: { - tests: 1, - passes: 2, - failures: 3, - pending: 4, - duration: 5, - }, - } - - sinon.stub(Reporter, 'setVideoTimestamp') - sinon.stub(runMode, 'postProcessRecording').resolves() - sinon.spy(runMode, 'displayResults') - sinon.spy(runMode, 'displayScreenshots') - sinon.spy(Promise.prototype, 'delay') - - this.setupProjectEnd(results) - - return runMode.waitForTestsToFinishRunning({ - project: this.projectInstance, - videoName: 'foo.mp4', - compressedVideoName: 'foo-compressed.mp4', - videoCompression: 32, - videoUploadOnPasses: true, - gui: false, - screenshots, - startedVideoCapture, - endVideoCapture, - spec: { - path: 'cypress/e2e/spec.cy.js', - }, - }) - .then((obj) => { - // since video was recording, there was a delay to let video finish - expect(Reporter.setVideoTimestamp).calledWith(startedVideoCapture, [1, 2, 3]) - expect(runMode.getVideoRecordingDelay).to.have.returned(1000) - expect(Promise.prototype.delay).to.be.calledWith(1000) - expect(runMode.postProcessRecording).to.be.calledWith('foo.mp4', 'foo-compressed.mp4', 32, true) - - expect(runMode.displayResults).to.be.calledWith(results) - expect(runMode.displayScreenshots).to.be.calledWith(screenshots) - - expect(obj).to.deep.eq({ - screenshots, - video: 'foo.mp4', - error: null, - hooks: null, - reporterStats: null, - shouldUploadVideo: true, - tests: results.tests, - spec: { - path: 'cypress/e2e/spec.cy.js', - }, - stats: { - tests: 1, - passes: 2, - failures: 3, - pending: 4, - duration: 5, - }, - }) - }) - }) - - it('exiting early resolves with no tests, and error', function () { - sinon.useFakeTimers({ shouldAdvanceTime: true }) - - const err = new Error('foo') - const startedVideoCapture = new Date - const wallClock = new Date() - const screenshots = [{}, {}, {}] - const endVideoCapture = sinon.stub().resolves() - - sinon.stub(runMode, 'postProcessRecording').resolves() - sinon.spy(runMode, 'displayResults') - sinon.spy(runMode, 'displayScreenshots') - sinon.spy(Promise.prototype, 'delay') - - process.nextTick(() => { - runMode.exitEarly(err) - }) - - return runMode.waitForTestsToFinishRunning({ - project: this.projectInstance, - videoName: 'foo.mp4', - compressedVideoName: 'foo-compressed.mp4', - videoCompression: 32, - videoUploadOnPasses: true, - gui: false, - screenshots, - startedVideoCapture, - endVideoCapture, - spec: { - path: 'cypress/e2e/spec.cy.js', - }, - }) - .then((obj) => { - // since video was recording, there was a delay to let video finish - expect(runMode.getVideoRecordingDelay).to.have.returned(1000) - expect(Promise.prototype.delay).to.be.calledWith(1000) - expect(runMode.postProcessRecording).to.be.calledWith('foo.mp4', 'foo-compressed.mp4', 32, true) - - expect(runMode.displayResults).to.be.calledWith(obj) - expect(runMode.displayScreenshots).to.be.calledWith(screenshots) - - expect(obj).to.deep.eq({ - screenshots, - error: err.message, - video: 'foo.mp4', - hooks: null, - tests: null, - reporterStats: null, - shouldUploadVideo: true, - spec: { - path: 'cypress/e2e/spec.cy.js', - }, - stats: { - failures: 1, - tests: 0, - passes: 0, - pending: 0, - suites: 0, - skipped: 0, - wallClockDuration: 0, - wallClockStartedAt: wallClock.toJSON(), - wallClockEndedAt: wallClock.toJSON(), - }, - }) - }) - }) - - it('logs warning and resolves on failed video end', async function () { - this.setupProjectEnd() - - sinon.spy(videoCapture, 'process') - const endVideoCapture = sinon.stub().rejects() - - await runMode.waitForTestsToFinishRunning({ - project: this.projectInstance, - videoName: 'foo.mp4', - compressedVideoName: 'foo-compressed.mp4', - videoCompression: 32, - videoUploadOnPasses: true, - gui: false, - endVideoCapture, - }) - - expect(errors.warning).to.be.calledWith('VIDEO_POST_PROCESSING_FAILED') - - expect(videoCapture.process).not.to.be.called - }) - - it('logs warning and resolves on failed video compression', async function () { - this.setupProjectEnd() - - const endVideoCapture = sinon.stub().resolves() - - sinon.stub(videoCapture, 'process').rejects() - - await runMode.waitForTestsToFinishRunning({ - project: this.projectInstance, - videoName: 'foo.mp4', - compressedVideoName: 'foo-compressed.mp4', - videoCompression: 32, - videoUploadOnPasses: true, - gui: false, - endVideoCapture, - }) - - expect(errors.warning).to.be.calledWith('VIDEO_POST_PROCESSING_FAILED') - }) - - it('does not upload video when videoUploadOnPasses is false and no failures', function () { - this.setupProjectEnd() - - sinon.spy(runMode, 'postProcessRecording') - sinon.spy(videoCapture, 'process') - const endVideoCapture = sinon.stub().resolves() - - return runMode.waitForTestsToFinishRunning({ - project: this.projectInstance, - videoName: 'foo.mp4', - compressedVideoName: 'foo-compressed.mp4', - videoCompression: 32, - videoUploadOnPasses: false, - gui: false, - endVideoCapture, - }) - .then(() => { - expect(runMode.postProcessRecording).to.be.calledWith('foo.mp4', 'foo-compressed.mp4', 32, false) - - expect(videoCapture.process).not.to.be.called - }) - }) - - it('does not delay when not capturing a video', () => { - sinon.stub(runMode, 'listenForProjectEnd').resolves({}) - - return runMode.waitForTestsToFinishRunning({ - startedVideoCapture: null, - }) - .then(() => { - expect(runMode.getVideoRecordingDelay).to.have.returned(0) - }) - }) - - describe('when video is deleted in after:spec event', function () { - beforeEach(function () { - this.setupProjectEnd() - sinon.spy(runMode, 'postProcessRecording') - sinon.spy(videoCapture, 'process') - - fs.pathExists.resolves(false) - }) - - it('does not process or upload video', function () { - return runMode.waitForTestsToFinishRunning({ - project: this.projectInstance, - startedVideoCapture: new Date(), - videoName: 'foo.mp4', - endVideoCapture: sinon.stub().resolves(), - }) - .then((results) => { - expect(runMode.postProcessRecording).not.to.be.called - expect(videoCapture.process).not.to.be.called - expect(results.shouldUploadVideo).to.be.false - }) - }) - - it('nulls out video value from results', function () { - return runMode.waitForTestsToFinishRunning({ - project: this.projectInstance, - startedVideoCapture: new Date(), - videoName: 'foo.mp4', - endVideoCapture: sinon.stub().resolves(), - }) - .then((results) => { - expect(results.video).to.be.null - }) - }) - }) - }) - - context('.listenForProjectEnd', () => { - it('resolves with end event + argument', function () { - process.nextTick(() => { - return this.projectInstance.emit('end', { foo: 'bar' }) - }) - - return runMode.listenForProjectEnd(this.projectInstance) - .then((obj) => { - expect(obj).to.deep.eq({ - foo: 'bar', - }) - }) - }) - - it('stops listening to end event', function () { - process.nextTick(() => { - expect(this.projectInstance.listeners('end')).to.have.length(1) - this.projectInstance.emit('end', { foo: 'bar' }) - - expect(this.projectInstance.listeners('end')).to.have.length(0) - }) - - return runMode.listenForProjectEnd(this.projectInstance) - }) - }) - - context('.run browser vs video recording', () => { - beforeEach(function () { - const config = { - proxyUrl: 'http://localhost:12345', - video: true, - videosFolder: 'videos', - } - - sinon.stub(electron.app, 'on').withArgs('ready').yieldsAsync() - sinon.stub(user, 'ensureAuthToken') - sinon.stub(random, 'id').returns(1234) - sinon.stub(openProject, 'create').resolves(openProject) - sinon.stub(runMode, 'waitForSocketConnection').resolves() - sinon.stub(fs, 'access').resolves() - sinon.stub(runMode, 'waitForTestsToFinishRunning').resolves({ - stats: { failures: 10 }, - spec: {}, - }) - - sinon.spy(runMode, 'waitForBrowserToConnect') - sinon.stub(videoCapture, 'start').resolves() - sinon.stub(openProject, 'launch').resolves() - this.projectInstance.__setConfig(config) - sinon.stub(openProject, 'getProject').returns({ - getProjectId: () => Promise.resolve({}), - options: this.projectInstance.options, - getConfig: () => { - return { - e2e: { - specPattern: '...', - }, - } - }, - ctx: { - project: { - findSpecs: () => Promise.resolve([{}]), - }, - }, - }) - - sinon.spy(errors, 'warning') - }) - - it('shows no warnings for default browser', () => { - return runMode.run({ testingType: 'e2e' }) - .then(() => { - expect(errors.warning).to.not.be.called - }) - }) - - it('throws an error if invalid browser family supplied', () => { - const browser = { name: 'opera', family: 'opera - btw when is Opera support coming?' } - - sinon.stub(browsers, 'ensureAndGetByNameOrPath').resolves(browser) - - return expect(runMode.run({ browser: 'opera', testingType: 'e2e' })) - .to.be.rejectedWith(/invalid browser family in/) - }) - - it('throws an error if unsupportedVersion', () => { - const browser = { displayName: 'SomeBrowser', warning: 'blah blah', unsupportedVersion: true } - - sinon.stub(browsers, 'ensureAndGetByNameOrPath').resolves(browser) - - return expect(runMode.run()) - .to.be.rejectedWith('blah blah') - }) - - it('shows no warnings for chrome browser', () => { - return runMode.run({ browser: 'chrome' }) - .then(() => { - expect(errors.warning).to.not.be.called - }) - }) - - it('names video file with spec name', () => { - return runMode.run() - .then(() => { - expect(videoCapture.start).to.be.calledWith('videos/foo_spec.js.mp4') - - expect(runMode.waitForTestsToFinishRunning).to.be.calledWithMatch({ - compressedVideoName: 'videos/foo_spec.js-compressed.mp4', - }) - }) - }) - }) - - context('.run', () => { - beforeEach(function () { - sinon.stub(this.projectInstance, 'getConfig').resolves({ - proxyUrl: 'http://localhost:12345', - }) - - sinon.stub(electron.app, 'on').withArgs('ready').yieldsAsync() - sinon.stub(user, 'ensureAuthToken') - sinon.stub(fs, 'access').resolves() - sinon.stub(random, 'id').returns(1234) - sinon.stub(openProject, 'create').resolves(openProject) - sinon.stub(system, 'info').resolves({ osName: 'osFoo', osVersion: 'fooVersion' }) - sinon.stub(browsers, 'ensureAndGetByNameOrPath').resolves({ - name: 'fooBrowser', - path: 'path/to/browser', - version: '777', - family: 'chromium', - }) - - sinon.stub(runMode, 'waitForSocketConnection').resolves() - sinon.stub(runMode, 'waitForTestsToFinishRunning').resolves({ - stats: { failures: 10 }, - spec: {}, - }) - - sinon.spy(runMode, 'waitForBrowserToConnect') - sinon.spy(runMode, 'runSpecs') - sinon.stub(openProject, 'launch').resolves() - sinon.stub(openProject, 'getProject').returns(this.projectInstance) - }) - - it('no longer ensures user session', () => { - return runMode.run() - .then(() => { - expect(user.ensureAuthToken).not.to.be.called - }) - }) - - it('resolves with object and totalFailed', () => { - return runMode.run() - .then((results) => { - expect(results).to.have.property('totalFailed', 10) - }) - }) - - it('passes projectRoot + options to openProject', () => { - const opts = { projectRoot: '/path/to/project', foo: 'bar' } - - return runMode.run(opts) - .then(() => { - expect(openProject.create).to.be.calledWithMatch(opts.projectRoot, opts) - }) - }) - - it('passes project + id to waitForBrowserToConnect', function () { - return runMode.run() - .then(() => { - expect(runMode.waitForBrowserToConnect).to.be.calledWithMatch({ - project: this.projectInstance, - socketId: 1234, - }) - }) - }) - - it('passes project to waitForTestsToFinishRunning', function () { - return runMode.run() - .then(() => { - expect(runMode.waitForTestsToFinishRunning).to.be.calledWithMatch({ - project: this.projectInstance, - }) - }) - }) - - it('passes headed to openProject.launch', () => { - const browser = { name: 'electron', family: 'chromium' } - - browsers.ensureAndGetByNameOrPath.resolves(browser) - - return runMode.run({ headed: true }) - .then(() => { - expect(openProject.launch).to.be.calledWithMatch( - browser, - { - name: 'foo_spec.js', - absolute: '/path/to/spec.js', - }, - { - show: true, - }, - ) - }) - }) - - it('passes sys to runSpecs', () => { - return runMode.run() - .then(() => { - expect(runMode.runSpecs).to.be.calledWithMatch({ - sys: { - osName: 'osFoo', - osVersion: 'fooVersion', - }, - }) - }) - }) - - it('passes browser to runSpecs', () => { - return runMode.run() - .then(() => { - expect(runMode.runSpecs).to.be.calledWithMatch({ - browser: { - name: 'fooBrowser', - path: 'path/to/browser', - version: '777', - }, - }) - }) - }) - }) - - context('#displayRunStarting', () => { - // restore pkg.version property - // for some reason I cannot stub property value using Sinon - let version - // save a copy of "true" experiments right away - const names = _.cloneDeep(experimental.names) - - before(() => { - // reset experiments names before each test - experimental.names = {} - version = pkg.version - }) - - afterEach(() => { - pkg.version = version - experimental.names = names - }) - - it('returns heading with experiments', () => { - pkg.version = '1.2.3' - - experimental.names = { - experimentalFeatureA: 'experimentalFeatureA', - experimentalFeatureB: 'experimentalFeatureB', - } - - const options = { - browser: { - displayName: 'Electron', - majorVersion: 99, - isHeadless: true, - }, - config: { - resolved: { - experimentalFeatureA: { - value: true, - from: 'config', - }, - experimentalFeatureB: { - value: 4, - from: 'cli', - }, - }, - }, - } - const heading = runMode.displayRunStarting(options) - - snapshot('enabled experiments', stripAnsi(heading)) - }) - - it('resets the experiments names', () => { - expect(experimental.names, 'experiments were reset').to.deep.equal(names) - }) - - it('returns heading with some enabled experiments', () => { - pkg.version = '1.2.3' - - experimental.names = { - experimentalFeatureA: 'experimentalFeatureA', - experimentalFeatureB: 'experimentalFeatureB', - } - - const options = { - browser: { - displayName: 'Electron', - majorVersion: 99, - isHeadless: true, - }, - config: { - resolved: { - // means this feature is not enabled, should not appear in the heading - experimentalFeatureA: { - value: true, - from: 'default', - }, - experimentalFeatureB: { - value: 4, - from: 'cli', - }, - }, - }, - } - const heading = runMode.displayRunStarting(options) - - const text = stripAnsi(heading) - - snapshot('some enabled experiments', text) - // explicit assertions for test clarity - expect(text).to.not.include('experimentalFeatureA') - expect(text).to.include('experimentalFeatureB') - }) - - it('returns heading without experiments', () => { - pkg.version = '1.2.3' - - const options = { - browser: { - displayName: 'Electron', - majorVersion: 99, - isHeadless: true, - }, - config: { - resolved: {}, - }, - } - const heading = runMode.displayRunStarting(options) - - snapshot('without enabled experiments', stripAnsi(heading)) - }) - - it('restores pkg.version', () => { - expect(pkg.version).to.not.equal('1.2.3') - }) - }) -}) diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index 6305a0b06a3b..46e24a6dd29d 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -30,7 +30,7 @@ export interface FullConfig extends Partial - & Pick // TODO: Figure out how to type this better. + & Pick // TODO: Figure out how to type this better. export interface SettingsOptions { testingType?: 'component' |'e2e' diff --git a/packages/types/src/server.ts b/packages/types/src/server.ts index 53d5c960dc41..a38eba449acc 100644 --- a/packages/types/src/server.ts +++ b/packages/types/src/server.ts @@ -10,6 +10,7 @@ export interface LaunchOpts { onBrowserClose?: (...args: unknown[]) => void onBrowserOpen?: (...args: unknown[]) => void onError?: (err: Error) => void + onWarning?: (err: Error) => void } export interface LaunchArgs { @@ -46,7 +47,7 @@ export interface AutomationMiddleware { onBeforeRequest?: OnRequestEvent | null onRequest?: OnRequestEvent | null onResponse?: NullableMiddlewareHook - onAfterResponse?: NullableMiddlewareHook + onAfterResponse?: ((eventName: string, data: any, resp: any) => void) | null } type WebSocketOptionsCallback = (...args: any[]) => any diff --git a/packages/types/src/spec.ts b/packages/types/src/spec.ts index cdd90313ce6d..1725e6723c24 100644 --- a/packages/types/src/spec.ts +++ b/packages/types/src/spec.ts @@ -15,3 +15,7 @@ export interface FoundSpec extends SpecFile { fileExtension: string specType: Cypress.CypressSpecType } + +export interface SpecWithRelativeRoot extends FoundSpec { + relativeToCommonRoot: string +} From 32221ff43aa0a8b9504c4d8b1cc3b210ec0a7ce4 Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 25 Aug 2022 15:10:12 -0400 Subject: [PATCH 30/45] chore(webpack-dev-server): update error message --- npm/webpack-dev-server/src/helpers/angularHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/webpack-dev-server/src/helpers/angularHandler.ts b/npm/webpack-dev-server/src/helpers/angularHandler.ts index 3fb19982fb48..0ef004aba0ca 100644 --- a/npm/webpack-dev-server/src/helpers/angularHandler.ts +++ b/npm/webpack-dev-server/src/helpers/angularHandler.ts @@ -42,7 +42,7 @@ export async function getProjectConfig (projectRoot: string): Promise angularJson.projects[name].projectType === 'application') if (!defaultProject) { - throw new Error('Could not find a project with projectType "application" in "angular.json"') + throw new Error('Could not find a project with projectType "application" in "angular.json". Visit https://docs.cypress.io/guides/references/configuration#Options-API to see how to pass in a custom project configuration') } } From 99562af65a10abb0fab211fd97b13f98e2b0f959 Mon Sep 17 00:00:00 2001 From: Adam Murray Date: Thu, 25 Aug 2022 15:22:25 -0500 Subject: [PATCH 31/45] feat(cypress/schematic): add support for component testing (#23385) Co-authored-by: Jordan --- npm/cypress-schematic/README.md | 102 +++++++++++-- npm/cypress-schematic/package.json | 4 +- .../builders/cypress/cypressBuilderOptions.ts | 2 + .../src/builders/cypress/index.ts | 4 + .../src/builders/cypress/schema.json | 12 ++ npm/cypress-schematic/src/ct.spec.ts | 41 ++++++ npm/cypress-schematic/src/e2e.spec.ts | 8 +- .../src/schematics/collection.json | 16 +- .../files-core/cypress.config.ts.template | 19 +++ .../cypress/e2e/spec.cy.ts | 0 .../cypress/fixtures/example.json | 0 .../cypress/support/commands.ts | 0 .../cypress/support/e2e.ts | 2 +- .../cypress/tsconfig.json | 2 +- .../ng-add/files-ct/component-index.html | 12 ++ .../schematics/ng-add/files-ct/component.ts | 39 +++++ .../schematics/ng-add/files/cypress.config.ts | 7 - .../src/schematics/ng-add/index.spec.ts | 19 ++- .../src/schematics/ng-add/index.ts | 139 ++++++++++++++---- .../src/schematics/ng-add/schema.json | 16 +- .../{e2e => cypress-ct-tests}/index.spec.ts | 11 +- .../ng-generate/cypress-ct-tests/index.ts | 20 +++ .../{e2e => cypress-ct-tests}/schema.json | 18 +-- .../{e2e => cypress-ct-tests}/schema.ts | 7 +- .../ng-generate/cypress-test/index.spec.ts | 40 +++++ .../{e2e => cypress-test}/index.ts | 23 ++- .../ng-generate/cypress-test/schema.json | 46 ++++++ .../ng-generate/cypress-test/schema.ts | 16 ++ ...eName@dasherize__.component.cy.ts.template | 7 + .../__name@dasherize__.cy.ts.template | 0 .../src/schematics/utils/dependencies.ts | 2 +- .../src/schematics/utils/index.ts | 72 ++++++++- npm/cypress-schematic/tsconfig.json | 2 +- 33 files changed, 594 insertions(+), 114 deletions(-) create mode 100644 npm/cypress-schematic/src/ct.spec.ts create mode 100644 npm/cypress-schematic/src/schematics/ng-add/files-core/cypress.config.ts.template rename npm/cypress-schematic/src/schematics/ng-add/{files => files-core}/cypress/e2e/spec.cy.ts (100%) rename npm/cypress-schematic/src/schematics/ng-add/{files => files-core}/cypress/fixtures/example.json (100%) rename npm/cypress-schematic/src/schematics/ng-add/{files => files-core}/cypress/support/commands.ts (100%) rename npm/cypress-schematic/src/schematics/ng-add/{files => files-core}/cypress/support/e2e.ts (91%) rename npm/cypress-schematic/src/schematics/ng-add/{files => files-core}/cypress/tsconfig.json (65%) create mode 100644 npm/cypress-schematic/src/schematics/ng-add/files-ct/component-index.html create mode 100644 npm/cypress-schematic/src/schematics/ng-add/files-ct/component.ts delete mode 100644 npm/cypress-schematic/src/schematics/ng-add/files/cypress.config.ts rename npm/cypress-schematic/src/schematics/ng-generate/{e2e => cypress-ct-tests}/index.spec.ts (71%) create mode 100644 npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/index.ts rename npm/cypress-schematic/src/schematics/ng-generate/{e2e => cypress-ct-tests}/schema.json (52%) rename npm/cypress-schematic/src/schematics/ng-generate/{e2e => cypress-ct-tests}/schema.ts (74%) create mode 100644 npm/cypress-schematic/src/schematics/ng-generate/cypress-test/index.spec.ts rename npm/cypress-schematic/src/schematics/ng-generate/{e2e => cypress-test}/index.ts (71%) create mode 100644 npm/cypress-schematic/src/schematics/ng-generate/cypress-test/schema.json create mode 100644 npm/cypress-schematic/src/schematics/ng-generate/cypress-test/schema.ts create mode 100644 npm/cypress-schematic/src/schematics/ng-generate/files/ct/__path__/__fileName@dasherize__.component.cy.ts.template rename npm/cypress-schematic/src/schematics/ng-generate/files/{ => e2e}/__path__/__name@dasherize__.cy.ts.template (100%) diff --git a/npm/cypress-schematic/README.md b/npm/cypress-schematic/README.md index 5f0b5baff0fb..bd61e4828164 100644 --- a/npm/cypress-schematic/README.md +++ b/npm/cypress-schematic/README.md @@ -19,26 +19,36 @@ ✅ Install Cypress -✅ Add npm scripts for running Cypress in `run` mode and `open` mode +✅ Add npm scripts for running Cypress e2e tests in `run` mode and `open` mode ✅ Scaffold base Cypress files and directories -✅ Provide the ability to add new e2e files easily using `ng-generate` +✅ Provide the ability to add new e2e and component specs easily using `ng-generate` -✅ Optional: prompt you to add or update the default `ng e2e` command to use Cypress. +✅ Optional: prompt you to add or update the default `ng e2e` command to use Cypress for e2e tests. + +✅ Optional: prompt you to add a `ng ct` command to use Cypress component testing. ## Requirements -- Angular 12+ +- Angular 13+ ## Usage ⏯ -Install the schematic: +### Adding E2E and Component Testing + +To install the schematic via prompts: ```shell ng add @cypress/schematic ``` +To install the schematic via cli arguments (installs both e2e and component testing): + +```shell +ng add @cypress/schematic --e2e --component +``` + To run Cypress in `open` mode within your project: ```shell script @@ -57,11 +67,49 @@ If you have chosen to add or update the `ng e2e` command, you can also run Cypre ng e2e ``` -To generate new e2e spec files: +If you have chosen to add Cypress component testing, you can run component tests in `open` mode using this: + +```shell script +ng run {project-name}:ct +``` + +### Generating New Cypress Spec Files + +To generate a new e2e spec file: + +```shell script +ng generate @cypress/schematic:spec +``` + +or (without cli prompt) + +```shell script +ng generate @cypress/schematic:spec {name} +``` + +To generate a new component spec file: + +```shell script +ng generate @cypress/schematic:spec --component +``` + +or (without cli prompt) + +```shell script +ng generate @cypress/schematic:spec {component name} --component +``` + +To generate a new component spec file in a specific folder: + +```shell script +ng generate @cypress/schematic:spec {component name} --component --path {path relative to project root} +``` + +To generate new component spec files alongside all component files in a project: ```shell script -ng generate @cypress/schematic:e2e -``` +ng generate @cypress/schematic:specs-ct +``` ## Builder Options 🛠 @@ -109,7 +157,7 @@ We recommend setting your [Cypress Dashboard](https://on.cypress.io/features-das Read our docs to learn more about [recording test results](https://on.cypress.io/recording-project-runs) to the [Cypress Dashboard](https://on.cypress.io/features-dashboard). -### Specifying a custom `cypress.json` config file +### Specifying a custom config file It may be useful to have different Cypress configuration files per environment (ie. development, staging, production). @@ -223,12 +271,22 @@ In order to prevent the application from building, add the following to the end ## Generator Options +### Specify Testing Type + +The default generated spec is E2E. In order to generate a component test you can run: + +```shell script +ng generate @cypress/schematic:spec --name=button -t component +``` + +`-t` is an alias for `testing-type`. It accepts `e2e` or `component` as arguments. If you are using the CLI tool, a prompt will appear asking which spec type you want to generate. + ### Specify Filename (bypassing CLI prompt) -In order to bypass the prompt asking for your e2e spec name, simply add a `--name=` flag like this: +In order to bypass the prompt asking for your spec name add a `--name=` flag like this: ```shell script -ng generate @cypress/schematic:e2e --name=login +ng generate @cypress/schematic:spec --name=login ``` This will create a new spec file named `login.cy.ts` in the default Cypress folder location. @@ -238,17 +296,33 @@ This will create a new spec file named `login.cy.ts` in the default Cypress fold Add a `--project=` flag to specify the project: ```shell script -ng generate @cypress/schematic:e2e --name=login --project=sandbox +ng generate @cypress/schematic:spec --name=login --project=sandbox ``` ### Specify Path Add a `--path=` flag to specify the project: ```shell script -ng generate @cypress/schematic:e2e --name=login --path=src/app/tests +ng generate @cypress/schematic:spec --name=login --path=src/app/tests +``` + +This will create a spec file in your specific location, creating folders as needed. By default, new specs are created in either `cypress/e2e` for E2E specs or `cypress/ct` for component specs. + +### Generate Tests for All Components + +You can scaffold component test specs alongside all your components in the default project by using: + +```shell script +ng generate @cypress/schematic:specs-ct -g ``` -This will create the e2e spec file in your specific location, creating folders as needed. +This will identify files ending in `component.ts`. It will then create spec files alongside them - if they don't exist. + +If you would like to specify a project, you can use the command: + +```shell script +ng generate @cypress/schematic:specs-ct -g -p {project-name} +``` ## Migrating from Protractor to Cypress? diff --git a/npm/cypress-schematic/package.json b/npm/cypress-schematic/package.json index 9e8be56964d9..55005c1ea350 100644 --- a/npm/cypress-schematic/package.json +++ b/npm/cypress-schematic/package.json @@ -27,8 +27,8 @@ "typescript": "^4.7.4" }, "peerDependencies": { - "@angular/cli": ">=14.1.0", - "@angular/core": ">=14.1.0" + "@angular/cli": ">=12", + "@angular/core": ">=12" }, "license": "MIT", "repository": { diff --git a/npm/cypress-schematic/src/builders/cypress/cypressBuilderOptions.ts b/npm/cypress-schematic/src/builders/cypress/cypressBuilderOptions.ts index fa6e3b8ef766..c5239730337b 100644 --- a/npm/cypress-schematic/src/builders/cypress/cypressBuilderOptions.ts +++ b/npm/cypress-schematic/src/builders/cypress/cypressBuilderOptions.ts @@ -6,6 +6,7 @@ export interface CypressBuilderOptions extends JsonObject { browser: 'electron' | 'chrome' | 'chromium' | 'canary' | 'firefox' | 'edge' | string devServerTarget: string e2e: boolean + component: boolean env: Record quiet: boolean exit: boolean @@ -20,4 +21,5 @@ export interface CypressBuilderOptions extends JsonObject { spec: string tsConfig: string watch: boolean + testingType: 'e2e' | 'component' } diff --git a/npm/cypress-schematic/src/builders/cypress/index.ts b/npm/cypress-schematic/src/builders/cypress/index.ts index bd4d265760c9..aab630063c27 100644 --- a/npm/cypress-schematic/src/builders/cypress/index.ts +++ b/npm/cypress-schematic/src/builders/cypress/index.ts @@ -75,6 +75,10 @@ function initCypress (userOptions: CypressBuilderOptions): Observable { + const projectPath = Fixtures.projectPath(project) + + Fixtures.removeProject(project) + await Fixtures.scaffoldProject(project) + await FixturesScaffold.scaffoldProjectNodeModules(project) + await fs.remove(path.join(projectPath, 'cypress.config.ts')) + await fs.remove(path.join(projectPath, 'cypress')) + + return projectPath +} + +const runCommandInProject = (command: string, projectPath: string) => { + const [ex, ...args] = command.split(' ') + + return execa(ex, args, { cwd: projectPath, stdio: 'inherit' }) +} + +const cypressSchematicPackagePath = path.join(__dirname, '..') + +const ANGULAR_PROJECTS: ProjectFixtureDir[] = ['angular-13', 'angular-14'] + +describe('ng add @cypress/schematic / e2e and ct', function () { + this.timeout(1000 * 60 * 4) + + for (const project of ANGULAR_PROJECTS) { + it('should install ct files with option and no component specs', async () => { + const projectPath = await scaffoldAngularProject(project) + + await runCommandInProject(`yarn add @cypress/schematic@file:${cypressSchematicPackagePath}`, projectPath) + await runCommandInProject('yarn ng add @cypress/schematic --e2e --component', projectPath) + await runCommandInProject('yarn ng run angular:ct --watch false --spec src/app/app.component.cy.ts', projectPath) + }) + } +}) diff --git a/npm/cypress-schematic/src/e2e.spec.ts b/npm/cypress-schematic/src/e2e.spec.ts index 2eb77d300734..add1d333e549 100644 --- a/npm/cypress-schematic/src/e2e.spec.ts +++ b/npm/cypress-schematic/src/e2e.spec.ts @@ -26,16 +26,16 @@ const cypressSchematicPackagePath = path.join(__dirname, '..') const ANGULAR_PROJECTS: ProjectFixtureDir[] = ['angular-13', 'angular-14'] -describe('cypress-schematic-e2e', function () { +describe('ng add @cypress/schematic / only e2e', function () { this.timeout(1000 * 60 * 4) for (const project of ANGULAR_PROJECTS) { - it('should', async () => { + it('should install e2e files by default', async () => { const projectPath = await scaffoldAngularProject(project) await runCommandInProject(`yarn add @cypress/schematic@file:${cypressSchematicPackagePath}`, projectPath) - await runCommandInProject('yarn ng add @cypress/schematic --e2eUpdate', projectPath) - await runCommandInProject('yarn ng e2e angular --watch false', projectPath) + await runCommandInProject('yarn ng add @cypress/schematic --e2e --component false --add-ct-specs false', projectPath) + await runCommandInProject('yarn ng e2e --watch false', projectPath) }) } }) diff --git a/npm/cypress-schematic/src/schematics/collection.json b/npm/cypress-schematic/src/schematics/collection.json index 4c27b6e1d4e5..8141b0ec54a3 100644 --- a/npm/cypress-schematic/src/schematics/collection.json +++ b/npm/cypress-schematic/src/schematics/collection.json @@ -6,13 +6,15 @@ "factory": "./ng-add/index", "schema": "./ng-add/schema.json" }, - "e2e": { - "description": "Create an e2e spec file", - "factory": "./ng-generate/e2e/index", - "schema": "./ng-generate/e2e/schema.json", - "aliases": [ - "e2e-spec" - ] + "spec": { + "description": "Create a single spec file", + "factory": "./ng-generate/cypress-test/index", + "schema": "./ng-generate/cypress-test/schema.json" + }, + "specs-ct": { + "description": "Create spec files for all Angular components in a project", + "factory": "./ng-generate/cypress-ct-tests/index", + "schema": "./ng-generate/cypress-ct-tests/schema.json" } } } diff --git a/npm/cypress-schematic/src/schematics/ng-add/files-core/cypress.config.ts.template b/npm/cypress-schematic/src/schematics/ng-add/files-core/cypress.config.ts.template new file mode 100644 index 000000000000..acfba90c7323 --- /dev/null +++ b/npm/cypress-schematic/src/schematics/ng-add/files-core/cypress.config.ts.template @@ -0,0 +1,19 @@ +import { defineConfig } from 'cypress' + +export default defineConfig({ + <% if (e2e) { %> + e2e: { + 'baseUrl': '<%= baseUrl%>', + supportFile: false + }, + <% } %> + <% if (component) { %> + component: { + devServer: { + framework: 'angular', + bundler: 'webpack', + }, + specPattern: '**/*.cy.ts' + } + <% } %> +}) \ No newline at end of file diff --git a/npm/cypress-schematic/src/schematics/ng-add/files/cypress/e2e/spec.cy.ts b/npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/e2e/spec.cy.ts similarity index 100% rename from npm/cypress-schematic/src/schematics/ng-add/files/cypress/e2e/spec.cy.ts rename to npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/e2e/spec.cy.ts diff --git a/npm/cypress-schematic/src/schematics/ng-add/files/cypress/fixtures/example.json b/npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/fixtures/example.json similarity index 100% rename from npm/cypress-schematic/src/schematics/ng-add/files/cypress/fixtures/example.json rename to npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/fixtures/example.json diff --git a/npm/cypress-schematic/src/schematics/ng-add/files/cypress/support/commands.ts b/npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/support/commands.ts similarity index 100% rename from npm/cypress-schematic/src/schematics/ng-add/files/cypress/support/commands.ts rename to npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/support/commands.ts diff --git a/npm/cypress-schematic/src/schematics/ng-add/files/cypress/support/e2e.ts b/npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/support/e2e.ts similarity index 91% rename from npm/cypress-schematic/src/schematics/ng-add/files/cypress/support/e2e.ts rename to npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/support/e2e.ts index 80a6b856d9c8..55540ff7d956 100644 --- a/npm/cypress-schematic/src/schematics/ng-add/files/cypress/support/e2e.ts +++ b/npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/support/e2e.ts @@ -1,5 +1,5 @@ // *********************************************************** -// This example support/component.ts is processed and +// This example support/e2e.ts is processed and // loaded automatically before your test files. // // This is a great place to put global configuration and diff --git a/npm/cypress-schematic/src/schematics/ng-add/files/cypress/tsconfig.json b/npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/tsconfig.json similarity index 65% rename from npm/cypress-schematic/src/schematics/ng-add/files/cypress/tsconfig.json rename to npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/tsconfig.json index 0508f357b97a..79d78d7ec971 100644 --- a/npm/cypress-schematic/src/schematics/ng-add/files/cypress/tsconfig.json +++ b/npm/cypress-schematic/src/schematics/ng-add/files-core/cypress/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "<%= relativeToWorkspace %>/tsconfig.json", + "extends": "../tsconfig.json", "include": ["**/*.ts"], "compilerOptions": { "sourceMap": false, diff --git a/npm/cypress-schematic/src/schematics/ng-add/files-ct/component-index.html b/npm/cypress-schematic/src/schematics/ng-add/files-ct/component-index.html new file mode 100644 index 000000000000..ac6e79fd83df --- /dev/null +++ b/npm/cypress-schematic/src/schematics/ng-add/files-ct/component-index.html @@ -0,0 +1,12 @@ + + + + + + + Components App + + +
+ + \ No newline at end of file diff --git a/npm/cypress-schematic/src/schematics/ng-add/files-ct/component.ts b/npm/cypress-schematic/src/schematics/ng-add/files-ct/component.ts new file mode 100644 index 000000000000..96e1d279839c --- /dev/null +++ b/npm/cypress-schematic/src/schematics/ng-add/files-ct/component.ts @@ -0,0 +1,39 @@ +// *********************************************************** +// This example support/component.ts is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') + +import { mount } from 'cypress/angular' + +// Augment the Cypress namespace to include type definitions for +// your custom command. +// Alternatively, can be defined in cypress/support/component.d.ts +// with a at the top of your spec. +declare global { + namespace Cypress { + interface Chainable { + mount: typeof mount + } + } +} + +Cypress.Commands.add('mount', mount) + +// Example use: +// cy.mount(MyComponent) diff --git a/npm/cypress-schematic/src/schematics/ng-add/files/cypress.config.ts b/npm/cypress-schematic/src/schematics/ng-add/files/cypress.config.ts deleted file mode 100644 index 8541c85b73fb..000000000000 --- a/npm/cypress-schematic/src/schematics/ng-add/files/cypress.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineConfig } from 'cypress' - -export default defineConfig({ - e2e: { - 'baseUrl': '<%= baseUrl%>', - }, -}) diff --git a/npm/cypress-schematic/src/schematics/ng-add/index.spec.ts b/npm/cypress-schematic/src/schematics/ng-add/index.spec.ts index eff647c20cd1..a83745411981 100644 --- a/npm/cypress-schematic/src/schematics/ng-add/index.spec.ts +++ b/npm/cypress-schematic/src/schematics/ng-add/index.spec.ts @@ -31,8 +31,8 @@ describe('@cypress/schematic: ng-add', () => { appTree = await schematicRunner.runExternalSchematicAsync('@schematics/angular', 'application', appOptions, appTree).toPromise() }) - it('should create cypress files', async () => { - return schematicRunner.runSchematicAsync('ng-add', {}, appTree).toPromise().then((tree) => { + it('should create cypress files for e2e testing by default', async () => { + await schematicRunner.runSchematicAsync('ng-add', {}, appTree).toPromise().then((tree: UnitTestTree) => { const files = tree.files expect(files).to.contain('/projects/sandbox/cypress/e2e/spec.cy.ts') @@ -43,4 +43,19 @@ describe('@cypress/schematic: ng-add', () => { expect(files).to.contain('/projects/sandbox/cypress/fixtures/example.json') }) }) + + it('should create cypress files for component testing', async () => { + await schematicRunner.runSchematicAsync('ng-add', { 'component': true }, appTree).toPromise().then((tree: UnitTestTree) => { + const files = tree.files + + expect(files).to.contain('/projects/sandbox/cypress/support/component.ts') + expect(files).to.contain('/projects/sandbox/cypress/support/component-index.html') + expect(files).to.contain('/projects/sandbox/cypress/e2e/spec.cy.ts') + expect(files).to.contain('/projects/sandbox/cypress/support/e2e.ts') + expect(files).to.contain('/projects/sandbox/cypress/support/commands.ts') + expect(files).to.contain('/projects/sandbox/cypress/tsconfig.json') + expect(files).to.contain('/projects/sandbox/cypress.config.ts') + expect(files).to.contain('/projects/sandbox/cypress/fixtures/example.json') + }) + }) }) diff --git a/npm/cypress-schematic/src/schematics/ng-add/index.ts b/npm/cypress-schematic/src/schematics/ng-add/index.ts index 2fa50235ee6e..8a7953377e99 100644 --- a/npm/cypress-schematic/src/schematics/ng-add/index.ts +++ b/npm/cypress-schematic/src/schematics/ng-add/index.ts @@ -7,7 +7,7 @@ import { Rule, SchematicContext, SchematicsException, - template, + applyTemplates, Tree, url, } from '@angular-devkit/schematics' @@ -17,20 +17,32 @@ import { concatMap, map } from 'rxjs/operators' import { addPackageJsonDependency, NodeDependencyType } from '../utils/dependencies' import { + getAngularJsonValue, getAngularVersion, getLatestNodeVersion, NodePackage, + getDirectoriesAndCreateSpecs, } from '../utils' import { relative, resolve } from 'path' import { JSONFile, JSONPath } from '../utils/jsonFile' +type HandleFilesType = { + projects: any + options: any + applyPath: string + movePath?: string + relativeToWorkspacePath: string +} + export default function (_options: any): Rule { return (tree: Tree, _context: SchematicContext) => { _options = { ..._options, __version__: getAngularVersion(tree) } return chain([ updateDependencies(), - addCypressFiles(), + addCypressCoreFiles(_options), + addCypressComponentTestingFiles(_options), + addCtSpecs(_options), addCypressTestScriptsToPackageJson(), modifyAngularJson(_options), ])(tree, _context) @@ -79,33 +91,79 @@ function addCypressTestScriptsToPackageJson (): Rule { } } -function addCypressFiles (): Rule { +function handleFiles (tree: Tree, context: SchematicContext, { projects, options, applyPath, movePath, relativeToWorkspacePath }: HandleFilesType): any { + return chain( + Object.keys(projects).map((name) => { + const project = projects[name] + const projectPath = resolve(getSystemPath(normalize(project.root))) + const workspacePath = resolve(getSystemPath(normalize(''))) + + const relativeToWorkspace = relative(`${projectPath}${relativeToWorkspacePath}`, workspacePath) + + const baseUrl = getBaseUrl(project) + + return mergeWith( + apply(url(applyPath), [ + move(movePath ? `${project.root}${movePath}` : project.root), + applyTemplates({ + ...options, + ...strings, + root: project.root ? `${project.root}/` : project.root, + baseUrl, + relativeToWorkspace, + }), + ]), + ) + }), + )(tree, context) +} + +function addCypressCoreFiles (options: any): Rule { return (tree: Tree, context: SchematicContext) => { context.logger.debug('Adding cypress files') const angularJsonValue = getAngularJsonValue(tree) const { projects } = angularJsonValue - return chain( + return handleFiles(tree, context, { + projects, + options, + applyPath: './files-core', + relativeToWorkspacePath: `/`, + }) + } +} + +function addCypressComponentTestingFiles (options: any): Rule { + return (tree: Tree, context: SchematicContext) => { + if (options.component) { + context.logger.debug('Adding cypress component testing files') + const angularJsonValue = getAngularJsonValue(tree) + const { projects } = angularJsonValue + + return handleFiles(tree, context, { + projects, + options, + applyPath: './files-ct', + movePath: '/cypress/support', + relativeToWorkspacePath: `/cypress`, + }) + } + } +} + +function addCtSpecs (options: any): Rule { + return (tree: Tree) => { + if (options.addCtSpecs) { + const angularJsonValue = getAngularJsonValue(tree) + const { projects } = angularJsonValue + Object.keys(projects).map((name) => { const project = projects[name] - const projectPath = resolve(getSystemPath(normalize(project.root))) - const workspacePath = resolve(getSystemPath(normalize(''))) - const relativeToWorkspace = relative(`${projectPath}/cypress`, workspacePath) - const baseUrl = getBaseUrl(project) - - return mergeWith( - apply(url('./files'), [ - move(project.root), - template({ - ...strings, - root: project.root ? `${project.root}/` : project.root, - baseUrl, - relativeToWorkspace, - }), - ]), - ) - }), - )(tree, context) + const appPath = `${project.root}/${project.sourceRoot}/${project.prefix}` + + return getDirectoriesAndCreateSpecs({ tree, appPath }) + }) + } } } @@ -129,26 +187,26 @@ function addNewCypressCommands ( runJson: JsonObject, openJson: JsonObject, e2eJson: JsonObject, - e2eUpdate: boolean, + e2e: boolean, + componentJson: JsonObject, + component: boolean, ) { const projectArchitectJson = angularJsonVal['projects'][project]['architect'] projectArchitectJson['cypress-run'] = runJson projectArchitectJson['cypress-open'] = openJson - if (e2eUpdate || !projectArchitectJson['e2e']) { + if (component) { + projectArchitectJson['ct'] = componentJson + } + + if (e2e || !projectArchitectJson['e2e']) { projectArchitectJson['e2e'] = e2eJson } return tree.overwrite('./angular.json', JSON.stringify(angularJsonVal, null, 2)) } -function getAngularJsonValue (tree: Tree) { - const angularJson = new JSONFile(tree, './angular.json') - - return angularJson.get([]) as any -} - function modifyAngularJson (options: any): Rule { return (tree: Tree, context: SchematicContext) => { if (tree.exists('./angular.json')) { @@ -195,6 +253,21 @@ function modifyAngularJson (options: any): Rule { }, } + const componentJson = { + builder, + options: { + devServerTarget: `${project}:serve`, + watch: true, + headless: false, + testingType: 'component', + }, + configurations: { + development: { + devServerTarget: `${project}:serve:development`, + }, + }, + } + const configFile = getCypressConfigFile(angularJsonVal, project) if (configFile) { @@ -202,7 +275,7 @@ function modifyAngularJson (options: any): Rule { Object.assign(openJson.options, { configFile }) } - if (options.e2eUpdate) { + if (options.e2e) { context.logger.debug(`Replacing e2e command with cypress-run in angular.json`) removeE2ELinting(tree, angularJsonVal, project) } @@ -220,7 +293,9 @@ function modifyAngularJson (options: any): Rule { runJson, openJson, e2eJson, - options.e2eUpdate, + options.e2e, + componentJson, + options.component, ) }) } else { diff --git a/npm/cypress-schematic/src/schematics/ng-add/schema.json b/npm/cypress-schematic/src/schematics/ng-add/schema.json index 131721b4a661..d530b868c87c 100644 --- a/npm/cypress-schematic/src/schematics/ng-add/schema.json +++ b/npm/cypress-schematic/src/schematics/ng-add/schema.json @@ -4,11 +4,23 @@ "title": "Cypress Install Schema", "type": "object", "properties": { - "e2eUpdate": { + "e2e": { "type": "boolean", "default": true, - "description": "When true, `ng e2e` will be added or updated to use Cypress", + "description": "When true, `ng e2e` will be added or updated to use Cypress.", "x-prompt": "Would you like the default `ng e2e` command to use Cypress? [ Protractor to Cypress Migration Guide: https://on.cypress.io/protractor-to-cypress?cli=true ]" + }, + "component": { + "type": "boolean", + "default": true, + "description": "When true, your project will set up for Cypress component testing.", + "x-prompt": "Would you like to add Cypress component testing? This will add all files needed for Cypress component testing." + }, + "addCtSpecs": { + "type": "boolean", + "default": false, + "alias": "a", + "description": "When true, Cypress component tests will be added alongside `.component` files." } }, "required": [] diff --git a/npm/cypress-schematic/src/schematics/ng-generate/e2e/index.spec.ts b/npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/index.spec.ts similarity index 71% rename from npm/cypress-schematic/src/schematics/ng-generate/e2e/index.spec.ts rename to npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/index.spec.ts index 25acd6deb786..cba6783c3ba8 100644 --- a/npm/cypress-schematic/src/schematics/ng-generate/e2e/index.spec.ts +++ b/npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/index.spec.ts @@ -3,8 +3,9 @@ import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing' import { join } from 'path' import { expect } from 'chai' +import { take } from 'rxjs/operators' -describe('@cypress/schematic:e2e ng-generate', () => { +describe('ng-generate @cypress/schematic:specs-ct', () => { const schematicRunner = new SchematicTestRunner( 'schematics', join(__dirname, '../../collection.json'), @@ -30,11 +31,7 @@ describe('@cypress/schematic:e2e ng-generate', () => { appTree = await schematicRunner.runExternalSchematicAsync('@schematics/angular', 'application', appOptions, appTree).toPromise() }) - it('should create cypress spec file', () => { - return schematicRunner.runSchematicAsync('e2e', { name: 'foo', project: 'sandbox' }, appTree).toPromise().then((tree) => { - const files = tree.files - - expect(files).to.contain('/projects/sandbox/cypress/e2e/foo.cy.ts') - }) + it('should create cypress component tests alongside components', async () => { + return schematicRunner.runSchematicAsync('specs-ct', { project: 'sandbox' }, appTree).pipe(take(1)).subscribe((tree: UnitTestTree) => expect(tree.files).to.contain('/projects/sandbox/app/src/app.component.cy.ts')) }) }) diff --git a/npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/index.ts b/npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/index.ts new file mode 100644 index 000000000000..6c1863d3d1aa --- /dev/null +++ b/npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/index.ts @@ -0,0 +1,20 @@ +import { Rule, Tree, SchematicsException } from '@angular-devkit/schematics' + +import { getAngularJsonValue, getDirectoriesAndCreateSpecs } from '../../utils' +import { Schema } from './schema' + +export default function (options: Schema): Rule { + return (tree: Tree) => { + if (!options.project) { + throw new SchematicsException(`Invalid project name: ${options.project}`) + } + + const angularJsonValue = getAngularJsonValue(tree) + const { projects } = angularJsonValue + const project = projects[options.project] + + const appPath = `${project.sourceRoot}` + + return getDirectoriesAndCreateSpecs({ tree, appPath }) + } +} diff --git a/npm/cypress-schematic/src/schematics/ng-generate/e2e/schema.json b/npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/schema.json similarity index 52% rename from npm/cypress-schematic/src/schematics/ng-generate/e2e/schema.json rename to npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/schema.json index 4087f806ba6a..97c9371ff866 100644 --- a/npm/cypress-schematic/src/schematics/ng-generate/e2e/schema.json +++ b/npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/schema.json @@ -1,33 +1,23 @@ { "$schema": "http://json-schema.org/draft-07/schema", - "$id": "cypress-schematics-e2e-spec", + "$id": "cypress-schematics-generate-ct-specs", "title": "Cypress E2E Spec Options Schema", "type": "object", "properties": { "path": { "type": "string", "format": "path", - "description": "The path to create the component.", + "description": "The path where the spec will be created.", "visible": false }, "project": { "type": "string", "description": "The name of the project.", + "alias": "p", "$default": { "$source": "projectName" } - }, - "name": { - "type": "string", - "description": "The name of the e2e test.", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What is the name of the e2e test?" } }, - "required": [ - "name" - ] + "required": [] } \ No newline at end of file diff --git a/npm/cypress-schematic/src/schematics/ng-generate/e2e/schema.ts b/npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/schema.ts similarity index 74% rename from npm/cypress-schematic/src/schematics/ng-generate/e2e/schema.ts rename to npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/schema.ts index c4619ed95762..0b29704c97d9 100644 --- a/npm/cypress-schematic/src/schematics/ng-generate/e2e/schema.ts +++ b/npm/cypress-schematic/src/schematics/ng-generate/cypress-ct-tests/schema.ts @@ -1,10 +1,7 @@ export interface Schema { - // The name of the spec. - name: string + // The name of the project. + project?: string // The path to create the spec. path?: string - - // The name of the project. - project?: string } diff --git a/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/index.spec.ts b/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/index.spec.ts new file mode 100644 index 000000000000..4b70527f5e29 --- /dev/null +++ b/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/index.spec.ts @@ -0,0 +1,40 @@ +/// + +import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing' +import { join } from 'path' +import { expect } from 'chai' + +describe('ng-generate @cypress/schematic:spec', () => { + const schematicRunner = new SchematicTestRunner( + 'schematics', + join(__dirname, '../../collection.json'), + ) + let appTree: UnitTestTree + + const workspaceOptions = { + name: 'workspace', + newProjectRoot: 'projects', + version: '12.0.0', + } + + const appOptions: Parameters[2] = { + name: 'sandbox', + inlineTemplate: false, + routing: false, + skipTests: false, + skipPackageJson: false, + } + + beforeEach(async () => { + appTree = await schematicRunner.runExternalSchematicAsync('@schematics/angular', 'workspace', workspaceOptions).toPromise() + appTree = await schematicRunner.runExternalSchematicAsync('@schematics/angular', 'application', appOptions, appTree).toPromise() + }) + + it('should create cypress e2e spec file by default', async () => { + await schematicRunner.runSchematicAsync('spec', { name: 'foo', project: 'sandbox' }, appTree).toPromise().then((tree: UnitTestTree) => expect(tree.files).to.contain('/projects/sandbox/cypress/e2e/foo.cy.ts')) + }) + + it('should create cypress ct spec file when testingType is component', async () => { + await schematicRunner.runSchematicAsync('spec', { name: 'foo', project: 'sandbox', component: true }, appTree).toPromise().then((tree: UnitTestTree) => expect(tree.files).to.contain('/projects/sandbox/src/app/foo.component.cy.ts')) + }) +}) diff --git a/npm/cypress-schematic/src/schematics/ng-generate/e2e/index.ts b/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/index.ts similarity index 71% rename from npm/cypress-schematic/src/schematics/ng-generate/e2e/index.ts rename to npm/cypress-schematic/src/schematics/ng-generate/cypress-test/index.ts index 1a68ad613e73..9a1b22617553 100644 --- a/npm/cypress-schematic/src/schematics/ng-generate/e2e/index.ts +++ b/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/index.ts @@ -1,13 +1,13 @@ import { - Rule, Tree, SchematicsException, - apply, url, applyTemplates, move, - chain, mergeWith, + Rule, Tree, SchematicsException, chain, mergeWith, } from '@angular-devkit/schematics' -import { strings, normalize, virtualFs, workspaces } from '@angular-devkit/core' +import { virtualFs, workspaces } from '@angular-devkit/core' import { Schema } from './schema' +import { createTemplate } from '../../utils' + function createSpec (tree: Tree): workspaces.WorkspaceHost { return { async readFile (path: string): Promise { @@ -35,6 +35,7 @@ export default function (options: Schema): Rule { return async (tree: Tree) => { const host = createSpec(tree) const { workspace } = await workspaces.readWorkspace('/', host) + const testType = options.component ? 'component' : 'e2e' let project @@ -53,17 +54,13 @@ export default function (options: Schema): Rule { } if (options.path === undefined) { - options.path = `${project.root}/cypress/e2e` + options.path = testType === 'component' ? `${project.sourceRoot}/${project.prefix}` : `${project.root}/cypress/e2e` } - const templateSource = apply(url('../files/__path__'), [ - applyTemplates({ - classify: strings.classify, - dasherize: strings.dasherize, - name: options.name, - }), - move(normalize(options.path as string)), - ]) + console.log(`Creating new ${testType} spec named: ${options.name}`) + + const templatePath = testType === 'component' ? '../files/ct/__path__' : '../files/e2e/__path__' + const templateSource = createTemplate({ templatePath, options }) return chain([ mergeWith(templateSource), diff --git a/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/schema.json b/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/schema.json new file mode 100644 index 000000000000..ba3ee4b57031 --- /dev/null +++ b/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/schema.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "cypress-schematics-generate-spec", + "title": "Cypress Generate Spec Options Schema", + "type": "object", + "properties": { + "filename": { + "type": "string", + "description": "Allows users to specify a custom filename.", + "visible": false + }, + "path": { + "type": "string", + "format": "path", + "description": "The path where the spec will be created.", + "visible": false + }, + "project": { + "type": "string", + "description": "The name of the project to create the spec in.", + "alias": "p", + "$default": { + "$source": "projectName" + } + }, + "name": { + "type": "string", + "description": "The name of the spec.", + "alias": "n", + "$default": { + "$source": "argv", + "index": 0 + }, + "x-prompt": "What should the spec be named?" + }, + "component": { + "type": "boolean", + "alias": "c", + "default": false, + "description": "When true, the spec created will be a component spec." + } + }, + "required": [ + "name" + ] +} \ No newline at end of file diff --git a/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/schema.ts b/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/schema.ts new file mode 100644 index 000000000000..f73ef2797808 --- /dev/null +++ b/npm/cypress-schematic/src/schematics/ng-generate/cypress-test/schema.ts @@ -0,0 +1,16 @@ +export interface Schema { + // Custom filename. + filename?: string + + // The name of the spec. + name: string + + // The path to create the spec. + path?: string + + // The name of the project. + project?: string + + // Create a component spec + component?: boolean +} diff --git a/npm/cypress-schematic/src/schematics/ng-generate/files/ct/__path__/__fileName@dasherize__.component.cy.ts.template b/npm/cypress-schematic/src/schematics/ng-generate/files/ct/__path__/__fileName@dasherize__.component.cy.ts.template new file mode 100644 index 000000000000..e11eaf5d13cd --- /dev/null +++ b/npm/cypress-schematic/src/schematics/ng-generate/files/ct/__path__/__fileName@dasherize__.component.cy.ts.template @@ -0,0 +1,7 @@ +import { <%= classify(name) %> } from './<%= fileName %>.component' + +describe('<%= classify(name) %>', () => { + it('should mount', () => { + cy.mount(<%= classify(name) %>) + }) +}) \ No newline at end of file diff --git a/npm/cypress-schematic/src/schematics/ng-generate/files/__path__/__name@dasherize__.cy.ts.template b/npm/cypress-schematic/src/schematics/ng-generate/files/e2e/__path__/__name@dasherize__.cy.ts.template similarity index 100% rename from npm/cypress-schematic/src/schematics/ng-generate/files/__path__/__name@dasherize__.cy.ts.template rename to npm/cypress-schematic/src/schematics/ng-generate/files/e2e/__path__/__name@dasherize__.cy.ts.template diff --git a/npm/cypress-schematic/src/schematics/utils/dependencies.ts b/npm/cypress-schematic/src/schematics/utils/dependencies.ts index 80302968237b..ab80589ecd85 100644 --- a/npm/cypress-schematic/src/schematics/utils/dependencies.ts +++ b/npm/cypress-schematic/src/schematics/utils/dependencies.ts @@ -4,7 +4,7 @@ * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license - * https://github.com/angular/angular-cli/blob/master/packages/schematics/angular/utility/dependencies.ts + * https://github.com/angular/angular-cli/blob/master/packages/schematics/angular/utils/dependencies.ts */ import { Tree } from '@angular-devkit/schematics' diff --git a/npm/cypress-schematic/src/schematics/utils/index.ts b/npm/cypress-schematic/src/schematics/utils/index.ts index a1ddc2baec32..ef78888d6e33 100644 --- a/npm/cypress-schematic/src/schematics/utils/index.ts +++ b/npm/cypress-schematic/src/schematics/utils/index.ts @@ -1,7 +1,12 @@ -import { Tree } from '@angular-devkit/schematics' +import { readdirSync } from 'fs' +import { resolve } from 'path' +import { getSystemPath, normalize, strings } from '@angular-devkit/core' +import { Tree, apply, url, applyTemplates, move, Rule } from '@angular-devkit/schematics' import { get } from 'http' +import { Schema } from '../ng-generate/cypress-test/schema' import { getPackageJsonDependency } from './dependencies' +import { JSONFile } from './jsonFile' export interface NodePackage { name: string @@ -46,3 +51,68 @@ export function getLatestNodeVersion (packageName: string): Promise return { name, version } } } + +const ctSpecContent = ({ componentName, componentFilename }: {componentName: string, componentFilename: string}): string => { + return `import { ${componentName} } from './${componentFilename}.component'\n + describe('${componentName}', () => { + it('should mount', () => { + cy.mount(${componentName}) + }) + }) + ` +} + +function generateCTSpec ({ tree, appPath, component }: { tree: Tree, appPath: string, component: any}): Rule | void { + const buffer = tree.read(`${appPath}/${component['name']}`) + const componentString = buffer?.toString() + const componentMatch = componentString?.match(/(?<=class )\S+/g) + const componentFilename = component['name'].split('.')[0] + const componentName = componentMatch ? componentMatch[0] : componentFilename + + console.log(`Creating new component spec for: ${componentName}\n`) + + return tree.create(`${appPath}/${componentFilename}.component.cy.ts`, ctSpecContent({ componentName, componentFilename })) +} + +export function getDirectoriesAndCreateSpecs ({ appPath, tree }: { appPath: string, tree: Tree}) { + let components = [] + let directories = [] + + const projectPath = resolve(getSystemPath(normalize(''))) + const contents = readdirSync(resolve(`${projectPath}/${appPath}`), { withFileTypes: true }) + + if (contents) { + components = contents.filter((file) => file['name'].endsWith(`component.ts`)) + directories = contents.filter((file) => file.isDirectory()) + + if (components) { + components.map((component) => { + return generateCTSpec({ tree, appPath, component }) + }) + } + + if (directories) { + directories.forEach((directory: any) => { + return getDirectoriesAndCreateSpecs({ tree, appPath: `${appPath}/${directory['name']}` }) + }) + } + } +} + +export function createTemplate ({ templatePath, options }: {templatePath: string, options: Schema}): any { + return apply(url(templatePath), [ + applyTemplates({ + classify: strings.classify, + dasherize: strings.dasherize, + name: options.component ? `${options.name}Component` : options.name, + fileName: options.filename || options.name, + }), + move(normalize(options.path as string)), + ]) +} + +export function getAngularJsonValue (tree: Tree) { + const angularJson = new JSONFile(tree, './angular.json') + + return angularJson.get([]) as any +} diff --git a/npm/cypress-schematic/tsconfig.json b/npm/cypress-schematic/tsconfig.json index e9f13bb37a57..798d992aa8ec 100644 --- a/npm/cypress-schematic/tsconfig.json +++ b/npm/cypress-schematic/tsconfig.json @@ -27,5 +27,5 @@ "include": [ "src/**/*" ], - "exclude": ["src/**/files/**/*", "src/**/*.spec.ts"] + "exclude": ["src/**/files-core/**/*", "src/**/files-ct/**/*", "src/**/*.spec.ts"] } From e80e7781db74cd64585ed263ed5c5186b2fd6dda Mon Sep 17 00:00:00 2001 From: Zach Bloomquist Date: Thu, 25 Aug 2022 19:17:33 -0400 Subject: [PATCH 32/45] chore(percy): add percy context to finalize job (#23558) --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index af705010732c..ab2f0f861215 100644 --- a/circle.yml +++ b/circle.yml @@ -2320,7 +2320,7 @@ linux-x64-workflow: &linux-x64-workflow requires: - build - percy-finalize: - context: test-runner:poll-circle-workflow + context: [test-runner:poll-circle-workflow, test-runner:percy] required_env_var: PERCY_TOKEN # skips job if not defined (external PR) requires: - build From 9ba71c60931d8e6f993740dd027771a95ac5ca55 Mon Sep 17 00:00:00 2001 From: Emily Rohrbough Date: Fri, 26 Aug 2022 12:22:50 -0500 Subject: [PATCH 33/45] perf(cy.session): keep page state after validation runs (#23503) --- .../app/cypress/e2e/runner/sessions.ui.cy.ts | 4 +- .../cypress/e2e/commands/navigation.cy.js | 357 +++++++++++++----- .../e2e/commands/sessions/sessions.cy.js | 92 +++-- .../e2e/e2e/origin/commands/navigation.cy.ts | 4 +- packages/driver/src/cy/commands/navigation.ts | 8 +- .../driver/src/cy/commands/sessions/index.ts | 3 +- .../projects/e2e/cypress/e2e/session.cy.js | 4 +- 7 files changed, 319 insertions(+), 153 deletions(-) diff --git a/packages/app/cypress/e2e/runner/sessions.ui.cy.ts b/packages/app/cypress/e2e/runner/sessions.ui.cy.ts index a50a8d6486b4..d3205b09b061 100644 --- a/packages/app/cypress/e2e/runner/sessions.ui.cy.ts +++ b/packages/app/cypress/e2e/runner/sessions.ui.cy.ts @@ -160,7 +160,7 @@ describe('runner/cypress sessions.ui.spec', { cy.contains('user1') cy.contains('restored') - cy.get('.command-name-Clear-page').should('have.length', 2) + cy.get('.command-name-Clear-page').should('have.length', 1) cy.contains('Restore saved session') @@ -231,7 +231,7 @@ describe('runner/cypress sessions.ui.spec', { .find('.command-expander') .should('have.class', 'command-expander-is-open') - cy.get('.command-name-Clear-page').should('have.length', 3) + cy.get('.command-name-Clear-page').should('have.length', 2) validateSetupSessionGroup(false) diff --git a/packages/driver/cypress/e2e/commands/navigation.cy.js b/packages/driver/cypress/e2e/commands/navigation.cy.js index fdcd033a66dc..faad870f5413 100644 --- a/packages/driver/cypress/e2e/commands/navigation.cy.js +++ b/packages/driver/cypress/e2e/commands/navigation.cy.js @@ -89,8 +89,8 @@ describe('src/cy/commands/navigation', () => { cy.on('window:unload', stub3) cy.reload().then(() => { - expect(stub1.firstCall).to.be.calledWith(false, 'beforeunload') - expect(stub1.secondCall).to.be.calledWith(true, 'load') + expect(stub1.getCall(0)).to.be.calledWith(false, 'beforeunload') + expect(stub1.getCall(1)).to.be.calledWith(true, 'load') expect(stub2).to.be.calledOnce expect(stub3).to.be.calledOnce }) @@ -301,17 +301,17 @@ describe('src/cy/commands/navigation', () => { cy.go('back') }) .then(function () { - expect(emit.firstCall).to.be.calledWith( + expect(emit.getCall(0)).to.be.calledWith( 'url:changed', 'http://localhost:3500/fixtures/generic.html', ) - expect(emit.secondCall).to.be.calledWith( + expect(emit.getCall(1)).to.be.calledWith( 'url:changed', 'http://localhost:3500/fixtures/generic.html#hashchange', ) - expect(emit.thirdCall).to.be.calledWith( + expect(emit.getCall(2)).to.be.calledWith( 'url:changed', 'http://localhost:3500/fixtures/generic.html', ) @@ -377,8 +377,8 @@ describe('src/cy/commands/navigation', () => { cy.on('window:unload', stub3) }) .go('back').then(() => { - expect(stub1.firstCall).to.be.calledWith(false, 'beforeunload') - expect(stub1.secondCall).to.be.calledWith(true, 'load') + expect(stub1.getCall(0)).to.be.calledWith(false, 'beforeunload') + expect(stub1.getCall(1)).to.be.calledWith(true, 'load') expect(stub2).to.be.calledOnce expect(stub3).to.be.calledOnce }) @@ -581,18 +581,35 @@ describe('src/cy/commands/navigation', () => { }) }) - it('removes window:load listeners', () => { - const listeners = cy.listeners('window:load') + describe('removes window:load listeners when testIsolation=legacy', { testIsolation: 'legacy' }, () => { + it('removes 2x for about:blank and first url visit', () => { + const listeners = cy.listeners('window:load') - const winLoad = cy.spy(cy, 'once').withArgs('window:load') + const winLoad = cy.spy(cy, 'once').withArgs('window:load') - cy.visit('/fixtures/generic.html').then(() => { - // once for about:blank, once for $iframe src - expect(winLoad).to.be.calledTwice - expect(cy.listeners('window:load')).to.deep.eq(listeners) + cy.visit('/fixtures/generic.html').then(() => { + // once for about:blank, once for $iframe src + expect(winLoad).to.be.calledTwice + expect(cy.listeners('window:load')).to.deep.eq(listeners) + }) }) }) + if (Cypress.config('experimentalSessionAndOrigin')) { + describe('removes window:load listeners when testIsolation=strict', () => { + it('removes for first url visit', () => { + const listeners = cy.listeners('window:load') + + const winLoad = cy.spy(cy, 'once').withArgs('window:load') + + cy.visit('/fixtures/generic.html').then(() => { + expect(winLoad).to.be.calledOnce + expect(cy.listeners('window:load')).to.deep.eq(listeners) + }) + }) + }) + } + it('can visit pages on the same originPolicy', () => { cy .visit('http://localhost:3500/fixtures/jquery.html') @@ -748,7 +765,7 @@ describe('src/cy/commands/navigation', () => { cy.get('div').should('contain', 'this should fail?') }) - describe('when only hashes are changing', () => { + describe('when only hashes are changing when testIsolation=legacy', { testIsolation: 'legacy' }, () => { it('short circuits the visit if the page will not refresh', () => { let count = 0 const urls = [] @@ -786,6 +803,44 @@ describe('src/cy/commands/navigation', () => { }) }) + if (Cypress.config('experimentalSessionAndOrigin')) { + describe('when only hashes are changing when testIsolation=strict', () => { + it('short circuits the visit if the page will not refresh', () => { + let count = 0 + const urls = [] + + cy.on('window:load', () => { + urls.push(cy.state('window').location.href) + + count += 1 + }) + + cy + .visit('/fixtures/generic.html?foo#bar') // yes (1) + .visit('/fixtures/generic.html?foo#foo') // no (1) + .visit('/fixtures/generic.html?bar#bar') // yes (2) + .visit('/fixtures/dimensions.html?bar#bar') // yes (3) + .visit('/fixtures/dimensions.html?baz#bar') // yes (4) + .visit('/fixtures/dimensions.html#bar') // yes (5) + .visit('/fixtures/dimensions.html') // yes (6) + .visit('/fixtures/dimensions.html#baz') // no (6) + .visit('/fixtures/dimensions.html#') // no (6) + .then(() => { + expect(count).to.eq(6) + + expect(urls).to.deep.eq([ + 'http://localhost:3500/fixtures/generic.html?foo#bar', + 'http://localhost:3500/fixtures/generic.html?bar#bar', + 'http://localhost:3500/fixtures/dimensions.html?bar#bar', + 'http://localhost:3500/fixtures/dimensions.html?baz#bar', + 'http://localhost:3500/fixtures/dimensions.html#bar', + 'http://localhost:3500/fixtures/dimensions.html', + ]) + }) + }) + }) + } + // https://github.com/cypress-io/cypress/issues/1311 // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23201 it.skip('window immediately resolves and doesn\'t reload when visiting the same URL with hashes', () => { @@ -2232,12 +2287,12 @@ describe('src/cy/commands/navigation', () => { .visit('/timeout?ms=10', { onBeforeLoad () { expect(emit).to.be.calledOnce - expect(emit.firstCall).to.be.calledWith('page:loading', true) + expect(emit.getCall(0)).to.be.calledWith('page:loading', true) }, }) .then(() => { expect(emit).to.be.calledTwice - expect(emit.secondCall).to.be.calledWith('page:loading', false) + expect(emit.getCall(1)).to.be.calledWith('page:loading', false) }) }) @@ -2251,7 +2306,7 @@ describe('src/cy/commands/navigation', () => { cy.once('window:unload', () => { expected = true expect(emit.callCount).to.eq(3) - expect(emit.thirdCall).to.be.calledWith('page:loading', true) + expect(emit.getCall(2)).to.be.calledWith('page:loading', true) }) }).get('#dimensions').click() .then(() => { @@ -2517,17 +2572,17 @@ describe('src/cy/commands/navigation', () => { }).then(() => { expect(emit.callCount).to.eq(4) - expect(emit.firstCall).to.be.calledWith( + expect(emit.getCall(0)).to.be.calledWith( 'url:changed', 'http://localhost:3500/fixtures/generic.html', ) - expect(emit.secondCall).to.be.calledWith( + expect(emit.getCall(1)).to.be.calledWith( 'url:changed', 'http://localhost:3500/fixtures/generic.html#hashchange', ) - expect(emit.thirdCall).to.be.calledWith( + expect(emit.getCall(2)).to.be.calledWith( 'url:changed', 'http://localhost:3500/fixtures/generic.html', ) @@ -2540,104 +2595,204 @@ describe('src/cy/commands/navigation', () => { }) }) - // https://github.com/cypress-io/cypress/issues/19230 - it('filters page load events when going back with window navigation', () => { - const emit = cy.spy(Cypress, 'emit').log(false).withArgs('navigation:changed') - - cy - .visit('/fixtures/generic.html') - .get('#hashchange').click() - .window().then((win) => { - return new Promise((resolve) => { - cy.once('navigation:changed', resolve) + describe('filters page load events when going back with window navigation when testIsolation=legacy', { testIsolation: 'legacy' }, () => { + // https://github.com/cypress-io/cypress/issues/19230 + it('when going back with window navigation', () => { + const emit = cy.spy(Cypress, 'emit').log(false).withArgs('navigation:changed') - win.history.back() - }).then(() => { + cy + .visit('/fixtures/generic.html') + .get('#hashchange').click() + .window().then((win) => { return new Promise((resolve) => { cy.once('navigation:changed', resolve) - win.history.forward() - }) - }) - }) + win.history.back() + }).then(() => { + return new Promise((resolve) => { + cy.once('navigation:changed', resolve) - cy.get('#dimensions').click() - .window().then((win) => { - return new Promise((resolve) => { - cy.on('navigation:changed', (event) => { - if (event.includes('(load)')) { - resolve() - } + win.history.forward() + }) }) - - win.history.back() }) - .then(() => { + + cy.get('#dimensions').click() + .window().then((win) => { return new Promise((resolve) => { - cy.on('navigation:changed', resolve) + cy.on('navigation:changed', (event) => { + if (event.includes('(load)')) { + resolve() + } + }) + win.history.back() }) + .then(() => { + return new Promise((resolve) => { + cy.on('navigation:changed', resolve) + win.history.back() + }) + }) + .then(() => { + expect(emit.getCall(0)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (load)', + ) + + expect(emit.getCall(1)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (before:load)', + ) + + expect(emit.getCall(2)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (load)', + ) + + expect(emit.getCall(3)).to.be.calledWithMatch( + 'navigation:changed', + 'hashchange', + ) + + expect(emit.getCall(4)).to.be.calledWithMatch( + 'navigation:changed', + 'hashchange', + ) + + expect(emit.getCall(5)).to.be.calledWithMatch( + 'navigation:changed', + 'hashchange', + ) + + expect(emit.getCall(6)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (before:load)', + ) + + expect(emit.getCall(7)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (load)', + ) + + expect(emit.getCall(8)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (before:load)', + ) + + expect(emit.getCall(9)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (load)', + ) + + expect(emit.getCall(10)).to.be.calledWithMatch( + 'navigation:changed', + 'hashchange', + ) + + expect(emit.callCount).to.eq(11) + }) }) - .then(() => { - expect(emit.firstCall).to.be.calledWith( - 'navigation:changed', - 'page navigation event (load)', - ) - - expect(emit.secondCall).to.be.calledWith( - 'navigation:changed', - 'page navigation event (before:load)', - ) - - expect(emit.thirdCall).to.be.calledWith( - 'navigation:changed', - 'page navigation event (load)', - ) - - expect(emit.getCall(3)).to.be.calledWithMatch( - 'navigation:changed', - 'hashchange', - ) - - expect(emit.getCall(4)).to.be.calledWithMatch( - 'navigation:changed', - 'hashchange', - ) - - expect(emit.getCall(5)).to.be.calledWithMatch( - 'navigation:changed', - 'hashchange', - ) - - expect(emit.getCall(6)).to.be.calledWith( - 'navigation:changed', - 'page navigation event (before:load)', - ) + }) + }) - expect(emit.getCall(7)).to.be.calledWith( - 'navigation:changed', - 'page navigation event (load)', - ) + if (Cypress.config('experimentalSessionAndOrigin')) { + describe('filters page load events when going back with window navigation when testIsolation=strict', () => { + // https://github.com/cypress-io/cypress/issues/19230 + it('when going back with window navigation', () => { + const emit = cy.spy(Cypress, 'emit').log(false).withArgs('navigation:changed') - expect(emit.getCall(8)).to.be.calledWith( - 'navigation:changed', - 'page navigation event (before:load)', - ) + cy + .visit('/fixtures/generic.html') + .get('#hashchange').click() + .window().then((win) => { + return new Promise((resolve) => { + cy.once('navigation:changed', resolve) - expect(emit.getCall(9)).to.be.calledWith( - 'navigation:changed', - 'page navigation event (load)', - ) + win.history.back() + }).then(() => { + return new Promise((resolve) => { + cy.once('navigation:changed', resolve) - expect(emit.getCall(10)).to.be.calledWithMatch( - 'navigation:changed', - 'hashchange', - ) + win.history.forward() + }) + }) + }) - expect(emit.callCount).to.eq(11) + cy.get('#dimensions').click() + .window().then((win) => { + return new Promise((resolve) => { + cy.on('navigation:changed', (event) => { + if (event.includes('(load)')) { + resolve() + } + }) + + win.history.back() + }) + .then(() => { + return new Promise((resolve) => { + cy.on('navigation:changed', resolve) + win.history.back() + }) + }) + .then(() => { + expect(emit.getCall(0)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (before:load)', + ) + + expect(emit.getCall(1)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (load)', + ) + + expect(emit.getCall(2)).to.be.calledWith( + 'navigation:changed', + 'hashchange', + ) + + expect(emit.getCall(3)).to.be.calledWithMatch( + 'navigation:changed', + 'hashchange', + ) + + expect(emit.getCall(4)).to.be.calledWithMatch( + 'navigation:changed', + 'hashchange', + ) + + expect(emit.getCall(5)).to.be.calledWithMatch( + 'navigation:changed', + 'page navigation event (before:load)', + ) + + expect(emit.getCall(6)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (load)', + ) + + expect(emit.getCall(7)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (before:load)', + ) + + expect(emit.getCall(8)).to.be.calledWith( + 'navigation:changed', + 'page navigation event (load)', + ) + + expect(emit.getCall(9)).to.be.calledWith( + 'navigation:changed', + 'hashchange', + ) + + expect(emit.callCount).to.eq(10) + }) + }) }) }) - }) + } it('logs url changed event', () => { cy diff --git a/packages/driver/cypress/e2e/commands/sessions/sessions.cy.js b/packages/driver/cypress/e2e/commands/sessions/sessions.cy.js index ca5efc02f683..d6699a770563 100644 --- a/packages/driver/cypress/e2e/commands/sessions/sessions.cy.js +++ b/packages/driver/cypress/e2e/commands/sessions/sessions.cy.js @@ -100,18 +100,29 @@ describe('cy.session', { retries: 0 }, () => { let validate const handleSetup = () => { - cy.then(() => { - expect(clearPageCount, 'cleared page before executing session setup').to.eq(1) + // create session clears page before running + cy.contains('Default blank page') + cy.contains('This page was cleared by navigating to about:blank.') + + cy.visit('/fixtures/auth/index.html') + cy.contains('You are not logged in') + cy.window().then((win) => { + win.sessionStorage.setItem('cypressAuthToken', JSON.stringify({ body: { username: 'tester' } })) }) + } + + const handleValidate = () => { + // both create & restore session clears page after running + cy.contains('Default blank page') + cy.contains('This page was cleared by navigating to about:blank.') - cy.contains('This is a blank page') - cy.contains('We always navigate you here after') - cy.contains('cy.session(...)') + cy.visit('/fixtures/auth/index.html') + cy.contains('Welcome tester') } before(() => { setup = cy.stub().callsFake(handleSetup).as('setupSession') - validate = cy.stub().as('validateSession') + validate = cy.stub().callsFake(handleValidate).as('validateSession') }) const resetMocks = () => { @@ -119,7 +130,9 @@ describe('cy.session', { retries: 0 }, () => { clearPageCount = 0 sessionGroupId = undefined setup.reset() + setup.callsFake(handleSetup) validate.reset() + validate.callsFake(handleValidate) } const setupTestContext = () => { @@ -159,14 +172,18 @@ describe('cy.session', { retries: 0 }, () => { before(() => { setupTestContext() cy.log('Creating new session to test against') + expect(clearPageCount, 'total times session cleared the page').to.eq(0) cy.session('session-1', setup) + }) + + // test must be first to run before blank page visit between each test + it('clears page after setup runs', () => { cy.url().should('eq', 'about:blank') }) it('successfully creates new session', () => { expect(setup).to.be.calledOnce - // FIXME: currently page is cleared 3 times when it should clear 2 times - expect(clearPageCount, 'total times session cleared the page').to.eq(3) + expect(clearPageCount, 'total times session cleared the page').to.eq(2) }) it('groups session logs correctly', () => { @@ -205,11 +222,6 @@ describe('cy.session', { retries: 0 }, () => { name: 'Clear page', group: createNewSessionGroup.id, }) - - expect(logs[6].get()).to.contain({ - name: 'Clear page', - group: sessionGroupId, - }) }) it('creates new session instrument with session details', () => { @@ -238,14 +250,17 @@ describe('cy.session', { retries: 0 }, () => { cy.log('Creating new session with validation to test against') cy.session(`session-${Cypress.state('test').id}`, setup, { validate }) - cy.url().should('eq', 'about:blank') + }) + + // test must be first to run before blank page visit between each test + it('does not clear page visit from validate function', () => { + cy.url().should('contain', '/fixtures/auth/index.html') }) it('successfully creates new session and validates it', () => { expect(setup).to.be.calledOnce expect(validate).to.be.calledOnce - // FIXME: currently page is cleared 3 times when it should clear twice - expect(clearPageCount, 'total times session cleared the page').to.eq(3) + expect(clearPageCount, 'total times session cleared the page').to.eq(2) }) it('groups session logs correctly', () => { @@ -296,11 +311,6 @@ describe('cy.session', { retries: 0 }, () => { alias: ['validateSession'], group: validateSessionGroup.id, }) - - expect(logs[8].get()).to.contain({ - name: 'Clear page', - group: sessionGroupId, - }) }) }) @@ -383,13 +393,17 @@ describe('cy.session', { retries: 0 }, () => { cy.log('restore session to test against') cy.session(`session-${Cypress.state('test').id}`, setup) + }) + + // test must be first to run before blank page visit between each test + it('clears page after setup runs', () => { cy.url().should('eq', 'about:blank') }) it('successfully restores saved session', () => { expect(setup).to.not.be.called expect(validate).to.not.be.called - expect(clearPageCount, 'total times session cleared the page').to.eq(2) + expect(clearPageCount, 'total times session cleared the page').to.eq(1) }) it('groups session logs correctly', () => { @@ -422,11 +436,6 @@ describe('cy.session', { retries: 0 }, () => { displayName: 'Restore saved session', group: sessionGroupId, }) - - expect(logs[4].get()).to.contain({ - name: 'Clear page', - group: sessionGroupId, - }) }) }) @@ -442,13 +451,17 @@ describe('cy.session', { retries: 0 }, () => { cy.log('restore session to test against') cy.session(`session-${Cypress.state('test').id}`, setup, { validate }) - cy.url().should('eq', 'about:blank') + }) + + // test must be first to run before blank page visit between each test + it('does not clear page visit from validate function', () => { + cy.url().should('contain', '/fixtures/auth/index.html') }) it('successfully restores saved session', () => { expect(setup).to.not.be.called expect(validate).to.be.calledOnce - expect(clearPageCount, 'total times session cleared the page').to.eq(2) + expect(clearPageCount, 'total times session cleared the page').to.eq(1) }) it('groups session logs correctly', () => { @@ -493,11 +506,6 @@ describe('cy.session', { retries: 0 }, () => { alias: ['validateSession'], group: validateSessionGroup.id, }) - - expect(logs[6].get()).to.contain({ - name: 'Clear page', - group: sessionGroupId, - }) }) }) @@ -505,6 +513,7 @@ describe('cy.session', { retries: 0 }, () => { before(() => { setupTestContext() cy.log('Creating new session for test') + cy.session(`session-${Cypress.state('test').id}`, setup, { validate }) .then(() => { // reset and only test restored session @@ -513,18 +522,24 @@ describe('cy.session', { retries: 0 }, () => { if (validate.callCount === 1) { return false } + + handleValidate() }) }) cy.log('restore session to test against') cy.session(`session-${Cypress.state('test').id}`, setup, { validate }) - cy.url().should('eq', 'about:blank') + }) + + // test must be first to run before blank page visit between each test + it('does not clear page visit from validate function', () => { + cy.url().should('contain', '/fixtures/auth/index.html') }) it('successfully recreates session', () => { expect(setup).to.be.calledOnce expect(validate).to.be.calledTwice - expect(clearPageCount, 'total times session cleared the page').to.eq(4) + expect(clearPageCount, 'total times session cleared the page').to.eq(3) }) it('groups session logs correctly', () => { @@ -616,11 +631,6 @@ describe('cy.session', { retries: 0 }, () => { alias: ['validateSession'], group: secondValidateSessionGroup.id, }) - - expect(logs[14].get()).to.contain({ - name: 'Clear page', - group: sessionGroupId, - }) }) }) diff --git a/packages/driver/cypress/e2e/e2e/origin/commands/navigation.cy.ts b/packages/driver/cypress/e2e/e2e/origin/commands/navigation.cy.ts index 267a5b93f664..94ba040383ee 100644 --- a/packages/driver/cypress/e2e/e2e/origin/commands/navigation.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/commands/navigation.cy.ts @@ -52,7 +52,7 @@ context('cy.origin navigation', () => { onLoad: primaryVisitLoadSpy, }).then(() => { expect(primaryCyBeforeLoadSpy).to.be.calledOnce - expect(primaryCyLoadSpy).to.be.calledTwice // twice because it's also called for 'about:blank' + expect(primaryCyLoadSpy).to.be.calledOnce expect(primaryVisitBeforeLoadSpy).to.be.calledOnce expect(primaryVisitLoadSpy).to.be.calledOnce }) @@ -77,7 +77,7 @@ context('cy.origin navigation', () => { }) }).then(() => { expect(primaryCyBeforeLoadSpy).to.be.calledOnce - expect(primaryCyLoadSpy).to.be.calledTwice + expect(primaryCyLoadSpy).to.be.calledOnce expect(primaryVisitBeforeLoadSpy).to.be.calledOnce expect(primaryVisitLoadSpy).to.be.calledOnce }) diff --git a/packages/driver/src/cy/commands/navigation.ts b/packages/driver/src/cy/commands/navigation.ts index 22744a08809c..feaf4cb4c8e3 100644 --- a/packages/driver/src/cy/commands/navigation.ts +++ b/packages/driver/src/cy/commands/navigation.ts @@ -32,9 +32,11 @@ const reset = (test: any = {}) => { // before each test run! previouslyVisitedLocation = undefined - // make sure we reset that we haven't - // visited about blank again - hasVisitedAboutBlank = false + const { experimentalSessionAndOrigin, testIsolation } = Cypress.config() + + // make sure we reset that we haven't visited about blank again + // strict test isolation resets the navigation history for us. + hasVisitedAboutBlank = experimentalSessionAndOrigin && testIsolation === 'strict' currentlyVisitingAboutBlank = false diff --git a/packages/driver/src/cy/commands/sessions/index.ts b/packages/driver/src/cy/commands/sessions/index.ts index 196113b136ca..17ecd772a5b7 100644 --- a/packages/driver/src/cy/commands/sessions/index.ts +++ b/packages/driver/src/cy/commands/sessions/index.ts @@ -365,8 +365,7 @@ export default function (Commands, Cypress, cy) { } return restoreSessionWorkflow(existingSession) - }).then(async () => { - await navigateAboutBlank() + }).then(() => { _log.set({ state: 'passed' }) }) }) diff --git a/system-tests/projects/e2e/cypress/e2e/session.cy.js b/system-tests/projects/e2e/cypress/e2e/session.cy.js index 257e2250e5cf..bacb911a4f16 100644 --- a/system-tests/projects/e2e/cypress/e2e/session.cy.js +++ b/system-tests/projects/e2e/cypress/e2e/session.cy.js @@ -370,7 +370,7 @@ function SuiteWithValidateFn (id, fn) { expect(validate).calledOnce // (1,2) about:blank before & after session creation // (3) after validate runs - expect(numPageLoads, 'number of page loads').eq(3) + expect(numPageLoads, 'number of page loads').eq(2) }) it('t2', () => { @@ -380,7 +380,7 @@ function SuiteWithValidateFn (id, fn) { // (4) about:blank before session rehydrating // (5,6) about:blank before & after setup function // (7) about:blank after 2nd validate runs - expect(numPageLoads, 'number of page loads').eq(7) + expect(numPageLoads, 'number of page loads').eq(5) }) } From 8d2702f9bd6381b4843fcb6b3ac0f1454cf8baea Mon Sep 17 00:00:00 2001 From: Zachary Williams Date: Fri, 26 Aug 2022 12:35:27 -0500 Subject: [PATCH 34/45] chore: remove react parallelism (#23570) --- circle.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/circle.yml b/circle.yml index ab2f0f861215..45fb1019c602 100644 --- a/circle.yml +++ b/circle.yml @@ -1831,7 +1831,6 @@ jobs: npm-react: <<: *defaults - parallelism: 8 steps: - restore_cached_workspace - run: From f6eaad40e1836fa9db87c60defa5ae6f390c8fd8 Mon Sep 17 00:00:00 2001 From: Zachary Williams Date: Fri, 26 Aug 2022 12:36:05 -0500 Subject: [PATCH 35/45] feat: adding svelte component testing support (#23553) Co-authored-by: Jessica Sachs Co-authored-by: Rocky <25568640+rockindahizzy@users.noreply.github.com> --- cli/.gitignore | 3 +- cli/package.json | 8 +- cli/scripts/post-build.js | 1 + cli/types/cypress.d.ts | 4 +- npm/angular/package.json | 5 +- npm/angular/rollup.config.js | 61 - npm/angular/rollup.config.mjs | 14 + npm/mount-utils/create-rollup-entry.mjs | 71 + npm/mount-utils/package.json | 4 + npm/react/package.json | 6 +- npm/react/rollup.config.js | 74 - npm/react/rollup.config.mjs | 18 + npm/react18/package.json | 2 +- npm/react18/rollup.config.js | 3 - npm/react18/rollup.config.mjs | 3 + npm/svelte/.eslintrc | 17 + npm/svelte/.npmrc | 3 + npm/svelte/.releaserc.js | 7 + npm/svelte/CHANGELOG.md | 0 npm/svelte/README.md | 83 + npm/svelte/package.json | 43 + npm/svelte/rollup.config.mjs | 3 + npm/svelte/src/index.ts | 1 + npm/svelte/src/mount.ts | 100 + npm/svelte/tsconfig.json | 22 + npm/vue/package.json | 7 +- npm/vue/rollup.config.js | 75 - npm/vue/rollup.config.mjs | 14 + npm/vue2/package.json | 5 +- npm/vue2/rollup.config.js | 93 - npm/vue2/rollup.config.mjs | 28 + npm/webpack-dev-server/src/devServer.ts | 1 + .../helpers/sourceRelativeWebpackModules.ts | 1 + package.json | 4 +- packages/graphql/schemas/schema.graphql | 1 + .../e2e/scaffold-component-testing.cy.ts | 26 + .../launchpad/src/images/logos/svelte.svg | 1 + packages/launchpad/src/utils/icons.ts | 2 + packages/scaffold-config/src/dependencies.ts | 10 + packages/scaffold-config/src/frameworks.ts | 19 + .../scaffold-config/test/unit/detect.spec.ts | 30 + .../test/unit/supportFile.spec.ts | 82 + .../cypress/support/component-index.html | 14 + .../svelte/cypress/support/component.js | 4 + .../project-fixtures/svelte/src/App.cy.js | 10 + .../project-fixtures/svelte/src/App.svelte | 14 + .../svelte/src/Context.svelte | 7 + .../svelte/src/Counter.svelte | 20 + .../project-fixtures/svelte/src/Store.svelte | 19 + .../project-fixtures/svelte/src/main.js | 8 + .../project-fixtures/svelte/src/mount.cy.js | 56 + .../project-fixtures/svelte/src/store.js | 3 + .../project-fixtures/svelte/src/styles.css | 3 + .../svelte-vite-unconfigured/index.html | 13 + .../svelte-vite-unconfigured/jsconfig.json | 21 + .../svelte-vite-unconfigured/package.json | 16 + .../svelte-vite-unconfigured/public/vite.svg | 1 + .../svelte-vite-unconfigured/src/App.svelte | 45 + .../svelte-vite-unconfigured/src/app.css | 81 + .../src/assets/svelte.svg | 1 + .../src/lib/Counter.svelte | 10 + .../svelte-vite-unconfigured/src/main.js | 8 + .../src/vite-env.d.ts | 2 + .../svelte-vite-unconfigured/vite.config.js | 7 + .../svelte-vite-unconfigured/yarn.lock | 295 ++ .../projects/svelte-vite/cypress.config.js | 10 + .../projects/svelte-vite/package.json | 12 + .../projects/svelte-vite/vite.config.js | 7 + system-tests/projects/svelte-vite/yarn.lock | 295 ++ .../svelte-webpack-unconfigured/package.json | 18 + .../public/favicon.png | Bin 0 -> 3127 bytes .../public/index.html | 17 + .../scripts/setupTypeScript.js | 210 ++ .../src/App.svelte | 30 + .../src/global.css | 63 + .../svelte-webpack-unconfigured/src/main.js | 12 + .../webpack.config.js | 64 + .../svelte-webpack-unconfigured/yarn.lock | 3304 +++++++++++++++++ .../projects/svelte-webpack/cypress.config.js | 10 + .../projects/svelte-webpack/package.json | 15 + .../projects/svelte-webpack/webpack.config.js | 39 + .../projects/svelte-webpack/yarn.lock | 2225 +++++++++++ system-tests/test/component_testing_spec.ts | 14 + yarn.lock | 51 +- 84 files changed, 7636 insertions(+), 373 deletions(-) delete mode 100644 npm/angular/rollup.config.js create mode 100644 npm/angular/rollup.config.mjs create mode 100644 npm/mount-utils/create-rollup-entry.mjs delete mode 100644 npm/react/rollup.config.js create mode 100644 npm/react/rollup.config.mjs delete mode 100644 npm/react18/rollup.config.js create mode 100644 npm/react18/rollup.config.mjs create mode 100644 npm/svelte/.eslintrc create mode 100644 npm/svelte/.npmrc create mode 100644 npm/svelte/.releaserc.js create mode 100644 npm/svelte/CHANGELOG.md create mode 100644 npm/svelte/README.md create mode 100644 npm/svelte/package.json create mode 100644 npm/svelte/rollup.config.mjs create mode 100644 npm/svelte/src/index.ts create mode 100644 npm/svelte/src/mount.ts create mode 100644 npm/svelte/tsconfig.json delete mode 100644 npm/vue/rollup.config.js create mode 100644 npm/vue/rollup.config.mjs delete mode 100644 npm/vue2/rollup.config.js create mode 100644 npm/vue2/rollup.config.mjs create mode 100644 packages/launchpad/src/images/logos/svelte.svg create mode 100644 system-tests/project-fixtures/svelte/cypress/support/component-index.html create mode 100644 system-tests/project-fixtures/svelte/cypress/support/component.js create mode 100644 system-tests/project-fixtures/svelte/src/App.cy.js create mode 100644 system-tests/project-fixtures/svelte/src/App.svelte create mode 100644 system-tests/project-fixtures/svelte/src/Context.svelte create mode 100644 system-tests/project-fixtures/svelte/src/Counter.svelte create mode 100644 system-tests/project-fixtures/svelte/src/Store.svelte create mode 100644 system-tests/project-fixtures/svelte/src/main.js create mode 100644 system-tests/project-fixtures/svelte/src/mount.cy.js create mode 100644 system-tests/project-fixtures/svelte/src/store.js create mode 100644 system-tests/project-fixtures/svelte/src/styles.css create mode 100644 system-tests/projects/svelte-vite-unconfigured/index.html create mode 100644 system-tests/projects/svelte-vite-unconfigured/jsconfig.json create mode 100644 system-tests/projects/svelte-vite-unconfigured/package.json create mode 100644 system-tests/projects/svelte-vite-unconfigured/public/vite.svg create mode 100644 system-tests/projects/svelte-vite-unconfigured/src/App.svelte create mode 100644 system-tests/projects/svelte-vite-unconfigured/src/app.css create mode 100644 system-tests/projects/svelte-vite-unconfigured/src/assets/svelte.svg create mode 100644 system-tests/projects/svelte-vite-unconfigured/src/lib/Counter.svelte create mode 100644 system-tests/projects/svelte-vite-unconfigured/src/main.js create mode 100644 system-tests/projects/svelte-vite-unconfigured/src/vite-env.d.ts create mode 100644 system-tests/projects/svelte-vite-unconfigured/vite.config.js create mode 100644 system-tests/projects/svelte-vite-unconfigured/yarn.lock create mode 100644 system-tests/projects/svelte-vite/cypress.config.js create mode 100644 system-tests/projects/svelte-vite/package.json create mode 100644 system-tests/projects/svelte-vite/vite.config.js create mode 100644 system-tests/projects/svelte-vite/yarn.lock create mode 100644 system-tests/projects/svelte-webpack-unconfigured/package.json create mode 100644 system-tests/projects/svelte-webpack-unconfigured/public/favicon.png create mode 100644 system-tests/projects/svelte-webpack-unconfigured/public/index.html create mode 100644 system-tests/projects/svelte-webpack-unconfigured/scripts/setupTypeScript.js create mode 100644 system-tests/projects/svelte-webpack-unconfigured/src/App.svelte create mode 100644 system-tests/projects/svelte-webpack-unconfigured/src/global.css create mode 100644 system-tests/projects/svelte-webpack-unconfigured/src/main.js create mode 100644 system-tests/projects/svelte-webpack-unconfigured/webpack.config.js create mode 100644 system-tests/projects/svelte-webpack-unconfigured/yarn.lock create mode 100644 system-tests/projects/svelte-webpack/cypress.config.js create mode 100644 system-tests/projects/svelte-webpack/package.json create mode 100644 system-tests/projects/svelte-webpack/webpack.config.js create mode 100644 system-tests/projects/svelte-webpack/yarn.lock diff --git a/cli/.gitignore b/cli/.gitignore index b8d51e94bcf7..d13afcd7f1bc 100644 --- a/cli/.gitignore +++ b/cli/.gitignore @@ -19,4 +19,5 @@ vue vue2 react* mount-utils -angular \ No newline at end of file +angular +svelte diff --git a/cli/package.json b/cli/package.json index d273862a44a0..b350b423acba 100644 --- a/cli/package.json +++ b/cli/package.json @@ -108,7 +108,8 @@ "react", "vue2", "react18", - "angular" + "angular", + "svelte" ], "bin": { "cypress": "bin/cypress" @@ -155,6 +156,11 @@ "import": "./angular/dist/index.js", "require": "./angular/dist/index.js", "types": "./angular/dist/index.d.ts" + }, + "./svelte": { + "import": "./svelte/dist/cypress-svelte.esm-bundler.js", + "require": "./svelte/dist/cypress-svelte.cjs.js", + "types": "./svelte/dist/index.d.ts" } }, "workspaces": { diff --git a/cli/scripts/post-build.js b/cli/scripts/post-build.js index 0e2c65e6ad4e..ab853799a748 100644 --- a/cli/scripts/post-build.js +++ b/cli/scripts/post-build.js @@ -13,6 +13,7 @@ const npmModulesToCopy = [ 'vue', 'vue2', 'angular', + 'svelte', ] npmModulesToCopy.forEach((folder) => { diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index be48d578586a..2826c4fcd71e 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -3058,11 +3058,11 @@ declare namespace Cypress { type DevServerConfigOptions = { bundler: 'webpack' - framework: 'react' | 'vue' | 'vue-cli' | 'nuxt' | 'create-react-app' | 'next' + framework: 'react' | 'vue' | 'vue-cli' | 'nuxt' | 'create-react-app' | 'next' | 'svelte' webpackConfig?: PickConfigOpt<'webpackConfig'> } | { bundler: 'vite' - framework: 'react' | 'vue' + framework: 'react' | 'vue' | 'svelte' viteConfig?: Omit, undefined>, 'base' | 'root'> } | { bundler: 'webpack', diff --git a/npm/angular/package.json b/npm/angular/package.json index b8aa75d447ff..ef5bdb538f6a 100644 --- a/npm/angular/package.json +++ b/npm/angular/package.json @@ -6,7 +6,7 @@ "main": "dist/index.js", "scripts": { "prebuild": "rimraf dist", - "build": "rollup -c rollup.config.js", + "build": "rollup -c rollup.config.mjs", "postbuild": "node ../../scripts/sync-exported-npm-with-cli.js", "build-prod": "yarn build", "check-ts": "tsc --noEmit" @@ -16,8 +16,7 @@ "@angular/common": "^14.0.6", "@angular/core": "^14.0.6", "@angular/platform-browser-dynamic": "^14.0.6", - "@rollup/plugin-node-resolve": "^11.1.1", - "rollup-plugin-typescript2": "^0.29.0", + "@cypress/mount-utils": "0.0.0-development", "typescript": "^4.7.4", "zone.js": "~0.11.4" }, diff --git a/npm/angular/rollup.config.js b/npm/angular/rollup.config.js deleted file mode 100644 index 975310fc9131..000000000000 --- a/npm/angular/rollup.config.js +++ /dev/null @@ -1,61 +0,0 @@ -import ts from 'rollup-plugin-typescript2' -import resolve from '@rollup/plugin-node-resolve' - -import pkg from './package.json' - -const banner = ` -/** - * ${pkg.name} v${pkg.version} - * (c) ${new Date().getFullYear()} Cypress.io - * Released under the MIT License - */ -` - -function createEntry () { - const input = 'src/index.ts' - const format = 'es' - - const config = { - input, - external: [ - '@angular/core', - '@angular/core/testing', - '@angular/common', - '@angular/platform-browser-dynamic/testing', - 'zone.js', - 'zone.js/testing', - ], - plugins: [ - resolve(), - ], - output: { - banner, - name: 'CypressAngular', - file: pkg.module, - format, - exports: 'auto', - }, - } - - console.log(`Building ${format}: ${config.output.file}`) - - config.plugins.push( - ts({ - check: true, - tsconfigOverride: { - compilerOptions: { - declaration: true, - target: 'es6', // not sure what this should be? - module: 'esnext', - }, - exclude: [], - }, - }), - ) - - return config -} - -export default [ - createEntry(), -] diff --git a/npm/angular/rollup.config.mjs b/npm/angular/rollup.config.mjs new file mode 100644 index 000000000000..4ef324cfd1a3 --- /dev/null +++ b/npm/angular/rollup.config.mjs @@ -0,0 +1,14 @@ +import { createEntries } from '@cypress/mount-utils/create-rollup-entry.mjs' + +const config = { + external: [ + '@angular/core', + '@angular/core/testing', + '@angular/common', + '@angular/platform-browser-dynamic/testing', + 'zone.js', + 'zone.js/testing', + ], +} + +export default createEntries({ formats: ['es'], input: 'src/index.ts', config }) diff --git a/npm/mount-utils/create-rollup-entry.mjs b/npm/mount-utils/create-rollup-entry.mjs new file mode 100644 index 000000000000..2db5e4781262 --- /dev/null +++ b/npm/mount-utils/create-rollup-entry.mjs @@ -0,0 +1,71 @@ +// CommonJS to easily share across packages +import ts from 'rollup-plugin-typescript2' +import resolve from '@rollup/plugin-node-resolve' +import commonjs from '@rollup/plugin-commonjs' +import _ from 'lodash' +import { readFileSync } from 'fs' + +const pkg = JSON.parse(readFileSync('./package.json')) + +/** @type {(options: { formats: string[], input: string, config: {} }) => []} */ +export function createEntries (options) { + const { + formats, + input, + config = {}, + } = options + + const banner = ` +/** + * ${pkg.name} v${pkg.version} + * (c) ${new Date().getFullYear()} Cypress.io + * Released under the MIT License + */ +` + + return formats.map((format) => { + const baseConfig = { + input, + plugins: [ + resolve({ preferBuiltins: true }), + commonjs(), + ts({ + check: format === 'es', + tsconfigOverride: { + compilerOptions: { + declaration: format === 'es', + target: 'es6', + module: format === 'cjs' ? 'es2015' : 'esnext', + }, + exclude: ['tests'], + }, + }), + ], + output: { + banner, + name: 'CypressReact', + file: pkg.unpkg, + format, + }, + } + + const finalConfig = _.mergeWith({}, baseConfig, config, (objValue, srcValue) => { + if (_.isArray(objValue)) { + return objValue.concat(srcValue) + } + }) + + if (format === 'es') { + finalConfig.output.file = pkg.module + } + + if (format === 'cjs') { + finalConfig.output.file = pkg.main + } + + // eslint-disable-next-line no-console + console.log(`Building ${format}: ${finalConfig.output.file}`) + + return finalConfig + }) +} diff --git a/npm/mount-utils/package.json b/npm/mount-utils/package.json index 1cb2f56dbd89..04747ef6a3da 100644 --- a/npm/mount-utils/package.json +++ b/npm/mount-utils/package.json @@ -12,6 +12,10 @@ }, "dependencies": {}, "devDependencies": { + "@rollup/plugin-commonjs": "^17.1.0", + "@rollup/plugin-node-resolve": "^11.1.1", + "rollup": "^2.38.5", + "rollup-plugin-typescript2": "^0.29.0", "typescript": "^4.7.4" }, "files": [ diff --git a/npm/react/package.json b/npm/react/package.json index 2d098d779b1c..a8acf12c8781 100644 --- a/npm/react/package.json +++ b/npm/react/package.json @@ -4,7 +4,7 @@ "description": "Test React components using Cypress", "main": "dist/cypress-react.cjs.js", "scripts": { - "build": "rimraf dist && rollup -c rollup.config.js", + "build": "rimraf dist && rollup -c rollup.config.mjs", "postbuild": "node ../../scripts/sync-exported-npm-with-cli.js", "build-prod": "yarn build", "cy:open": "node ../../scripts/cypress.js open --component", @@ -16,8 +16,6 @@ }, "devDependencies": { "@cypress/mount-utils": "0.0.0-development", - "@rollup/plugin-commonjs": "^17.1.0", - "@rollup/plugin-node-resolve": "^11.1.1", "@types/semver": "7.3.9", "@vitejs/plugin-react": "1.3.1", "axios": "0.21.2", @@ -27,8 +25,6 @@ "react-dom": "16.8.6", "react-router": "6.0.0-alpha.1", "react-router-dom": "6.0.0-alpha.1", - "rollup": "^2.38.5", - "rollup-plugin-typescript2": "^0.29.0", "semver": "^7.3.2", "typescript": "^4.7.4", "vite": "3.0.3", diff --git a/npm/react/rollup.config.js b/npm/react/rollup.config.js deleted file mode 100644 index 19e8ae4e2e9e..000000000000 --- a/npm/react/rollup.config.js +++ /dev/null @@ -1,74 +0,0 @@ -// CommonJS to easily share across packages -const ts = require('rollup-plugin-typescript2') -const { default: resolve } = require('@rollup/plugin-node-resolve') -const commonjs = require('@rollup/plugin-commonjs') - -const pkg = require('./package.json') - -const banner = ` -/** - * ${pkg.name} v${pkg.version} - * (c) ${new Date().getFullYear()} Cypress.io - * Released under the MIT License - */ -` - -function createEntry (options) { - const { - format, - input, - } = options - - const config = { - input, - external: [ - 'react', - 'react-dom', - 'react-dom/client', - ], - plugins: [ - resolve(), - commonjs(), - ts({ - check: format === 'es', - tsconfigOverride: { - compilerOptions: { - declaration: format === 'es', - target: 'es5', - module: format === 'cjs' ? 'es2015' : 'esnext', - }, - exclude: ['tests'], - }, - }), - ], - output: { - banner, - name: 'CypressReact', - file: pkg.unpkg, - format, - globals: { - react: 'React', - 'react-dom': 'ReactDOM', - 'react-dom/client': 'ReactDOM/client', - }, - }, - } - - if (format === 'es') { - config.output.file = pkg.module - } - - if (format === 'cjs') { - config.output.file = pkg.main - } - - // eslint-disable-next-line no-console - console.log(`Building ${format}: ${config.output.file}`) - - return config -} - -module.exports = [ - createEntry({ format: 'es', input: 'src/index.ts' }), - createEntry({ format: 'cjs', input: 'src/index.ts' }), -] diff --git a/npm/react/rollup.config.mjs b/npm/react/rollup.config.mjs new file mode 100644 index 000000000000..c3295a5e498e --- /dev/null +++ b/npm/react/rollup.config.mjs @@ -0,0 +1,18 @@ +import { createEntries } from '@cypress/mount-utils/create-rollup-entry.mjs' + +const config = { + external: [ + 'react', + 'react-dom', + 'react-dom/client', + ], + output: { + globals: { + react: 'React', + 'react-dom': 'ReactDOM', + 'react-dom/client': 'ReactDOM/client', + }, + }, +} + +export default createEntries({ formats: ['es', 'cjs'], input: 'src/index.ts', config }) diff --git a/npm/react18/package.json b/npm/react18/package.json index cd7586379f2d..88cda1925ddb 100644 --- a/npm/react18/package.json +++ b/npm/react18/package.json @@ -4,7 +4,7 @@ "description": "Test React components using Cypress", "main": "dist/cypress-react.cjs.js", "scripts": { - "build": "rimraf dist && rollup -c rollup.config.js", + "build": "rimraf dist && rollup -c rollup.config.mjs", "postbuild": "node ../../scripts/sync-exported-npm-with-cli.js", "build-prod": "yarn build", "watch": "yarn build --watch --watch.exclude ./dist/**/*" diff --git a/npm/react18/rollup.config.js b/npm/react18/rollup.config.js deleted file mode 100644 index 567529d23f26..000000000000 --- a/npm/react18/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import * as RollupConfig from '../react/rollup.config' - -export default RollupConfig diff --git a/npm/react18/rollup.config.mjs b/npm/react18/rollup.config.mjs new file mode 100644 index 000000000000..db047e2bbd48 --- /dev/null +++ b/npm/react18/rollup.config.mjs @@ -0,0 +1,3 @@ +import rollupConfig from '@cypress/react/rollup.config.mjs' + +export default rollupConfig diff --git a/npm/svelte/.eslintrc b/npm/svelte/.eslintrc new file mode 100644 index 000000000000..220212842e1e --- /dev/null +++ b/npm/svelte/.eslintrc @@ -0,0 +1,17 @@ +{ + "plugins": [ + "cypress" + ], + "extends": [ + "plugin:@cypress/dev/tests" + ], + "env": { + "cypress/globals": true + }, + "rules": { + "mocha/no-global-tests": "off", + "no-unused-vars": "off", + "no-console": "off", + "@typescript-eslint/no-unused-vars": "off" + } +} diff --git a/npm/svelte/.npmrc b/npm/svelte/.npmrc new file mode 100644 index 000000000000..ff1f40faed0b --- /dev/null +++ b/npm/svelte/.npmrc @@ -0,0 +1,3 @@ +save-exact=true +progress=false +package-lock=true diff --git a/npm/svelte/.releaserc.js b/npm/svelte/.releaserc.js new file mode 100644 index 000000000000..4cb1091bc4f7 --- /dev/null +++ b/npm/svelte/.releaserc.js @@ -0,0 +1,7 @@ +module.exports = { + ...require('../../.releaserc.base'), + branches: [ + // this one releases v3 on master on the latest channel + 'master', + ], +} diff --git a/npm/svelte/CHANGELOG.md b/npm/svelte/CHANGELOG.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/npm/svelte/README.md b/npm/svelte/README.md new file mode 100644 index 000000000000..3f1e6be7b4f0 --- /dev/null +++ b/npm/svelte/README.md @@ -0,0 +1,83 @@ +# @cypress/svelte + +Mount Svelte components in the open source [Cypress.io](https://www.cypress.io/) test runner **v10.7.0+** + +> **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [Svelte Component Testing Docs](https://docs.cypress.io/guides/component-testing/quickstart-svelte#Configuring-Component-Testing) for mounting Svelte components. Installing and importing `mount` from `@cypress/svelte` should only be used for advanced use-cases. + +## Install + +- Requires Svelte >= 3 +- Requires Cypress v10.7.0 or later +- Requires [Node](https://nodejs.org/en/) version 12 or above + +```sh +npm install --save-dev @cypress/svelte +``` + +## Run + +Open cypress test runner +``` +npx cypress open --component +``` + +If you need to run test in CI +``` +npx cypress run --component +``` + +For more information, please check the official docs for [running Cypress](https://on.cypress.io/guides/getting-started/opening-the-app#Quick-Configuration) and for [component testing](https://on.cypress.io/guides/component-testing/writing-your-first-component-test). + +## Example + +```js +import { mount } from '@cypress/svelte' +import HelloWorld from './HelloWorld.svelte' + +describe('HelloWorld component', () => { + it('works', () => { + mount(HelloWorld) + // now use standard Cypress commands + cy.contains('Hello World!').should('be.visible') + }) +}) +``` + +## Options + +In most cases, the component already imports its own styles, thus it looks "right" during the test. If you need another CSS, the simplest way is to import it from the spec file: + +```js +// src/HelloWorld.svelte +import './styles/main.css' +import HelloWorld from './HelloWorld.svelte' + +it('looks right', () => { + // styles are applied + mount(HelloWorld) +}) +``` + +> Note: Global styles can be imported in your component support file, allowing the styles to apply to all mounted components. + +## Compatibility + +| @cypress/svelte | cypress | +| -------------- | ------- | +| >= v1 | >= v10 | + +## Development + +Run `yarn build` to compile and sync packages to the `cypress` cli package. + +Run `yarn cy:open` to open Cypress component testing against real-world examples. + +Run `yarn test` to execute headless Cypress tests. + +## License + +[![license](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/cypress-io/cypress/blob/master/LICENSE) + +This project is licensed under the terms of the [MIT license](/LICENSE). + +## [Changelog](./CHANGELOG.md) diff --git a/npm/svelte/package.json b/npm/svelte/package.json new file mode 100644 index 000000000000..14ffdaf8dc4e --- /dev/null +++ b/npm/svelte/package.json @@ -0,0 +1,43 @@ +{ + "name": "@cypress/svelte", + "version": "0.0.0-development", + "description": "Browser-based Component Testing for Svelte.js with Cypress.io 🧡", + "main": "dist/cypress-svelte.cjs.js", + "scripts": { + "prebuild": "rimraf dist", + "build": "rollup -c rollup.config.mjs", + "postbuild": "node ../../scripts/sync-exported-npm-with-cli.js", + "build-prod": "yarn build", + "check-ts": "tsc --noEmit" + }, + "devDependencies": { + "@cypress/mount-utils": "0.0.0-development", + "svelte": "^3.49.0", + "typescript": "^4.7.4" + }, + "peerDependencies": { + "cypress": ">=10.6.0", + "svelte": ">=3.0.0" + }, + "files": [ + "dist/**/*" + ], + "types": "dist/index.d.ts", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/cypress-io/cypress.git" + }, + "homepage": "https://github.com/cypress-io/cypress/blob/master/npm/svelte/#readme", + "bugs": "https://github.com/cypress-io/cypress/issues/new?assignees=&labels=npm%3A%20%40cypress%2Fsvelte&template=1-bug-report.md&title=", + "keywords": [ + "cypress", + "svelte", + "testing", + "component testing" + ], + "module": "dist/cypress-svelte.esm-bundler.js", + "publishConfig": { + "access": "public" + } +} diff --git a/npm/svelte/rollup.config.mjs b/npm/svelte/rollup.config.mjs new file mode 100644 index 000000000000..18d161ab7f90 --- /dev/null +++ b/npm/svelte/rollup.config.mjs @@ -0,0 +1,3 @@ +import { createEntries } from '@cypress/mount-utils/create-rollup-entry.mjs' + +export default createEntries({ formats: ['es', 'cjs'], input: 'src/index.ts' }) diff --git a/npm/svelte/src/index.ts b/npm/svelte/src/index.ts new file mode 100644 index 000000000000..1af962e1d530 --- /dev/null +++ b/npm/svelte/src/index.ts @@ -0,0 +1 @@ +export * from './mount' diff --git a/npm/svelte/src/mount.ts b/npm/svelte/src/mount.ts new file mode 100644 index 000000000000..b90581f895d0 --- /dev/null +++ b/npm/svelte/src/mount.ts @@ -0,0 +1,100 @@ +import { + injectStylesBeforeElement, + StyleOptions, + getContainerEl, + setupHooks, +} from '@cypress/mount-utils' +import type { ComponentConstructorOptions, ComponentProps, SvelteComponent } from 'svelte' + +const DEFAULT_COMP_NAME = 'unknown' + +type SvelteConstructor = new (...args: any[]) => T; +type SvelteComponentOptions = Omit< + ComponentConstructorOptions>, + 'hydrate' | 'target' | '$$inline' +>; + +export interface MountOptions + extends SvelteComponentOptions, + Partial { + log?: boolean +} + +export interface MountReturn { + component: T +} + +let componentInstance: SvelteComponent | undefined + +const cleanup = () => { + componentInstance?.$destroy() +} + +// Extract the component name from the object passed to mount +const getComponentDisplayName = (Component: SvelteConstructor): string => { + if (Component.name) { + const [_, match] = /Proxy\<(\w+)\>/.exec(Component.name) || [] + + return match || Component.name + } + + return DEFAULT_COMP_NAME +} + +/** + * Mounts a Svelte component inside the Cypress browser + * + * @param {SvelteConstructor} Component Svelte component being mounted + * @param {MountReturn} options options to customize the component being mounted + * @returns Cypress.Chainable + * + * @example + * import Counter from './Counter.svelte' + * import { mount } from 'cypress/svelte' + * + * it('should render', () => { + * mount(Counter, { props: { count: 42 } }) + * cy.get('button').contains(42) + * }) + */ +export function mount ( + Component: SvelteConstructor, + options: MountOptions = {}, +): Cypress.Chainable> { + return cy.then(() => { + const target = getContainerEl() + + injectStylesBeforeElement(options, document, target) + + const ComponentConstructor = ((Component as any).default || Component) as SvelteConstructor + + componentInstance = new ComponentConstructor({ + target, + ...options, + }) + + // by waiting, we are delaying test execution for the next tick of event loop + // and letting hooks and component lifecycle methods to execute mount + return cy.wait(0, { log: false }).then(() => { + if (options.log) { + const mountMessage = `<${getComponentDisplayName(Component)} ... />` + + Cypress.log({ + name: 'mount', + message: [mountMessage], + }).snapshot('mounted').end() + } + }) + .wrap({ component: componentInstance as T }, { log: false }) + }) +} + +// Side effects from "import { mount } from '@cypress/'" are annoying, we should avoid doing this +// by creating an explicit function/import that the user can register in their 'component.js' support file, +// such as: +// import 'cypress//support' +// or +// import { registerCT } from 'cypress/' +// registerCT() +// Note: This would be a breaking change +setupHooks(cleanup) diff --git a/npm/svelte/tsconfig.json b/npm/svelte/tsconfig.json new file mode 100644 index 000000000000..d8bd4213e255 --- /dev/null +++ b/npm/svelte/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "skipLibCheck": true, + "lib": [ + "es2015", + "dom" + ], + "allowJs": true, + "jsx": "preserve", + "outDir": "dist", + "strict": true, + "baseUrl": "./", + "types": [ + "cypress" + ], + "allowSyntheticDefaultImports": true, + "esModuleInterop": true + }, + "include": ["src"], +} diff --git a/npm/vue/package.json b/npm/vue/package.json index 1c75bc92329b..5bbb2d623b80 100644 --- a/npm/vue/package.json +++ b/npm/vue/package.json @@ -7,7 +7,7 @@ "build-prod": "yarn build", "cy:open": "node ../../scripts/cypress.js open --component --project ${PWD}", "cy:run": "node ../../scripts/cypress.js run --component --project ${PWD}", - "build": "rimraf dist && rollup -c rollup.config.js", + "build": "rimraf dist && rollup -c rollup.config.mjs", "postbuild": "node --require @packages/ts/register ./inline-types.ts && node ../../scripts/sync-exported-npm-with-cli.js", "typecheck": "yarn tsd && vue-tsc --noEmit", "test": "yarn cy:run", @@ -16,8 +16,6 @@ }, "devDependencies": { "@cypress/mount-utils": "0.0.0-development", - "@rollup/plugin-commonjs": "^17.1.0", - "@rollup/plugin-node-resolve": "^11.1.1", "@vitejs/plugin-vue": "2.3.1", "@vue/compiler-sfc": "3.2.31", "@vue/test-utils": "2.0.2", @@ -25,9 +23,6 @@ "cypress": "0.0.0-development", "debug": "^4.3.2", "globby": "^11.0.1", - "rollup": "^2.38.5", - "rollup-plugin-istanbul": "2.0.1", - "rollup-plugin-typescript2": "^0.29.0", "tailwindcss": "1.1.4", "typescript": "^4.7.4", "vite": "3.0.3", diff --git a/npm/vue/rollup.config.js b/npm/vue/rollup.config.js deleted file mode 100644 index 38c3018cb05b..000000000000 --- a/npm/vue/rollup.config.js +++ /dev/null @@ -1,75 +0,0 @@ -import ts from 'rollup-plugin-typescript2' -import resolve from '@rollup/plugin-node-resolve' -import commonjs from '@rollup/plugin-commonjs' - -import pkg from './package.json' - -const banner = ` -/** - * ${pkg.name} v${pkg.version} - * (c) ${new Date().getFullYear()} Cypress.io - * Released under the MIT License - */ -` - -function createEntry (options) { - const { - format, - input, - } = options - - const config = { - input, - external: [ - 'vue', - ], - plugins: [ - resolve({ preferBuiltins: true }), commonjs(), - ], - output: { - banner, - name: 'CypressVue', - file: pkg.unpkg, - format, - globals: { - vue: 'Vue', - }, - exports: 'auto', - }, - } - - if (input === 'src/index.ts') { - if (format === 'es') { - config.output.file = pkg.module - } - - if (format === 'cjs') { - config.output.file = pkg.main - } - } else { - config.output.file = input.replace(/^src\//, 'dist/') - } - - console.log(`Building ${format}: ${config.output.file}`) - - config.plugins.push( - ts({ - check: false, - tsconfigOverride: { - compilerOptions: { - declaration: format === 'es', - noEmit: false, - module: format === 'cjs' ? 'es2015' : 'esnext', - }, - exclude: ['cypress/component'], - }, - }), - ) - - return config -} - -export default [ - createEntry({ format: 'es', input: 'src/index.ts' }), - createEntry({ format: 'cjs', input: 'src/index.ts' }), -] diff --git a/npm/vue/rollup.config.mjs b/npm/vue/rollup.config.mjs new file mode 100644 index 000000000000..3166072b35d2 --- /dev/null +++ b/npm/vue/rollup.config.mjs @@ -0,0 +1,14 @@ +import { createEntries } from '@cypress/mount-utils/create-rollup-entry.mjs' + +const config = { + external: [ + 'vue', + ], + output: { + globals: { + vue: 'Vue', + }, + }, +} + +export default createEntries({ formats: ['es', 'cjs'], input: 'src/index.ts', config }) diff --git a/npm/vue2/package.json b/npm/vue2/package.json index 8ba42355f920..108650b5797d 100644 --- a/npm/vue2/package.json +++ b/npm/vue2/package.json @@ -5,7 +5,7 @@ "main": "dist/cypress-vue2.cjs.js", "scripts": { "typecheck": "tsc --noEmit", - "build": "rimraf dist && yarn rollup -c rollup.config.js", + "build": "rimraf dist && yarn rollup -c rollup.config.mjs", "postbuild": "node ../../scripts/sync-exported-npm-with-cli.js", "build-prod": "yarn build", "test": "echo \"Tests for @cypress/vue2 are run from system-tests\"", @@ -17,11 +17,8 @@ }, "devDependencies": { "@cypress/mount-utils": "0.0.0-development", - "@rollup/plugin-commonjs": "^17.1.0", "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^11.1.1", "@rollup/plugin-replace": "^2.3.1", - "rollup-plugin-typescript2": "^0.29.0", "tslib": "^2.1.0", "typescript": "^4.7.4", "vue": "2.6.12" diff --git a/npm/vue2/rollup.config.js b/npm/vue2/rollup.config.js deleted file mode 100644 index 0767286aae1a..000000000000 --- a/npm/vue2/rollup.config.js +++ /dev/null @@ -1,93 +0,0 @@ -import ts from 'rollup-plugin-typescript2' -import resolve from '@rollup/plugin-node-resolve' -import commonjs from '@rollup/plugin-commonjs' -import json from '@rollup/plugin-json' -import replace from '@rollup/plugin-replace' - -import pkg from './package.json' - -const banner = ` -/** - * ${pkg.name} v${pkg.version} - * (c) ${new Date().getFullYear()} Cypress.io - * Released under the MIT License - */ -` - -function createEntry (options) { - const { - format, - input, - isBrowser, - } = options - - const config = { - input, - external: [ - 'vue', - ], - plugins: [ - resolve({ preferBuiltins: true }), - commonjs(), - json(), - /** - * Vue 2 core tries to load require.resolve(`./package.json`) in the browser for the - * sole purpose of throwing an error about Vue Loader. - * Just truncate this for now for simplicity. - */ - replace({ - 'vueVersion && vueVersion !== packageVersion': JSON.stringify(false), - }), - ], - output: { - banner, - name: 'CypressVue2', - file: pkg.unpkg, - format, - globals: { - vue: 'Vue', - }, - exports: 'auto', - }, - } - - if (input === 'src/index.ts') { - if (format === 'es') { - config.output.file = pkg.module - if (isBrowser) { - config.output.file = pkg.unpkg - } - } - - if (format === 'cjs') { - config.output.file = pkg.main - } - } else { - config.output.file = input.replace(/^src\//, 'dist/') - } - - console.log(`Building ${format}: ${config.output.file}`) - - config.plugins.push( - ts({ - check: format === 'es' && isBrowser, - tsconfigOverride: { - compilerOptions: { - declaration: format === 'es', - target: 'es5', // not sure what this should be? - module: format === 'cjs' ? 'es2015' : 'esnext', - }, - exclude: ['tests'], - }, - }), - ) - - return config -} - -export default [ - createEntry({ format: 'es', input: 'src/index.ts', isBrowser: false }), - createEntry({ format: 'es', input: 'src/index.ts', isBrowser: true }), - createEntry({ format: 'iife', input: 'src/index.ts', isBrowser: true }), - createEntry({ format: 'cjs', input: 'src/index.ts', isBrowser: false }), -] diff --git a/npm/vue2/rollup.config.mjs b/npm/vue2/rollup.config.mjs new file mode 100644 index 000000000000..bed807e40c5d --- /dev/null +++ b/npm/vue2/rollup.config.mjs @@ -0,0 +1,28 @@ +import { createEntries } from '@cypress/mount-utils/create-rollup-entry.mjs' +import json from '@rollup/plugin-json' +import replace from '@rollup/plugin-replace' + +const config = { + external: [ + 'vue', + ], + plugins: [ + json(), + /** + * Vue 2 core tries to load require.resolve(`./package.json`) in the browser for the + * sole purpose of throwing an error about Vue Loader. + * Just truncate this for now for simplicity. + */ + replace({ + 'vueVersion && vueVersion !== packageVersion': JSON.stringify(false), + preventAssignment: false, + }), + ], + output: { + globals: { + vue: 'Vue', + }, + }, +} + +export default createEntries({ formats: ['es', 'cjs'], input: 'src/index.ts', config }) diff --git a/npm/webpack-dev-server/src/devServer.ts b/npm/webpack-dev-server/src/devServer.ts index 1a358937e989..a3a9f0d36879 100644 --- a/npm/webpack-dev-server/src/devServer.ts +++ b/npm/webpack-dev-server/src/devServer.ts @@ -128,6 +128,7 @@ async function getPreset (devServerConfig: WebpackDevServerConfig): Promise { + it('Scaffolds component testing for Svelte using vite', () => { + startSetupFor('svelte-vite-unconfigured') + + // should detect correctly + // Screen reader text is "Support is in", but don't want to rely on DOM introduced whitespace so using regex + cy.contains('button', /Svelte\.js\s+Support is in\s+Alpha\(detected\)/).should('be.visible') + cy.contains('button', 'Next Step').click() + cy.findByRole('button', { name: 'Continue' }).click() + verifyConfigFile(`cypress.config.js`) + }) + }) + + context('svelte-webpack-unconfigured', () => { + it('Scaffolds component testing for Svelte using webpack', () => { + startSetupFor('svelte-webpack-unconfigured') + + // should detect correctly + // Screen reader text is "Support is in", but don't want to rely on DOM introduced whitespace so using regex + cy.contains('button', /Svelte\.js\s+Support is in\s+Alpha\(detected\)/).should('be.visible') + cy.contains('button', 'Next Step').click() + cy.findByRole('button', { name: 'Continue' }).click() + verifyConfigFile(`cypress.config.js`) + }) + }) }) diff --git a/packages/launchpad/src/images/logos/svelte.svg b/packages/launchpad/src/images/logos/svelte.svg new file mode 100644 index 000000000000..57c110590300 --- /dev/null +++ b/packages/launchpad/src/images/logos/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/launchpad/src/utils/icons.ts b/packages/launchpad/src/utils/icons.ts index 7c408947d2c9..709ae2e5d24a 100644 --- a/packages/launchpad/src/utils/icons.ts +++ b/packages/launchpad/src/utils/icons.ts @@ -5,6 +5,7 @@ import LogoNuxt from '../images/logos/nuxt.svg' import LogoVue from '../images/logos/vue.svg' import LogoReact from '../images/logos/react.svg' import LogoAngular from '../images/logos/angular.svg' +import LogoSvelte from '../images/logos/svelte.svg' import type { FrontendFrameworkEnum, SupportedBundlers } from '../generated/graphql' @@ -20,4 +21,5 @@ export const FrameworkBundlerLogos: Record=13.0.0', } as const +export const WIZARD_DEPENDENCY_SVELTE = { + type: 'svelte', + name: 'Svelte.js', + package: 'svelte', + installer: 'svelte', + description: 'Cybernetically enhanced web apps', + minVersion: '^3.0.0', +} as const + export const WIZARD_DEPENDENCIES = [ WIZARD_DEPENDENCY_WEBPACK, WIZARD_DEPENDENCY_TYPESCRIPT, @@ -159,6 +168,7 @@ export const WIZARD_DEPENDENCIES = [ WIZARD_DEPENDENCY_ANGULAR_CORE, WIZARD_DEPENDENCY_ANGULAR_COMMON, WIZARD_DEPENDENCY_ANGULAR_PLATFORM_BROWSER_DYNAMIC, + WIZARD_DEPENDENCY_SVELTE, ] as const export const WIZARD_BUNDLERS = [ diff --git a/packages/scaffold-config/src/frameworks.ts b/packages/scaffold-config/src/frameworks.ts index 4f32935b7794..f006d46ec69b 100644 --- a/packages/scaffold-config/src/frameworks.ts +++ b/packages/scaffold-config/src/frameworks.ts @@ -264,4 +264,23 @@ export const WIZARD_FRAMEWORKS = [ componentIndexHtml: componentIndexHtmlGenerator(), specPattern: '**/*.cy.ts', }, + { + type: 'svelte', + configFramework: 'svelte', + category: 'library', + name: 'Svelte.js', + detectors: [dependencies.WIZARD_DEPENDENCY_SVELTE], + supportedBundlers: [dependencies.WIZARD_DEPENDENCY_WEBPACK, dependencies.WIZARD_DEPENDENCY_VITE], + dependencies: (bundler: WizardBundler['type'], projectPath: string): Promise => { + return Promise.all([ + getBundlerDependency(bundler, projectPath), + isDependencyInstalled(dependencies.WIZARD_DEPENDENCY_SVELTE, projectPath), + ]) + }, + codeGenFramework: 'svelte', + glob: '*.svelte', + mountModule: mountModule('cypress/svelte'), + supportStatus: 'alpha', + componentIndexHtml: componentIndexHtmlGenerator(), + }, ] as const diff --git a/packages/scaffold-config/test/unit/detect.spec.ts b/packages/scaffold-config/test/unit/detect.spec.ts index a87dec253c38..3f8d5f2fbf78 100644 --- a/packages/scaffold-config/test/unit/detect.spec.ts +++ b/packages/scaffold-config/test/unit/detect.spec.ts @@ -219,6 +219,36 @@ describe('detectFramework', () => { }) }) + ;['2.0.0', '3.0.0'].forEach((v) => { + it(`Svelte and Vite v${v}`, async () => { + const projectPath = await scaffoldMigrationProject('svelte-vite-unconfigured') + + fakeDepsInNodeModules(projectPath, [ + { dependency: 'svelte', version: '3.0.0' }, + { dependency: 'vite', version: v }, + ]) + + const actual = await detectFramework(projectPath) + + expect(actual.framework?.type).to.eq('svelte') + expect(actual.bundler?.type).to.eq('vite') + }) + }) + + it(`Svelte and Webpack`, async () => { + const projectPath = await scaffoldMigrationProject('svelte-webpack-unconfigured') + + fakeDepsInNodeModules(projectPath, [ + { dependency: 'svelte', version: '3.0.0' }, + { dependency: 'webpack', version: '5.0.0' }, + ]) + + const actual = await detectFramework(projectPath) + + expect(actual.framework?.type).to.eq('svelte') + expect(actual.bundler?.type).to.eq('webpack') + }) + it(`no framework or library`, async () => { const projectPath = await scaffoldMigrationProject('pristine') diff --git a/packages/scaffold-config/test/unit/supportFile.spec.ts b/packages/scaffold-config/test/unit/supportFile.spec.ts index ab50b1010c70..37bfce49e9d3 100644 --- a/packages/scaffold-config/test/unit/supportFile.spec.ts +++ b/packages/scaffold-config/test/unit/supportFile.spec.ts @@ -220,4 +220,86 @@ describe('supportFileComponent', () => { }) } }) + + context('svelte', () => { + it(`handles cypress/svelte and JS`, () => { + const actual = supportFileComponent('js', 'cypress/svelte') + + expect(actual).to.eq(dedent` + // *********************************************************** + // This example support/component.js is processed and + // loaded automatically before your test files. + // + // This is a great place to put global configuration and + // behavior that modifies Cypress. + // + // You can change the location of this file or turn off + // automatically serving support files with the + // 'supportFile' configuration option. + // + // You can read more here: + // https://on.cypress.io/configuration + // *********************************************************** + + // Import commands.js using ES2015 syntax: + import './commands' + + // Alternatively you can use CommonJS syntax: + // require('./commands') + + import { mount } from 'cypress/svelte' + + Cypress.Commands.add('mount', mount) + + // Example use: + // cy.mount(MyComponent) + `) + }) + + it(`handles cypress/svelte and TS`, () => { + const actual = supportFileComponent('ts', 'cypress/svelte') + + expect(actual).to.eq(dedent` + // *********************************************************** + // This example support/component.ts is processed and + // loaded automatically before your test files. + // + // This is a great place to put global configuration and + // behavior that modifies Cypress. + // + // You can change the location of this file or turn off + // automatically serving support files with the + // 'supportFile' configuration option. + // + // You can read more here: + // https://on.cypress.io/configuration + // *********************************************************** + + // Import commands.js using ES2015 syntax: + import './commands' + + // Alternatively you can use CommonJS syntax: + // require('./commands') + + import { mount } from 'cypress/svelte' + + // Augment the Cypress namespace to include type definitions for + // your custom command. + // Alternatively, can be defined in cypress/support/component.d.ts + // with a at the top of your spec. + declare global { + namespace Cypress { + interface Chainable { + mount: typeof mount + } + } + } + + Cypress.Commands.add('mount', mount) + + // Example use: + // cy.mount(MyComponent) + `) + }) + }) }) diff --git a/system-tests/project-fixtures/svelte/cypress/support/component-index.html b/system-tests/project-fixtures/svelte/cypress/support/component-index.html new file mode 100644 index 000000000000..efb21087792f --- /dev/null +++ b/system-tests/project-fixtures/svelte/cypress/support/component-index.html @@ -0,0 +1,14 @@ + + + + + + + Components App + + +
+
+
+ + \ No newline at end of file diff --git a/system-tests/project-fixtures/svelte/cypress/support/component.js b/system-tests/project-fixtures/svelte/cypress/support/component.js new file mode 100644 index 000000000000..e545642795cf --- /dev/null +++ b/system-tests/project-fixtures/svelte/cypress/support/component.js @@ -0,0 +1,4 @@ +import { mount } from "cypress/svelte"; +import "../../src/styles.css" + +Cypress.Commands.add("mount", mount); diff --git a/system-tests/project-fixtures/svelte/src/App.cy.js b/system-tests/project-fixtures/svelte/src/App.cy.js new file mode 100644 index 000000000000..eb0a1ca14db7 --- /dev/null +++ b/system-tests/project-fixtures/svelte/src/App.cy.js @@ -0,0 +1,10 @@ +import App from './App.svelte' + +it('should render with style', () => { + cy.mount(App) + cy.contains('Hello World!') + // Verify global styles + cy.get('.very-red').should('have.css', 'color', 'rgb(255, 0, 0)') + // Verify local styles + cy.get('.very-blue').should('have.css', 'color', 'rgb(0, 0, 255)') +}) \ No newline at end of file diff --git a/system-tests/project-fixtures/svelte/src/App.svelte b/system-tests/project-fixtures/svelte/src/App.svelte new file mode 100644 index 000000000000..0487536f3004 --- /dev/null +++ b/system-tests/project-fixtures/svelte/src/App.svelte @@ -0,0 +1,14 @@ + + +
+

Hello World!

+

Colored by global styles

+

Colored by local styles

+
+ + diff --git a/system-tests/project-fixtures/svelte/src/Context.svelte b/system-tests/project-fixtures/svelte/src/Context.svelte new file mode 100644 index 000000000000..7286ab59bc20 --- /dev/null +++ b/system-tests/project-fixtures/svelte/src/Context.svelte @@ -0,0 +1,7 @@ + + +

{msg}

diff --git a/system-tests/project-fixtures/svelte/src/Counter.svelte b/system-tests/project-fixtures/svelte/src/Counter.svelte new file mode 100644 index 000000000000..91f3067a54c4 --- /dev/null +++ b/system-tests/project-fixtures/svelte/src/Counter.svelte @@ -0,0 +1,20 @@ + + +
+
+

Count is {count}

+ +
+
diff --git a/system-tests/project-fixtures/svelte/src/Store.svelte b/system-tests/project-fixtures/svelte/src/Store.svelte new file mode 100644 index 000000000000..4e931f833869 --- /dev/null +++ b/system-tests/project-fixtures/svelte/src/Store.svelte @@ -0,0 +1,19 @@ + + +

{message}

+ \ No newline at end of file diff --git a/system-tests/project-fixtures/svelte/src/main.js b/system-tests/project-fixtures/svelte/src/main.js new file mode 100644 index 000000000000..1e9065b459ac --- /dev/null +++ b/system-tests/project-fixtures/svelte/src/main.js @@ -0,0 +1,8 @@ +import App from "./App.svelte"; +import "./styles.css"; + +const app = new App({ + target: document.getElementById("app"), +}); + +export default app; diff --git a/system-tests/project-fixtures/svelte/src/mount.cy.js b/system-tests/project-fixtures/svelte/src/mount.cy.js new file mode 100644 index 000000000000..998006e0c3c8 --- /dev/null +++ b/system-tests/project-fixtures/svelte/src/mount.cy.js @@ -0,0 +1,56 @@ +import Counter from "./Counter.svelte"; +import Context from "./Context.svelte"; +import Store from "./Store.svelte"; +import { messageStore } from "./store"; + +describe("Svelte mount", () => { + it("mounts", () => { + cy.mount(Counter) + cy.contains("h1", "Count is 0"); + }); + + it("reacts to state changes", () => { + cy.mount(Counter); + cy.contains("h1", "Count is 0"); + cy.get("button").click(); + cy.contains("h1", "Count is 1"); + }); + + it("accepts props", () => { + cy.mount(Counter, { props: { count: 42 } }); + cy.contains("h1", "Count is 42"); + }); + + it("accepts context", () => { + const payload = { msg: "This value came from context!" }; + const context = new Map(); + context.set("myKey", payload); + + cy.mount(Context, { context }); + cy.contains("h1", payload.msg); + }); + + it("spies on outputs", () => { + cy.mount(Counter).then(({ component }) => { + component.$on("change", cy.spy().as("changeSpy")); + cy.get("button").click(); + cy.get("@changeSpy").should("have.been.called"); + }); + }); + + it("anchors mounted component", () => { + cy.mount(Counter, { anchor: document.getElementById("anchor") }); + cy.get("[data-cy-root]").children().last().should("have.id", "anchor"); + }); + + it("reactive to writables", () => { + cy.mount(Store); + cy.contains("h1", "Hello World!"); + + cy.get("input").clear().type("New Message"); + cy.contains("h1", "New Message"); + + cy.then(() => messageStore.set("Written from spec")); + cy.contains("h1", "Written from spec"); + }); +}); diff --git a/system-tests/project-fixtures/svelte/src/store.js b/system-tests/project-fixtures/svelte/src/store.js new file mode 100644 index 000000000000..3553aaeef4c6 --- /dev/null +++ b/system-tests/project-fixtures/svelte/src/store.js @@ -0,0 +1,3 @@ +import { writable } from "svelte/store"; + +export const messageStore = writable("Hello World!"); diff --git a/system-tests/project-fixtures/svelte/src/styles.css b/system-tests/project-fixtures/svelte/src/styles.css new file mode 100644 index 000000000000..3d556d74ae23 --- /dev/null +++ b/system-tests/project-fixtures/svelte/src/styles.css @@ -0,0 +1,3 @@ +.very-red { + color: rgb(255, 0, 0) +} \ No newline at end of file diff --git a/system-tests/projects/svelte-vite-unconfigured/index.html b/system-tests/projects/svelte-vite-unconfigured/index.html new file mode 100644 index 000000000000..26c29c45b268 --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Svelte + + +
+ + + diff --git a/system-tests/projects/svelte-vite-unconfigured/jsconfig.json b/system-tests/projects/svelte-vite-unconfigured/jsconfig.json new file mode 100644 index 000000000000..a7f7b904decf --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/jsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "moduleResolution": "Node", + "target": "ESNext", + "module": "ESNext", + "importsNotUsedAsValues": "error", + "isolatedModules": true, + "resolveJsonModule": true, + "sourceMap": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + "checkJs": true + }, + "include": [ + "src/**/*.d.ts", + "src/**/*.js", + "src/**/*.svelte" + ] +} diff --git a/system-tests/projects/svelte-vite-unconfigured/package.json b/system-tests/projects/svelte-vite-unconfigured/package.json new file mode 100644 index 000000000000..c1fedc4e10ab --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/package.json @@ -0,0 +1,16 @@ +{ + "name": "svelte-vite-unconfigured", + "version": "0.0.0", + "private": true, + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^1.0.1", + "svelte": "^3.49.0", + "vite": "^3.0.7" + }, + "type": "module" +} diff --git a/system-tests/projects/svelte-vite-unconfigured/public/vite.svg b/system-tests/projects/svelte-vite-unconfigured/public/vite.svg new file mode 100644 index 000000000000..e7b8dfb1b2a6 --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/system-tests/projects/svelte-vite-unconfigured/src/App.svelte b/system-tests/projects/svelte-vite-unconfigured/src/App.svelte new file mode 100644 index 000000000000..704ad09e9ea5 --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/src/App.svelte @@ -0,0 +1,45 @@ + + +
+ +

Vite + Svelte

+ +
+ +
+ +

+ Check out SvelteKit, the official Svelte app framework powered by Vite! +

+ +

+ Click on the Vite and Svelte logos to learn more +

+
+ + diff --git a/system-tests/projects/svelte-vite-unconfigured/src/app.css b/system-tests/projects/svelte-vite-unconfigured/src/app.css new file mode 100644 index 000000000000..bcc7233dd1ca --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/src/app.css @@ -0,0 +1,81 @@ +:root { + font-family: Inter, Avenir, Helvetica, Arial, sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/system-tests/projects/svelte-vite-unconfigured/src/assets/svelte.svg b/system-tests/projects/svelte-vite-unconfigured/src/assets/svelte.svg new file mode 100644 index 000000000000..c5e08481f8ae --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/src/assets/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/system-tests/projects/svelte-vite-unconfigured/src/lib/Counter.svelte b/system-tests/projects/svelte-vite-unconfigured/src/lib/Counter.svelte new file mode 100644 index 000000000000..e45f90310979 --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/src/lib/Counter.svelte @@ -0,0 +1,10 @@ + + + diff --git a/system-tests/projects/svelte-vite-unconfigured/src/main.js b/system-tests/projects/svelte-vite-unconfigured/src/main.js new file mode 100644 index 000000000000..8a909a15a0eb --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/src/main.js @@ -0,0 +1,8 @@ +import './app.css' +import App from './App.svelte' + +const app = new App({ + target: document.getElementById('app'), +}) + +export default app diff --git a/system-tests/projects/svelte-vite-unconfigured/src/vite-env.d.ts b/system-tests/projects/svelte-vite-unconfigured/src/vite-env.d.ts new file mode 100644 index 000000000000..4078e7476a2e --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/system-tests/projects/svelte-vite-unconfigured/vite.config.js b/system-tests/projects/svelte-vite-unconfigured/vite.config.js new file mode 100644 index 000000000000..d70196943d0d --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()], +}) diff --git a/system-tests/projects/svelte-vite-unconfigured/yarn.lock b/system-tests/projects/svelte-vite-unconfigured/yarn.lock new file mode 100644 index 000000000000..97655e18a763 --- /dev/null +++ b/system-tests/projects/svelte-vite-unconfigured/yarn.lock @@ -0,0 +1,295 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@esbuild/linux-loong64@0.14.54": + version "0.14.54" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028" + integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw== + +"@rollup/pluginutils@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" + integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== + dependencies: + estree-walker "^2.0.1" + picomatch "^2.2.2" + +"@sveltejs/vite-plugin-svelte@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.1.tgz#7f468f03c933fcdfc60d4773671c73f33b9ef4d6" + integrity sha512-PorCgUounn0VXcpeJu+hOweZODKmGuLHsLomwqSj+p26IwjjGffmYQfVHtiTWq+NqaUuuHWWG7vPge6UFw4Aeg== + dependencies: + "@rollup/pluginutils" "^4.2.1" + debug "^4.3.4" + deepmerge "^4.2.2" + kleur "^4.1.5" + magic-string "^0.26.2" + svelte-hmr "^0.14.12" + +debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +esbuild-android-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz#505f41832884313bbaffb27704b8bcaa2d8616be" + integrity sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ== + +esbuild-android-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz#8ce69d7caba49646e009968fe5754a21a9871771" + integrity sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg== + +esbuild-darwin-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz#24ba67b9a8cb890a3c08d9018f887cc221cdda25" + integrity sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug== + +esbuild-darwin-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz#3f7cdb78888ee05e488d250a2bdaab1fa671bf73" + integrity sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw== + +esbuild-freebsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz#09250f997a56ed4650f3e1979c905ffc40bbe94d" + integrity sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg== + +esbuild-freebsd-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz#bafb46ed04fc5f97cbdb016d86947a79579f8e48" + integrity sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q== + +esbuild-linux-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz#e2a8c4a8efdc355405325033fcebeb941f781fe5" + integrity sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw== + +esbuild-linux-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz#de5fdba1c95666cf72369f52b40b03be71226652" + integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg== + +esbuild-linux-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz#dae4cd42ae9787468b6a5c158da4c84e83b0ce8b" + integrity sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig== + +esbuild-linux-arm@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz#a2c1dff6d0f21dbe8fc6998a122675533ddfcd59" + integrity sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw== + +esbuild-linux-mips64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz#d9918e9e4cb972f8d6dae8e8655bf9ee131eda34" + integrity sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw== + +esbuild-linux-ppc64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz#3f9a0f6d41073fb1a640680845c7de52995f137e" + integrity sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ== + +esbuild-linux-riscv64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz#618853c028178a61837bc799d2013d4695e451c8" + integrity sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg== + +esbuild-linux-s390x@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz#d1885c4c5a76bbb5a0fe182e2c8c60eb9e29f2a6" + integrity sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA== + +esbuild-netbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz#69ae917a2ff241b7df1dbf22baf04bd330349e81" + integrity sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w== + +esbuild-openbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz#db4c8495287a350a6790de22edea247a57c5d47b" + integrity sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw== + +esbuild-sunos-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz#54287ee3da73d3844b721c21bc80c1dc7e1bf7da" + integrity sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw== + +esbuild-windows-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz#f8aaf9a5667630b40f0fb3aa37bf01bbd340ce31" + integrity sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w== + +esbuild-windows-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz#bf54b51bd3e9b0f1886ffdb224a4176031ea0af4" + integrity sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ== + +esbuild-windows-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz#937d15675a15e4b0e4fafdbaa3a01a776a2be982" + integrity sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg== + +esbuild@^0.14.47: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.54.tgz#8b44dcf2b0f1a66fc22459943dccf477535e9aa2" + integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA== + optionalDependencies: + "@esbuild/linux-loong64" "0.14.54" + esbuild-android-64 "0.14.54" + esbuild-android-arm64 "0.14.54" + esbuild-darwin-64 "0.14.54" + esbuild-darwin-arm64 "0.14.54" + esbuild-freebsd-64 "0.14.54" + esbuild-freebsd-arm64 "0.14.54" + esbuild-linux-32 "0.14.54" + esbuild-linux-64 "0.14.54" + esbuild-linux-arm "0.14.54" + esbuild-linux-arm64 "0.14.54" + esbuild-linux-mips64le "0.14.54" + esbuild-linux-ppc64le "0.14.54" + esbuild-linux-riscv64 "0.14.54" + esbuild-linux-s390x "0.14.54" + esbuild-netbsd-64 "0.14.54" + esbuild-openbsd-64 "0.14.54" + esbuild-sunos-64 "0.14.54" + esbuild-windows-32 "0.14.54" + esbuild-windows-64 "0.14.54" + esbuild-windows-arm64 "0.14.54" + +estree-walker@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +is-core-module@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + dependencies: + has "^1.0.3" + +kleur@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== + +magic-string@^0.26.2: + version "0.26.2" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.2.tgz#5331700e4158cd6befda738bb6b0c7b93c0d4432" + integrity sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A== + dependencies: + sourcemap-codec "^1.4.8" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.2.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +postcss@^8.4.16: + version "8.4.16" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" + integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +resolve@^1.22.1: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +"rollup@>=2.75.6 <2.77.0 || ~2.77.0": + version "2.77.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.77.3.tgz#8f00418d3a2740036e15deb653bed1a90ee0cc12" + integrity sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g== + optionalDependencies: + fsevents "~2.3.2" + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svelte-hmr@^0.14.12: + version "0.14.12" + resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.12.tgz#a127aec02f1896500b10148b2d4d21ddde39973f" + integrity sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w== + +svelte@^3.49.0: + version "3.49.0" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.49.0.tgz#5baee3c672306de1070c3b7888fc2204e36a4029" + integrity sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA== + +vite@^3.0.7: + version "3.0.9" + resolved "https://registry.yarnpkg.com/vite/-/vite-3.0.9.tgz#45fac22c2a5290a970f23d66c1aef56a04be8a30" + integrity sha512-waYABTM+G6DBTCpYAxvevpG50UOlZuynR0ckTK5PawNVt7ebX6X7wNXHaGIO6wYYFXSM7/WcuFuO2QzhBB6aMw== + dependencies: + esbuild "^0.14.47" + postcss "^8.4.16" + resolve "^1.22.1" + rollup ">=2.75.6 <2.77.0 || ~2.77.0" + optionalDependencies: + fsevents "~2.3.2" diff --git a/system-tests/projects/svelte-vite/cypress.config.js b/system-tests/projects/svelte-vite/cypress.config.js new file mode 100644 index 000000000000..2f63489eec8f --- /dev/null +++ b/system-tests/projects/svelte-vite/cypress.config.js @@ -0,0 +1,10 @@ +import { defineConfig } from 'cypress' + +export default defineConfig({ + component: { + devServer: { + framework: 'svelte', + bundler: 'vite', + }, + }, +}) diff --git a/system-tests/projects/svelte-vite/package.json b/system-tests/projects/svelte-vite/package.json new file mode 100644 index 000000000000..07b59117dc83 --- /dev/null +++ b/system-tests/projects/svelte-vite/package.json @@ -0,0 +1,12 @@ +{ + "name": "svelte-vite", + "version": "0.0.0", + "private": true, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^1.0.1", + "svelte": "^3.44.0", + "vite": "^3.0.0" + }, + "type": "module", + "projectFixtureDirectory": "svelte" +} diff --git a/system-tests/projects/svelte-vite/vite.config.js b/system-tests/projects/svelte-vite/vite.config.js new file mode 100644 index 000000000000..d70196943d0d --- /dev/null +++ b/system-tests/projects/svelte-vite/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()], +}) diff --git a/system-tests/projects/svelte-vite/yarn.lock b/system-tests/projects/svelte-vite/yarn.lock new file mode 100644 index 000000000000..f23a4149c41d --- /dev/null +++ b/system-tests/projects/svelte-vite/yarn.lock @@ -0,0 +1,295 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@esbuild/linux-loong64@0.14.54": + version "0.14.54" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028" + integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw== + +"@rollup/pluginutils@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" + integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== + dependencies: + estree-walker "^2.0.1" + picomatch "^2.2.2" + +"@sveltejs/vite-plugin-svelte@^1.0.1": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.2.tgz#d9997e9f1aeca7b5f72634e774c4f0c7207134b3" + integrity sha512-8tTVbNuraeDchBaArNbwaZLpO0feM7BRSdZU5yeM4Clasx2p1p1CYBoWh+VgxZlxiark49HXummkHqKztbl8lA== + dependencies: + "@rollup/pluginutils" "^4.2.1" + debug "^4.3.4" + deepmerge "^4.2.2" + kleur "^4.1.5" + magic-string "^0.26.2" + svelte-hmr "^0.14.12" + +debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +esbuild-android-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz#505f41832884313bbaffb27704b8bcaa2d8616be" + integrity sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ== + +esbuild-android-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz#8ce69d7caba49646e009968fe5754a21a9871771" + integrity sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg== + +esbuild-darwin-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz#24ba67b9a8cb890a3c08d9018f887cc221cdda25" + integrity sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug== + +esbuild-darwin-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz#3f7cdb78888ee05e488d250a2bdaab1fa671bf73" + integrity sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw== + +esbuild-freebsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz#09250f997a56ed4650f3e1979c905ffc40bbe94d" + integrity sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg== + +esbuild-freebsd-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz#bafb46ed04fc5f97cbdb016d86947a79579f8e48" + integrity sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q== + +esbuild-linux-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz#e2a8c4a8efdc355405325033fcebeb941f781fe5" + integrity sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw== + +esbuild-linux-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz#de5fdba1c95666cf72369f52b40b03be71226652" + integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg== + +esbuild-linux-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz#dae4cd42ae9787468b6a5c158da4c84e83b0ce8b" + integrity sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig== + +esbuild-linux-arm@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz#a2c1dff6d0f21dbe8fc6998a122675533ddfcd59" + integrity sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw== + +esbuild-linux-mips64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz#d9918e9e4cb972f8d6dae8e8655bf9ee131eda34" + integrity sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw== + +esbuild-linux-ppc64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz#3f9a0f6d41073fb1a640680845c7de52995f137e" + integrity sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ== + +esbuild-linux-riscv64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz#618853c028178a61837bc799d2013d4695e451c8" + integrity sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg== + +esbuild-linux-s390x@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz#d1885c4c5a76bbb5a0fe182e2c8c60eb9e29f2a6" + integrity sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA== + +esbuild-netbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz#69ae917a2ff241b7df1dbf22baf04bd330349e81" + integrity sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w== + +esbuild-openbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz#db4c8495287a350a6790de22edea247a57c5d47b" + integrity sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw== + +esbuild-sunos-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz#54287ee3da73d3844b721c21bc80c1dc7e1bf7da" + integrity sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw== + +esbuild-windows-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz#f8aaf9a5667630b40f0fb3aa37bf01bbd340ce31" + integrity sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w== + +esbuild-windows-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz#bf54b51bd3e9b0f1886ffdb224a4176031ea0af4" + integrity sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ== + +esbuild-windows-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz#937d15675a15e4b0e4fafdbaa3a01a776a2be982" + integrity sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg== + +esbuild@^0.14.47: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.54.tgz#8b44dcf2b0f1a66fc22459943dccf477535e9aa2" + integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA== + optionalDependencies: + "@esbuild/linux-loong64" "0.14.54" + esbuild-android-64 "0.14.54" + esbuild-android-arm64 "0.14.54" + esbuild-darwin-64 "0.14.54" + esbuild-darwin-arm64 "0.14.54" + esbuild-freebsd-64 "0.14.54" + esbuild-freebsd-arm64 "0.14.54" + esbuild-linux-32 "0.14.54" + esbuild-linux-64 "0.14.54" + esbuild-linux-arm "0.14.54" + esbuild-linux-arm64 "0.14.54" + esbuild-linux-mips64le "0.14.54" + esbuild-linux-ppc64le "0.14.54" + esbuild-linux-riscv64 "0.14.54" + esbuild-linux-s390x "0.14.54" + esbuild-netbsd-64 "0.14.54" + esbuild-openbsd-64 "0.14.54" + esbuild-sunos-64 "0.14.54" + esbuild-windows-32 "0.14.54" + esbuild-windows-64 "0.14.54" + esbuild-windows-arm64 "0.14.54" + +estree-walker@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +is-core-module@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + dependencies: + has "^1.0.3" + +kleur@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== + +magic-string@^0.26.2: + version "0.26.2" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.2.tgz#5331700e4158cd6befda738bb6b0c7b93c0d4432" + integrity sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A== + dependencies: + sourcemap-codec "^1.4.8" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.2.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +postcss@^8.4.16: + version "8.4.16" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" + integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +resolve@^1.22.1: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +"rollup@>=2.75.6 <2.77.0 || ~2.77.0": + version "2.77.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.77.3.tgz#8f00418d3a2740036e15deb653bed1a90ee0cc12" + integrity sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g== + optionalDependencies: + fsevents "~2.3.2" + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svelte-hmr@^0.14.12: + version "0.14.12" + resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.12.tgz#a127aec02f1896500b10148b2d4d21ddde39973f" + integrity sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w== + +svelte@^3.44.0: + version "3.49.0" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.49.0.tgz#5baee3c672306de1070c3b7888fc2204e36a4029" + integrity sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA== + +vite@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/vite/-/vite-3.0.9.tgz#45fac22c2a5290a970f23d66c1aef56a04be8a30" + integrity sha512-waYABTM+G6DBTCpYAxvevpG50UOlZuynR0ckTK5PawNVt7ebX6X7wNXHaGIO6wYYFXSM7/WcuFuO2QzhBB6aMw== + dependencies: + esbuild "^0.14.47" + postcss "^8.4.16" + resolve "^1.22.1" + rollup ">=2.75.6 <2.77.0 || ~2.77.0" + optionalDependencies: + fsevents "~2.3.2" diff --git a/system-tests/projects/svelte-webpack-unconfigured/package.json b/system-tests/projects/svelte-webpack-unconfigured/package.json new file mode 100644 index 000000000000..fd237045b83d --- /dev/null +++ b/system-tests/projects/svelte-webpack-unconfigured/package.json @@ -0,0 +1,18 @@ +{ + "name": "svelte-app", + "version": "1.0.0", + "scripts": { + "build": "cross-env NODE_ENV=production webpack", + "dev": "webpack serve --content-base public" + }, + "devDependencies": { + "cross-env": "^7.0.3", + "css-loader": "^5.0.1", + "mini-css-extract-plugin": "^1.3.4", + "svelte": "^3.31.2", + "svelte-loader": "^3.0.0", + "webpack": "^5.16.0", + "webpack-cli": "^4.4.0", + "webpack-dev-server": "^3.11.2" + } +} diff --git a/system-tests/projects/svelte-webpack-unconfigured/public/favicon.png b/system-tests/projects/svelte-webpack-unconfigured/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7e6f5eb5a2f1f1c882d265cf479de25caa925645 GIT binary patch literal 3127 zcmV-749N3|P)i z7)}s4L53SJCkR}iVi00SFk;`MXX*#X*kkwKs@nFGS}c;=?XFjU|G$3t^5sjIVS2G+ zw)WGF83CpoGXhLGW(1gW%uV|X7>1P6VhCX=Ux)Lb!*DZ%@I3!{Gsf7d?gtIQ%nQiK z3%(LUSkBji;C5Rfgd6$VsF@H`Pk@xtY6t<>FNR-pD}=C~$?)9pdm3XZ36N5PNWYjb z$xd$yNQR9N!dfj-Vd@BwQo^FIIWPPmT&sZyQ$v81(sCBV=PGy{0wltEjB%~h157*t zvbe_!{=I_783x!0t1-r#-d{Y?ae$Q4N_Nd^Ui^@y(%)Gjou6y<3^XJdu{rmUf-Me?)zZ>9OR&6U5H*cK; z$gUlB{g0O4gN0sLSO|Of?hU(l?;h(jA3uH!Z{EBKuV23ouU@^Y6#%v+QG;>e*E}%?wlu-NT4DG zs)z)7WbLr)vGAu(ohrKc^em@OpO&f~6_>E61n_e0_V3@{U3^O;j{`^mNCJUj_>;7v zsMs6Hu3g7+@v+lSo;=yTYFqq}jZmQ-BK8K{C4kqi_i*jBaQE(Au0607V-zKeT;EPg zX(`vrn=L+e74+-Tqeok@_`tDa$G9I|$nTU5H*2V8@y()n*zqM?J1G!-1aX;CfDC9B zTnJ#j_%*n8Qb1)re*Bno7g0RG{Eb;IK14irJYJp$5Z6ac9~b_P?+5t~95~SRG$g?1 znFJ7p$xV&GZ18m~79TGRdfsc-BcX$9yXTR*n)mPD@1~O(_?cT$ZvFPucRmGlq&se0 zKrcUf^k}4hM*biEJOWKzz!qQe;CB_ZtSOO9Owg#lZAc=s65^rb{fZe(TYu_rk!wKkEf}RIt=#Om( zR8mN`DM<^xj~59euMMspBolVN zAPTr8sSDI104orIAdmL$uOXn*6hga1G+0WD0E?UtabxC#VC~vf3|10|phW;yQ3CY8 z2CM=)ErF;xq-YJ5G|um}>*1#E+O_Mu|Nr#qQ&G1P-NMq@f?@*XUcSbV?tX=)ilM-Q zBZP|!Bpv0V;#ojKcpc7$=eqO;#Uy~#?^kNI{vSZfLx&DEt~LTmaKWXcx=joubklI<*Aw z>LtMaQ7DR<1I2LkWvwyu#Rwn~;ezT}_g(@5l3h?W%-a86Y-t#O1PubP+z<%?V5D(U zy57A6{h+{?kOZp7&WKZR+=sznMJ}+Dnpo=C_0%R_x_t~J5T?E_{+))l5v1%52>)d-`iiZyx|5!%M2Fb2dU zW3~MwwpEH9Rhue+k$UIOoo($Ds!NbOyMR36fRHu;*15(YcA7siIZk#%JWz>P!qX1?IUojG&nKR>^gArBt2 zit(ETyZ=@V&7mv_Fi4bABcnwP+jzQuHcfU&BrAV91u-rFvEi7y-KnWsvHH=d2 zgAk(GKm_S8RcTJ>2N3~&Hbwp{Z3NF_Xeh}g4Eke)V&dY{W(3&b1j9t4yK_aYJisZZ{1rcU5- z;eD>K;ndPq&B-8yA_S0F!4ThA&{1{x)H<#?k9a#6Pc6L?V^s0``ynL&D;p(!Nmx`Y zFkHex{4p!Ggm^@DlehW}iHHVi}~u=$&N? z(NEBLQ#UxxAkdW>X9LnqUr#t4Lu0=9L8&o>JsqTtT5|%gb3QA~hr0pED71+iFFr)dZ=Q=E6ng{NE{Z~0)C?deO#?Aj zSDQ$z#TeC2T^|=}6GBo-&$;E{HL3!q3Z-szuf)O=G#zDjin4SSP%o%6+2IT#sLjQa ziyxFFz~LMjWY+_a5H!U6%a<=b7QVP^ z*90a62;bVq{?@)P6^DWd^Yilq4|YTV2Nw!Yu;a1lPI-sxR)rf@Fe5DhDP7FH zZZ%4S*1C30P;|O+jB!1;m|rXT90Sm5*RBbQN`PKu+hDD*S^yE(CdtSfg=z>u$cIj> z + + + + + + Svelte app + + + + + + + + + + diff --git a/system-tests/projects/svelte-webpack-unconfigured/scripts/setupTypeScript.js b/system-tests/projects/svelte-webpack-unconfigured/scripts/setupTypeScript.js new file mode 100644 index 000000000000..155676295a42 --- /dev/null +++ b/system-tests/projects/svelte-webpack-unconfigured/scripts/setupTypeScript.js @@ -0,0 +1,210 @@ +/** + * Run this script to convert the project to TypeScript. This is only guaranteed to work + * on the unmodified default template; if you have done code changes you are likely need + * to touch up the generated project manually. + */ + +// @ts-check +const fs = require('fs') +const path = require('path') +const { argv } = require('process') + +const projectRoot = argv[2] || path.join(__dirname, '..') + +function warn (message) { + console.warn(`Warning: ${ message}`) +} + +function createFile (fileName, contents) { + if (fs.existsSync(fileName)) { + warn(`Wanted to create ${fileName}, but it already existed. Leaving existing file.`) + } else { + fs.writeFileSync(fileName, contents) + } +} + +function replaceInFile (fileName, replacements) { + if (fs.existsSync(fileName)) { + let contents = fs.readFileSync(fileName, 'utf8') + let hadUpdates = false + + replacements.forEach(([from, to]) => { + const newContents = contents.replace(from, to) + + const isAlreadyApplied = typeof to !== 'string' || contents.includes(to) + + if (newContents !== contents) { + contents = newContents + hadUpdates = true + } else if (!isAlreadyApplied) { + warn(`Wanted to update "${from}" in ${fileName}, but did not find it.`) + } + }) + + if (hadUpdates) { + fs.writeFileSync(fileName, contents) + } else { + console.log(`${fileName} had already been updated.`) + } + } else { + warn(`Wanted to update ${fileName} but the file did not exist.`) + } +} + +// Add deps to pkg.json +function addDepsToPackageJson () { + const pkgJSONPath = path.join(projectRoot, 'package.json') + const packageJSON = JSON.parse(fs.readFileSync(pkgJSONPath, 'utf8')) + + packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, { + 'ts-loader': '^8.0.4', + '@tsconfig/svelte': '^1.0.10', + '@types/node': '^14.11.1', + 'svelte-check': '^1.0.46', + 'svelte-preprocess': '^4.3.0', + tslib: '^2.0.1', + typescript: '^4.0.3', + }) + + // Add script for checking + packageJSON.scripts = Object.assign(packageJSON.scripts, { + validate: 'svelte-check', + }) + + // Write the package JSON + fs.writeFileSync(pkgJSONPath, JSON.stringify(packageJSON, null, ' ')) +} + +// mv src/main.js to main.ts - note, we need to edit rollup.config.js for this too +function changeJsExtensionToTs (dir) { + const elements = fs.readdirSync(dir, { withFileTypes: true }) + + for (let i = 0; i < elements.length; i++) { + if (elements[i].isDirectory()) { + changeJsExtensionToTs(path.join(dir, elements[i].name)) + } else if (elements[i].name.match(/^[^_]((?!json).)*js$/)) { + fs.renameSync(path.join(dir, elements[i].name), path.join(dir, elements[i].name).replace('.js', '.ts')) + } + } +} + +function updateSingleSvelteFile ({ view, vars, contextModule }) { + replaceInFile(path.join(projectRoot, 'src', `${view}.svelte`), [ + [/(?:/gm, (m, attrs) => ``], + ...(vars ? vars.map(({ name, type }) => [`export let ${name};`, `export let ${name}: ${type};`]) : []), + ...(contextModule ? contextModule.map(({ js, ts }) => [js, ts]) : []), + ]) +} + +// Switch the App.svelte file to use TS +function updateSvelteFiles () { + [ + { + view: 'App', + vars: [{ name: 'name', type: 'string' }], + }, + ].forEach(updateSingleSvelteFile) +} + +function updateWebpackConfig () { + // Edit webpack config + replaceInFile(path.join(projectRoot, 'webpack.config.js'), [ + // Edit imports + [ + /require\('path'\);\n(?!const sveltePreprocess)/, + `require('path');\nconst sveltePreprocess = require('svelte-preprocess');\n`, + ], + // Edit extensions + [ + /'\.js',/, + `'.js', '.ts',`, + ], + // Edit name of entry point + [ + /'\.\/src\/main.js'/, + `'./src/main.ts'`, + ], + // Add preprocess to the svelte loader, this is tricky because there's no easy signifier. + // Instead we look for 'hotReload: 'prod,' + [ + /hotReload: \!prod(?!,\n\s*preprocess)/g, + 'hotReload: !prod,\n\t\t\t\t\t\t\tpreprocess: sveltePreprocess({ sourceMap: !prod })', + ], + // Add ts-loader + [ + /module: {\n\s*rules: \[\n\s*(?!{\n\s*test: \/\\\.ts\$\/)/g, + `module: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.ts$/,\n\t\t\t\t\tloader: 'ts-loader',\n\t\t\t\t\texclude: /node_modules/\n\t\t\t\t},\n\t\t\t\t`, + ], + ]) +} + +// Add TSConfig +function createTsConfig () { + const tsconfig = `{ + "extends": "@tsconfig/svelte/tsconfig.json", + "include": ["src/**/*", "src/node_modules/**/*"], + "exclude": ["node_modules/*", "__sapper__/*", "static/*"] + }` + + createFile(path.join(projectRoot, 'tsconfig.json'), tsconfig) +} + +// Adds the extension recommendation +function configureVsCode () { + const dir = path.join(projectRoot, '.vscode') + + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir) + } + + createFile(path.join(projectRoot, '.vscode', 'extensions.json'), `{"recommendations": ["svelte.svelte-vscode"]}`) +} + +function deleteThisScript () { + fs.unlinkSync(path.join(__filename)) + + // Check for Mac's DS_store file, and if it's the only one left remove it + const remainingFiles = fs.readdirSync(path.join(__dirname)) + + if (remainingFiles.length === 1 && remainingFiles[0] === '.DS_store') { + fs.unlinkSync(path.join(__dirname, '.DS_store')) + } + + // Check if the scripts folder is empty + if (fs.readdirSync(path.join(__dirname)).length === 0) { + // Remove the scripts folder + try { + fs.rmdirSync(path.join(__dirname)) + } catch (e) { + warn(`Cannot delete locked directory ${__dirname}`) + } + } +} + +console.log(`Adding TypeScript...`) + +addDepsToPackageJson() + +changeJsExtensionToTs(path.join(projectRoot, 'src')) + +updateSvelteFiles() + +updateWebpackConfig() + +createTsConfig() + +configureVsCode() + +// Delete this script, but not during testing +if (!argv[2]) { + deleteThisScript() +} + +console.log('Converted to TypeScript.') + +if (fs.existsSync(path.join(projectRoot, 'node_modules'))) { + console.log(` +Next: +1. run 'npm install' again to install TypeScript dependencies +`) +} diff --git a/system-tests/projects/svelte-webpack-unconfigured/src/App.svelte b/system-tests/projects/svelte-webpack-unconfigured/src/App.svelte new file mode 100644 index 000000000000..bdc486ab884d --- /dev/null +++ b/system-tests/projects/svelte-webpack-unconfigured/src/App.svelte @@ -0,0 +1,30 @@ + + +
+

Hello {name}!

+

Visit the Svelte tutorial to learn how to build Svelte apps.

+
+ + diff --git a/system-tests/projects/svelte-webpack-unconfigured/src/global.css b/system-tests/projects/svelte-webpack-unconfigured/src/global.css new file mode 100644 index 000000000000..bb28a9414d45 --- /dev/null +++ b/system-tests/projects/svelte-webpack-unconfigured/src/global.css @@ -0,0 +1,63 @@ +html, body { + position: relative; + width: 100%; + height: 100%; +} + +body { + color: #333; + margin: 0; + padding: 8px; + box-sizing: border-box; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; +} + +a { + color: rgb(0,100,200); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +a:visited { + color: rgb(0,80,160); +} + +label { + display: block; +} + +input, button, select, textarea { + font-family: inherit; + font-size: inherit; + -webkit-padding: 0.4em 0; + padding: 0.4em; + margin: 0 0 0.5em 0; + box-sizing: border-box; + border: 1px solid #ccc; + border-radius: 2px; +} + +input:disabled { + color: #ccc; +} + +button { + color: #333; + background-color: #f4f4f4; + outline: none; +} + +button:disabled { + color: #999; +} + +button:not(:disabled):active { + background-color: #ddd; +} + +button:focus { + border-color: #666; +} diff --git a/system-tests/projects/svelte-webpack-unconfigured/src/main.js b/system-tests/projects/svelte-webpack-unconfigured/src/main.js new file mode 100644 index 000000000000..c8fad53ee752 --- /dev/null +++ b/system-tests/projects/svelte-webpack-unconfigured/src/main.js @@ -0,0 +1,12 @@ +import './global.css' + +import App from './App.svelte' + +const app = new App({ + target: document.body, + props: { + name: 'world', + }, +}) + +export default app diff --git a/system-tests/projects/svelte-webpack-unconfigured/webpack.config.js b/system-tests/projects/svelte-webpack-unconfigured/webpack.config.js new file mode 100644 index 000000000000..dd8727789aa0 --- /dev/null +++ b/system-tests/projects/svelte-webpack-unconfigured/webpack.config.js @@ -0,0 +1,64 @@ +const MiniCssExtractPlugin = require('mini-css-extract-plugin') +const path = require('path') + +const mode = process.env.NODE_ENV || 'development' +const prod = mode === 'production' + +module.exports = { + entry: { + 'build/bundle': ['./src/main.js'], + }, + resolve: { + alias: { + svelte: path.dirname(require.resolve('svelte/package.json')), + }, + extensions: ['.mjs', '.js', '.svelte'], + mainFields: ['svelte', 'browser', 'module', 'main'], + }, + output: { + path: path.join(__dirname, '/public'), + filename: '[name].js', + chunkFilename: '[name].[id].js', + }, + module: { + rules: [ + { + test: /\.svelte$/, + use: { + loader: 'svelte-loader', + options: { + compilerOptions: { + dev: !prod, + }, + emitCss: prod, + hotReload: !prod, + }, + }, + }, + { + test: /\.css$/, + use: [ + MiniCssExtractPlugin.loader, + 'css-loader', + ], + }, + { + // required to prevent errors from Svelte on Webpack 5+ + test: /node_modules\/svelte\/.*\.mjs$/, + resolve: { + fullySpecified: false, + }, + }, + ], + }, + mode, + plugins: [ + new MiniCssExtractPlugin({ + filename: '[name].css', + }), + ], + devtool: prod ? false : 'source-map', + devServer: { + hot: true, + }, +} diff --git a/system-tests/projects/svelte-webpack-unconfigured/yarn.lock b/system-tests/projects/svelte-webpack-unconfigured/yarn.lock new file mode 100644 index 000000000000..f911b0162a7e --- /dev/null +++ b/system-tests/projects/svelte-webpack-unconfigured/yarn.lock @@ -0,0 +1,3304 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.4.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.6.tgz#7976f054c1bccfcf514bff0564c0c41df5c08207" + integrity sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/glob@^7.1.1": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/minimatch@*": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + +"@types/node@*": + version "18.7.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.6.tgz#31743bc5772b6ac223845e18c3fc26f042713c83" + integrity sha512-EdxgKRXgYsNITy5mjjXjVE/CS8YENSdhiagGrLqjG0pvA2owgJ6i4l7wy/PFZGC0B1/H20lWKN7ONVDNYDZm7A== + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" + integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== + +"@webpack-cli/info@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" + integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" + integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.5.0, acorn@^8.7.1: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.1.0, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + +ansi-html-community@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + +ansi-regex@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== + +ansi-styles@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-flatten@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" + integrity sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg== + dependencies: + array-flatten "^2.1.0" + deep-equal "^1.0.1" + dns-equal "^1.0.0" + dns-txt "^2.0.2" + multicast-dns "^6.0.1" + multicast-dns-service-types "^1.1.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +browserslist@^4.14.5: + version "4.21.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" + integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== + dependencies: + caniuse-lite "^1.0.30001370" + electron-to-chromium "^1.4.202" + node-releases "^2.0.6" + update-browserslist-db "^1.0.5" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-indexof@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" + integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30001370: + version "1.0.30001378" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001378.tgz#3d2159bf5a8f9ca093275b0d3ecc717b00f27b67" + integrity sha512-JVQnfoO7FK7WvU4ZkBRbPjaot4+YqxogSDosHv0Hv5mWpUESmN+UubMU6L/hGz8QlQ2aY5U0vR6MOs6j/CXpNA== + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +colorette@^2.0.14: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.1, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-loader@^5.0.1: + version "5.2.7" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" + integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg== + dependencies: + icss-utils "^5.1.0" + loader-utils "^2.0.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^3.0.0" + semver "^7.3.5" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +default-gateway@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" + integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== + dependencies: + execa "^1.0.0" + ip-regex "^2.1.0" + +define-properties@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + +dns-packet@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== + dependencies: + ip "^1.1.0" + safe-buffer "^5.0.1" + +dns-txt@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" + integrity sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ== + dependencies: + buffer-indexof "^1.0.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.202: + version "1.4.225" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.225.tgz#3e27bdd157cbaf19768141f2e0f0f45071e52338" + integrity sha512-ICHvGaCIQR3P88uK8aRtx8gmejbVJyC6bB4LEC3anzBrIzdzC7aiZHY4iFfXhN4st6I7lMO0x4sgBHf/7kBvRw== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +errno@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +eventsource@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-2.0.2.tgz#76dfcc02930fb2ff339520b6d290da573a9e8508" + integrity sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA== + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +express@^4.17.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.0" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.10.3" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + +faye-websocket@^0.11.3, faye-websocket@^0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +file-uri-to-path@1.0.0: + version "1.0.0" + 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== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +follow-redirects@^1.0.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.0.3, glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw== + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +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-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" + integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-middleware@0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" + integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== + dependencies: + http-proxy "^1.17.0" + is-glob "^4.0.0" + lodash "^4.17.11" + micromatch "^3.1.10" + +http-proxy@^1.17.0: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +internal-ip@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" + integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== + dependencies: + default-gateway "^4.2.0" + ipaddr.js "^1.9.0" + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +ip-regex@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== + +ip@^1.1.0, ip@^1.1.5: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" + integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== + +ipaddr.js@1.9.1, ipaddr.js@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-core-module@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.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 sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== + dependencies: + kind-of "^3.0.2" + +is-path-cwd@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.0.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== + +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 sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json5@^2.1.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +killable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" + integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +loader-utils@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" + integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash@^4.17.11, lodash@^4.17.14: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +loglevel@^1.6.8: + version "1.8.0" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.0.tgz#e7ec73a57e1e7b419cb6c6ac06bf050b67356114" + integrity sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== + dependencies: + object-visit "^1.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.4.4: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mini-css-extract-plugin@^1.3.4: + version "1.6.2" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz#83172b4fd812f8fc4a09d6f6d16f924f53990ca8" + integrity sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + webpack-sources "^1.1.0" + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.1, mkdirp@^0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns-service-types@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" + integrity sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ== + +multicast-dns@^6.0.1: + version "6.2.3" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" + integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== + dependencies: + dns-packet "^1.3.1" + thunky "^1.0.2" + +nan@^2.12.1: + version "2.16.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916" + integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA== + +nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-forge@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== + dependencies: + path-key "^2.0.0" + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== + dependencies: + isobject "^3.0.0" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + dependencies: + isobject "^3.0.1" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +opn@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" + integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== + dependencies: + is-wsl "^1.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-retry@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" + integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== + dependencies: + retry "^0.12.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +portfinder@^1.0.26: + version "1.0.32" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81" + integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg== + dependencies: + async "^2.6.4" + debug "^3.2.7" + mkdirp "^0.5.6" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.10" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.2.15: + version "8.4.16" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" + integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^2.0.1, readable-stream@^2.0.2: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.2.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + +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 sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg== + dependencies: + resolve-from "^3.0.0" + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + +resolve@^1.9.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + +rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^1.10.8: + version "1.10.14" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574" + integrity sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA== + dependencies: + node-forge "^0.10.0" + +semver@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.5: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sockjs-client@^1.5.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.6.1.tgz#350b8eda42d6d52ddc030c39943364c11dcad806" + integrity sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw== + dependencies: + debug "^3.2.7" + eventsource "^2.0.2" + faye-websocket "^0.11.4" + inherits "^2.0.4" + url-parse "^1.5.10" + +sockjs@^0.3.21: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +source-map@^0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svelte-dev-helper@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/svelte-dev-helper/-/svelte-dev-helper-1.1.9.tgz#7d187db5c6cdbbd64d75a32f91b8998bde3273c3" + integrity sha512-oU+Xv7Dl4kRU2kdFjsoPLfJfnt5hUhsFUZtuzI3Ku/f2iAFZqBoEuXOqK3N9ngD4dxQOmN4OKWPHVi3NeAeAfQ== + +svelte-hmr@^0.14.2: + version "0.14.12" + resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.12.tgz#a127aec02f1896500b10148b2d4d21ddde39973f" + integrity sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w== + +svelte-loader@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/svelte-loader/-/svelte-loader-3.1.3.tgz#3e24930bfe9b3d94b82e276eb844016d138fe646" + integrity sha512-B7HsKRrWaGB9RFef1t7JXbQ1npG/6J/Tka/ehv6pkxJx+QU9Dd8Sdi415IfhogpWEmH95VgsaWNrNU2GeBJ1VQ== + dependencies: + loader-utils "^2.0.0" + svelte-dev-helper "^1.1.9" + svelte-hmr "^0.14.2" + +svelte@^3.31.2: + version "3.49.0" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.49.0.tgz#5baee3c672306de1070c3b7888fc2204e36a4029" + integrity sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.1.3: + version "5.3.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.5.tgz#f7d82286031f915a4f8fb81af4bd35d2e3c011bc" + integrity sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.14" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + terser "^5.14.1" + +terser@^5.14.1: + version "5.14.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +update-browserslist-db@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + +url-parse@^1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ== + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-cli@^4.4.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" + integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.2.0" + "@webpack-cli/info" "^1.5.0" + "@webpack-cli/serve" "^1.7.0" + colorette "^2.0.14" + commander "^7.0.0" + cross-spawn "^7.0.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-dev-middleware@^3.7.2: + version "3.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-dev-server@^3.11.2: + version "3.11.3" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.3.tgz#8c86b9d2812bf135d3c9bce6f07b718e30f7c3d3" + integrity sha512-3x31rjbEQWKMNzacUZRE6wXvUFuGpH7vr0lIEbYpMAG9BOxi0928QU1BBswOAP3kg3H1O4hiS+sq4YyAn6ANnA== + dependencies: + ansi-html-community "0.0.8" + bonjour "^3.5.0" + chokidar "^2.1.8" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + debug "^4.1.1" + del "^4.1.1" + express "^4.17.1" + html-entities "^1.3.1" + http-proxy-middleware "0.19.1" + import-local "^2.0.0" + internal-ip "^4.3.0" + ip "^1.1.5" + is-absolute-url "^3.0.3" + killable "^1.0.1" + loglevel "^1.6.8" + opn "^5.5.0" + p-retry "^3.0.1" + portfinder "^1.0.26" + schema-utils "^1.0.0" + selfsigned "^1.10.8" + semver "^6.3.0" + serve-index "^1.9.1" + sockjs "^0.3.21" + sockjs-client "^1.5.0" + spdy "^4.0.2" + strip-ansi "^3.0.1" + supports-color "^6.1.0" + url "^0.11.0" + webpack-dev-middleware "^3.7.2" + webpack-log "^2.0.0" + ws "^6.2.1" + yargs "^13.3.2" + +webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + +webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^1.1.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5.16.0: + version "5.74.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" + integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.10.0" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^6.2.1: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" + integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== + dependencies: + async-limiter "~1.0.0" + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" diff --git a/system-tests/projects/svelte-webpack/cypress.config.js b/system-tests/projects/svelte-webpack/cypress.config.js new file mode 100644 index 000000000000..d29c623408ee --- /dev/null +++ b/system-tests/projects/svelte-webpack/cypress.config.js @@ -0,0 +1,10 @@ +const { defineConfig } = require('cypress') + +module.exports = defineConfig({ + component: { + devServer: { + framework: 'svelte', + bundler: 'webpack', + }, + }, +}) diff --git a/system-tests/projects/svelte-webpack/package.json b/system-tests/projects/svelte-webpack/package.json new file mode 100644 index 000000000000..e4dc622dabce --- /dev/null +++ b/system-tests/projects/svelte-webpack/package.json @@ -0,0 +1,15 @@ +{ + "name": "svelte-webpack", + "version": "0.0.0", + "private": true, + "devDependencies": { + "css-loader": "^6.7.1", + "html-webpack-plugin": "^5.5.0", + "mini-css-extract-plugin": "^2.6.1", + "svelte": "^3.44.0", + "svelte-loader": "^3.1.3", + "webpack": "^5.74.0", + "webpack-dev-server": "^4.10.0" + }, + "projectFixtureDirectory": "svelte" +} diff --git a/system-tests/projects/svelte-webpack/webpack.config.js b/system-tests/projects/svelte-webpack/webpack.config.js new file mode 100644 index 000000000000..e03ebdcb3f93 --- /dev/null +++ b/system-tests/projects/svelte-webpack/webpack.config.js @@ -0,0 +1,39 @@ +const MiniCssExtractPlugin = require('mini-css-extract-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') + +module.exports = { + mode: 'development', + entry: './src/main.js', + resolve: { + extensions: ['.mjs', '.js', '.svelte'], + }, + module: { + rules: [ + { + test: /\.svelte$/, + use: { + loader: 'svelte-loader', + }, + }, + { + test: /\.css$/, + use: [MiniCssExtractPlugin.loader, 'css-loader'], + }, + { + test: /node_modules\/svelte\/.*\.mjs$/, + resolve: { + fullySpecified: false, + }, + }, + ], + }, + plugins: [ + new MiniCssExtractPlugin({ + filename: '[name].css', + }), + new HtmlWebpackPlugin({ + template: './public/index.html', + }), + ], + devtool: 'source-map', +} diff --git a/system-tests/projects/svelte-webpack/yarn.lock b/system-tests/projects/svelte-webpack/yarn.lock new file mode 100644 index 000000000000..8dd460fb5077 --- /dev/null +++ b/system-tests/projects/svelte-webpack/yarn.lock @@ -0,0 +1,2225 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.4.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.6.tgz#7976f054c1bccfcf514bff0564c0c41df5c08207" + integrity sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.30" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz#0f2f99617fa8f9696170c46152ccf7500b34ac04" + integrity sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== + +"@types/http-proxy@^1.17.8": + version "1.17.9" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" + integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== + dependencies: + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/node@*": + version "18.7.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.9.tgz#180bfc495c91dc62573967edf047e15dbdce1491" + integrity sha512-0N5Y1XAdcl865nDdjbO0m3T6FdmQ4ijE89/urOHLREyTXbpMWbSafx9y7XIsgWGtwUP2iYTinLyyW3FatAxBLQ== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" + integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.5.0, acorn@^8.7.1: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.8.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.0.13" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.13.tgz#4ac003dc1626023252d58adf2946f57e5da450c1" + integrity sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.14.5: + version "4.21.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" + integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== + dependencies: + caniuse-lite "^1.0.30001370" + electron-to-chromium "^1.4.202" + node-releases "^2.0.6" + update-browserslist-db "^1.0.5" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +caniuse-lite@^1.0.30001370: + version "1.0.30001381" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001381.tgz#e62955310e6e69cdf4b40bc5bc0895aa24bc4b8b" + integrity sha512-fEnkDOKpvp6qc+olg7+NzE1SqyfiyKf4uci7fAU38M3zxs0YOyKOxW/nMZ2l9sJbt7KZHcDIxUnbI0Iime7V4w== + +chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +clean-css@^5.2.2: + version "5.3.1" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" + integrity sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg== + dependencies: + source-map "~0.6.0" + +colorette@^2.0.10: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-loader@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" + integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.7" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.5" + +css-select@^4.1.3: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== + dependencies: + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + +dns-packet@^5.2.2: + version "5.4.0" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" + integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.202: + version "1.4.225" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.225.tgz#3e27bdd157cbaf19768141f2e0f0f45071e52338" + integrity sha512-ICHvGaCIQR3P88uK8aRtx8gmejbVJyC6bB4LEC3anzBrIzdzC7aiZHY4iFfXhN4st6I7lMO0x4sgBHf/7kBvRw== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +enhanced-resolve@^5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.3: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.0" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.10.3" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +follow-redirects@^1.0.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-monkey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +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-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" + integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + +html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== + dependencies: + camel-case "^4.1.2" + clean-css "^5.2.2" + commander "^8.3.0" + he "^1.2.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.10.0" + +html-webpack-plugin@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" + integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== + dependencies: + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json5@^2.1.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +loader-utils@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129" + integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +lodash@^4.17.20, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.4.3: + version "3.4.7" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" + integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== + dependencies: + fs-monkey "^1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mini-css-extract-plugin@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz#9a1251d15f2035c342d99a468ab9da7a0451b71e" + integrity sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg== + dependencies: + schema-utils "^4.0.0" + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + +nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.10" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.7: + version "8.4.16" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" + integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +pretty-error@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== + dependencies: + lodash "^4.17.20" + renderkid "^3.0.0" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^2.0.1: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== + +renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^6.0.1" + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" + integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== + dependencies: + node-forge "^1" + +semver@^7.3.5: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +svelte-dev-helper@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/svelte-dev-helper/-/svelte-dev-helper-1.1.9.tgz#7d187db5c6cdbbd64d75a32f91b8998bde3273c3" + integrity sha512-oU+Xv7Dl4kRU2kdFjsoPLfJfnt5hUhsFUZtuzI3Ku/f2iAFZqBoEuXOqK3N9ngD4dxQOmN4OKWPHVi3NeAeAfQ== + +svelte-hmr@^0.14.2: + version "0.14.12" + resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.12.tgz#a127aec02f1896500b10148b2d4d21ddde39973f" + integrity sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w== + +svelte-loader@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/svelte-loader/-/svelte-loader-3.1.3.tgz#3e24930bfe9b3d94b82e276eb844016d138fe646" + integrity sha512-B7HsKRrWaGB9RFef1t7JXbQ1npG/6J/Tka/ehv6pkxJx+QU9Dd8Sdi415IfhogpWEmH95VgsaWNrNU2GeBJ1VQ== + dependencies: + loader-utils "^2.0.0" + svelte-dev-helper "^1.1.9" + svelte-hmr "^0.14.2" + +svelte@^3.44.0: + version "3.49.0" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.49.0.tgz#5baee3c672306de1070c3b7888fc2204e36a4029" + integrity sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA== + +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.1.3: + version "5.3.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.5.tgz#f7d82286031f915a4f8fb81af4bd35d2e3c011bc" + integrity sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.14" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + terser "^5.14.1" + +terser@^5.10.0, terser@^5.14.1: + version "5.14.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tslib@^2.0.3: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@^4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.10.0.tgz#de270d0009eba050546912be90116e7fd740a9ca" + integrity sha512-7dezwAs+k6yXVFZ+MaL8VnE+APobiO3zvpp3rBHe/HmWQ+avwh0Q3d0xxacOiBybZZ3syTZw9HXzpa3YNbAZDQ== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.0.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5.74.0: + version "5.74.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" + integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.10.0" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^8.4.2: + version "8.8.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" + integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/system-tests/test/component_testing_spec.ts b/system-tests/test/component_testing_spec.ts index 8f29b1c82ba0..b2ee8e799c0b 100644 --- a/system-tests/test/component_testing_spec.ts +++ b/system-tests/test/component_testing_spec.ts @@ -133,6 +133,20 @@ describe(`Angular CLI major versions`, () => { }) }) +describe('svelte component testing', () => { + systemTests.setup() + + for (const bundler of ['webpack', 'vite']) { + systemTests.it(`svelte + ${bundler}`, { + project: `svelte-${bundler}`, + testingType: 'component', + spec: '**/*.cy.js', + browser: 'chrome', + expectedExitCode: 0, + }) + } +}) + describe('experimentalSingleTabRunMode', function () { systemTests.setup() diff --git a/yarn.lock b/yarn.lock index f1470d93735a..28d61b8a5163 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9466,7 +9466,7 @@ babel-extract-comments@^1.0.0: dependencies: babylon "^6.18.0" -babel-generator@^6.18.0, babel-generator@^6.26.0: +babel-generator@^6.26.0: version "6.26.1" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== @@ -10363,7 +10363,7 @@ babel-runtime@^6.18.0, babel-runtime@^6.20.0, babel-runtime@^6.22.0, babel-runti core-js "^2.4.0" regenerator-runtime "^0.11.0" -babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: +babel-template@^6.24.1, babel-template@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= @@ -10374,7 +10374,7 @@ babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: babylon "^6.18.0" lodash "^4.17.4" -babel-traverse@^6.18.0, babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-traverse@^6.26.0: +babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-traverse@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= @@ -10389,7 +10389,7 @@ babel-traverse@^6.18.0, babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-tr invariant "^2.2.2" lodash "^4.17.4" -babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.26.0: +babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= @@ -15825,11 +15825,6 @@ estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -estree-walker@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" - integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== - estree-walker@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" @@ -20552,11 +20547,6 @@ issue-parser@^6.0.0: lodash.isstring "^4.0.1" lodash.uniqby "^4.7.0" -istanbul-lib-coverage@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" - integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== - istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" @@ -20567,19 +20557,6 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.1: resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-instrument@^1.9.1: - version "1.10.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" - integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== - dependencies: - babel-generator "^6.18.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.18.0" - istanbul-lib-coverage "^1.2.1" - semver "^5.3.0" - istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" @@ -29591,14 +29568,6 @@ rollup-plugin-copy@3.4.0: globby "10.0.1" is-plain-object "^3.0.0" -rollup-plugin-istanbul@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-istanbul/-/rollup-plugin-istanbul-2.0.1.tgz#f562d378b4082855ef035e63c04d9ee1bd601c20" - integrity sha512-5X1ExH74moFY/pHqCrAZQ0V8RyEMCmrUSuo1t1bDzv9UHTd54s79ALDaK8N87PgNzA6UuKtBVAP/tsaSYzIUVQ== - dependencies: - istanbul-lib-instrument "^1.9.1" - rollup-pluginutils "^2.0.1" - rollup-plugin-node-builtins@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/rollup-plugin-node-builtins/-/rollup-plugin-node-builtins-2.1.2.tgz#24a1fed4a43257b6b64371d8abc6ce1ab14597e9" @@ -29627,13 +29596,6 @@ rollup-plugin-typescript2@^0.29.0: resolve "1.17.0" tslib "2.0.1" -rollup-pluginutils@^2.0.1: - version "2.8.2" - resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" - integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== - dependencies: - estree-walker "^0.6.1" - rollup@^2.38.5, rollup@^2.75.6: version "2.77.0" resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.77.0.tgz#749eaa5ac09b6baa52acc076bc46613eddfd53f4" @@ -31944,6 +31906,11 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +svelte@^3.49.0: + version "3.49.0" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.49.0.tgz#5baee3c672306de1070c3b7888fc2204e36a4029" + integrity sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA== + sver-compat@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" From b08bc270e90db72e7bdafc4eb80cc38c8463ccb1 Mon Sep 17 00:00:00 2001 From: Emily Rohrbough Date: Sun, 28 Aug 2022 21:15:05 -0500 Subject: [PATCH 36/45] chore: remove dead code -- lives in data-context/src/sources/HtmlDataSource.ts now (#23542) --- packages/server/lib/controllers/runner.ts | 96 +---------------------- packages/server/lib/routes.ts | 7 +- packages/server/lib/server-base.ts | 2 - packages/server/test/unit/runner_spec.js | 19 ----- 4 files changed, 4 insertions(+), 120 deletions(-) delete mode 100644 packages/server/test/unit/runner_spec.js diff --git a/packages/server/lib/controllers/runner.ts b/packages/server/lib/controllers/runner.ts index 64b759ea1482..ef8e09ccbbd0 100644 --- a/packages/server/lib/controllers/runner.ts +++ b/packages/server/lib/controllers/runner.ts @@ -1,101 +1,11 @@ -import _ from 'lodash' import type { Request, Response } from 'express' import send from 'send' -import os from 'os' -import { fs } from '../util/fs' -import path from 'path' -import Debug from 'debug' -import pkg from '@packages/root' -import { getPathToDist, getPathToIndex, RunnerPkg } from '@packages/resolve-dist' -import type { InitializeRoutes } from '../routes' -import type { PlatformName } from '@packages/types' -import type { Cfg } from '../project-base' - -const debug = Debug('cypress:server:runner') - -const PATH_TO_NON_PROXIED_ERROR = path.join(__dirname, '..', 'html', 'non_proxied_error.html') - -const _serveNonProxiedError = (res: Response) => { - return fs.readFile(PATH_TO_NON_PROXIED_ERROR) - .then((html) => { - return res.type('html').end(html) - }) -} - -export interface ServeOptions extends Pick { - testingType: Cypress.TestingType -} - -export const serveRunner = (runnerPkg: RunnerPkg, config: Cfg, res: Response) => { - // base64 before embedding so user-supplied contents can't break out of diff --git a/packages/app/src/runner/SpecRunnerOpenMode.vue b/packages/app/src/runner/SpecRunnerOpenMode.vue index efa65c8d5298..4bfa040d18cd 100644 --- a/packages/app/src/runner/SpecRunnerOpenMode.vue +++ b/packages/app/src/runner/SpecRunnerOpenMode.vue @@ -1,4 +1,12 @@