diff --git a/.vscode/cspell.json b/.vscode/cspell.json
index 0d635abffbad..5649488074b9 100644
--- a/.vscode/cspell.json
+++ b/.vscode/cspell.json
@@ -6,27 +6,41 @@
"words": [
"Chainable",
"composables",
+ "dedup",
"ERRORED",
"execa",
+ "Fetchable",
+ "Fetchables",
"forcedefault",
+ "getenv",
+ "graphcache",
+ "headlessui",
"Iconify",
+ "intlify",
"Lachlan",
+ "loggedin",
"msapplication",
"NOTESTS",
"OVERLIMIT",
+ "overscan",
"Pinia",
"pnpm",
"pseudoclass",
"revparse",
"Screenshotting",
+ "semibold",
"shiki",
+ "speclist",
"testid",
"TIMEDOUT",
+ "titleize",
+ "topnav",
"unconfigured",
"unplugin",
"unrunnable",
"unstaged",
"urql",
+ "viewports",
"vite",
"vitejs",
"vueuse",
@@ -34,4 +48,4 @@
],
"ignoreWords": [],
"import": []
-}
+}
\ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 18f46a05a56a..845b2fc55678 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -28,7 +28,7 @@
// Name: Volar
// Description: Language server for Vue. Required for any syntax highlighting in Vue files.
- "vue.volar",
+ "Vue.volar",
// Name: Code Spell Checker
// Description: Add spell-checking help to your code.
diff --git a/README.md b/README.md
index 5ed74849fdc5..d10a70893421 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,11 @@
-
+
+
+
+
+
+
+
Documentation |
diff --git a/assets/cypress-logo-dark.png b/assets/cypress-logo-dark.png
new file mode 100644
index 000000000000..97ced299171f
Binary files /dev/null and b/assets/cypress-logo-dark.png differ
diff --git a/assets/cypress-logo-light.png b/assets/cypress-logo-light.png
new file mode 100644
index 000000000000..d8ae53068507
Binary files /dev/null and b/assets/cypress-logo-light.png differ
diff --git a/browser-versions.json b/browser-versions.json
index 423d9c28e419..1ba5d0e62917 100644
--- a/browser-versions.json
+++ b/browser-versions.json
@@ -1,4 +1,4 @@
{
- "chrome:beta": "103.0.5060.42",
- "chrome:stable": "102.0.5005.115"
+ "chrome:beta": "103.0.5060.53",
+ "chrome:stable": "103.0.5060.53"
}
diff --git a/circle.yml b/circle.yml
index ede5ccf5b0fc..fa0dfbe418e0 100644
--- a/circle.yml
+++ b/circle.yml
@@ -528,14 +528,45 @@ commands:
browser: <>
- run:
command: |
- cmd=$([[ <> == 'true' ]] && echo 'yarn percy exec --parallel -- --') || true
- DEBUG=<> \
- CYPRESS_KONFIG_ENV=production \
- CYPRESS_RECORD_KEY=${TEST_LAUNCHPAD_RECORD_KEY:-$MAIN_RECORD_KEY} \
- PERCY_PARALLEL_NONCE=$CIRCLE_SHA1 \
- PERCY_ENABLE=${PERCY_TOKEN:-0} \
- PERCY_PARALLEL_TOTAL=-1 \
- $cmd yarn workspace @packages/<> cypress:run:<> --browser <> --record --parallel --group <>-<>
+ echo Current working directory is $PWD
+ echo Total containers $CIRCLE_NODE_TOTAL
+
+ if [[ -v MAIN_RECORD_KEY ]]; then
+ # internal PR
+ cmd=$([[ <> == 'true' ]] && echo 'yarn percy exec --parallel -- --') || true
+ DEBUG=<> \
+ CYPRESS_KONFIG_ENV=production \
+ CYPRESS_RECORD_KEY=${TEST_LAUNCHPAD_RECORD_KEY:-$MAIN_RECORD_KEY} \
+ PERCY_PARALLEL_NONCE=$CIRCLE_SHA1 \
+ PERCY_ENABLE=${PERCY_TOKEN:-0} \
+ PERCY_PARALLEL_TOTAL=-1 \
+ $cmd yarn workspace @packages/<> cypress:run:<> --browser <> --record --parallel --group <>-<>
+ else
+ # external PR
+
+ # To make `circleci tests` work correctly, we need to step into the package folder.
+ cd packages/<>
+
+ GLOB="cypress/e2e/**/*cy.*"
+
+ if [[ <> == 'ct' ]]; then
+ # component tests are located side by side with the source codes.
+ GLOB="src/**/*cy.*"
+ fi
+
+ TESTFILES=$(circleci tests glob "$GLOB" | circleci tests split --total=$CIRCLE_NODE_TOTAL)
+ echo "Test files for this machine are $TESTFILES"
+
+ # To run the `yarn` command, we need to walk out of the package folder.
+ cd ../..
+
+ DEBUG=<> \
+ CYPRESS_KONFIG_ENV=production \
+ PERCY_PARALLEL_NONCE=$CIRCLE_SHA1 \
+ PERCY_ENABLE=${PERCY_TOKEN:-0} \
+ PERCY_PARALLEL_TOTAL=-1 \
+ yarn workspace @packages/<> cypress:run:<> --browser <> --spec $TESTFILES
+ fi
- run:
command: |
if [[ <> == 'app' && <> == 'true' && -d "packages/app/cypress/screenshots/runner/screenshot/screenshot.cy.tsx/percy" ]]; then
@@ -2359,22 +2390,22 @@ linux-x64-workflow: &linux-x64-workflow
requires:
- build
- run-frontend-shared-component-tests-chrome:
- context: [test-runner:launchpad-tests, test-runner:percy]
+ context: [test-runner:cypress-record-key, test-runner:launchpad-tests, test-runner:percy]
percy: true
requires:
- build
- run-launchpad-integration-tests-chrome:
- context: [test-runner:launchpad-tests, test-runner:percy]
+ context: [test-runner:cypress-record-key, test-runner:launchpad-tests, test-runner:percy]
percy: true
requires:
- build
- run-launchpad-component-tests-chrome:
- context: [test-runner:launchpad-tests, test-runner:percy]
+ context: [test-runner:cypress-record-key, test-runner:launchpad-tests, test-runner:percy]
percy: true
requires:
- build
- run-app-integration-tests-chrome:
- context: [test-runner:launchpad-tests, test-runner:percy]
+ context: [test-runner:cypress-record-key, test-runner:launchpad-tests, test-runner:percy]
percy: true
requires:
- build
@@ -2387,7 +2418,7 @@ linux-x64-workflow: &linux-x64-workflow
requires:
- system-tests-node-modules-install
- run-app-component-tests-chrome:
- context: [test-runner:launchpad-tests, test-runner:percy]
+ context: [test-runner:cypress-record-key, test-runner:launchpad-tests, test-runner:percy]
percy: true
requires:
- build
diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts
index 86040383ba81..334db2f7cb69 100644
--- a/cli/types/cypress.d.ts
+++ b/cli/types/cypress.d.ts
@@ -3003,7 +3003,7 @@ declare namespace Cypress {
xhrUrl: string
}
- interface TestConfigOverrides extends Partial> {
+ interface TestConfigOverrides extends Partial>, Partial> {
browser?: IsBrowserMatcher | IsBrowserMatcher[]
keystrokeDelay?: number
}
diff --git a/cli/types/tests/cypress-tests.ts b/cli/types/tests/cypress-tests.ts
index f28e09c95893..2f7202713699 100644
--- a/cli/types/tests/cypress-tests.ts
+++ b/cli/types/tests/cypress-tests.ts
@@ -33,6 +33,7 @@ namespace CypressConfigTests {
Cypress.config().baseUrl // $ExpectType string | null
// setters
+ Cypress.config('baseUrl', '.') // $ExpectType void
Cypress.config({ e2e: { baseUrl: '.' }}) // $ExpectType void
Cypress.config({ e2e: { baseUrl: null }}) // $ExpectType void
Cypress.config({ e2e: { baseUrl: '.', }}) // $ExpectType void
diff --git a/graphql-codegen.yml b/graphql-codegen.yml
index 111c3dc6c3c1..c540da7d5694 100644
--- a/graphql-codegen.yml
+++ b/graphql-codegen.yml
@@ -67,11 +67,14 @@ generates:
- 'packages/frontend-shared/script/codegen-type-map.js'
'./packages/graphql/src/gen/cloud-source-types.gen.ts':
+ config:
+ useTypeImports: true
schema: 'packages/graphql/schemas/cloud.graphql'
plugins:
- add:
content: '/* eslint-disable */'
- 'typescript'
+ - 'typescript-resolvers'
###
# Generates types for us to infer the correct keys for graphcache
diff --git a/npm/angular/package.json b/npm/angular/package.json
index 82c7e10455bd..711a7a3e93a4 100644
--- a/npm/angular/package.json
+++ b/npm/angular/package.json
@@ -55,7 +55,7 @@
"raw-loader": "1.0.0",
"renderkid": "2.0.5",
"rxjs": "~6.6.0",
- "semantic-release": "17.4.2",
+ "semantic-release": "19.0.3",
"to-string-loader": "1.1.6",
"ts-loader": "8.1.0",
"ts-node": "^10.2.1",
diff --git a/npm/cypress-schematic/sandbox12/package.json b/npm/cypress-schematic/sandbox12/package.json
index 6d4647bd8147..e2ede6c5d19b 100644
--- a/npm/cypress-schematic/sandbox12/package.json
+++ b/npm/cypress-schematic/sandbox12/package.json
@@ -28,7 +28,7 @@
"@angular/compiler-cli": "~13.1.3",
"@types/jasmine": "~3.6.0",
"@types/node": "^12.11.1",
- "jasmine-core": "~3.7.0",
+ "jasmine-core": "~3.8.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
diff --git a/npm/webpack-dev-server/test/.mocharc.js b/npm/webpack-dev-server/test/.mocharc.js
index b41c643ee9ec..8b0298fc8597 100644
--- a/npm/webpack-dev-server/test/.mocharc.js
+++ b/npm/webpack-dev-server/test/.mocharc.js
@@ -1,4 +1,4 @@
module.exports = {
spec: 'test/**/*.spec.ts',
- timeout: 10000,
+ timeout: 15000,
}
diff --git a/npm/webpack-preprocessor/package.json b/npm/webpack-preprocessor/package.json
index 465ad7db54a5..390f12d8f08b 100644
--- a/npm/webpack-preprocessor/package.json
+++ b/npm/webpack-preprocessor/package.json
@@ -54,7 +54,7 @@
"react-dom": "16.13.1",
"react-scripts": "3.2",
"rimraf": "3.0.2",
- "semantic-release": "17.2.3",
+ "semantic-release": "19.0.3",
"sinon": "^9.0.0",
"sinon-chai": "^3.5.0",
"snap-shot-it": "7.9.2",
diff --git a/package.json b/package.json
index f41dc4328b5d..e820142fb6e8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cypress",
- "version": "10.2.0",
+ "version": "10.3.0",
"description": "Cypress.io end to end testing tool",
"private": true,
"scripts": {
@@ -83,6 +83,7 @@
"@graphql-codegen/typed-document-node": "2.2.8",
"@graphql-codegen/typescript": "2.4.2",
"@graphql-codegen/typescript-operations": "2.2.3",
+ "@graphql-codegen/typescript-resolvers": "^2.6.4",
"@graphql-codegen/typescript-urql-graphcache": "2.2.3",
"@graphql-tools/delegate": "8.2.1",
"@graphql-tools/utils": "8.2.3",
@@ -196,7 +197,7 @@
"print-arch": "1.0.0",
"proxyquire": "2.1.3",
"rimraf": "3.0.2",
- "semantic-release": "17.2.3",
+ "semantic-release": "19.0.3",
"semantic-release-monorepo": "7.0.3",
"semver": "7.3.2",
"shelljs": "0.8.5",
@@ -276,4 +277,4 @@
"sharp": "0.29.3",
"vue-template-compiler": "2.6.12"
}
-}
+}
\ No newline at end of file
diff --git a/packages/app/cypress.config.ts b/packages/app/cypress.config.ts
index 772965e18456..7c42687ab789 100644
--- a/packages/app/cypress.config.ts
+++ b/packages/app/cypress.config.ts
@@ -3,9 +3,10 @@ import getenv from 'getenv'
import { initGitRepoForTestProject, resetGitRepoForTestProject } from './cypress/tasks/git'
const CYPRESS_INTERNAL_CLOUD_ENV = getenv('CYPRESS_INTERNAL_CLOUD_ENV', process.env.CYPRESS_INTERNAL_ENV || 'development')
+const CYPRESS_INTERNAL_DEV_PROJECT_ID = getenv('CYPRESS_INTERNAL_DEV_PROJECT_ID', process.env.CYPRESS_INTERNAL_DEV_PROJECT_ID || 'sehy69')
export default defineConfig({
- projectId: CYPRESS_INTERNAL_CLOUD_ENV === 'staging' ? 'ypt4pf' : 'sehy69',
+ projectId: CYPRESS_INTERNAL_CLOUD_ENV === 'staging' ? 'ypt4pf' : CYPRESS_INTERNAL_DEV_PROJECT_ID,
retries: {
runMode: 2,
openMode: 0,
diff --git a/packages/app/cypress/e2e/cypress-in-cypress-component.cy.ts b/packages/app/cypress/e2e/cypress-in-cypress-component.cy.ts
index d1b480379a04..90d5af4b00d9 100644
--- a/packages/app/cypress/e2e/cypress-in-cypress-component.cy.ts
+++ b/packages/app/cypress/e2e/cypress-in-cypress-component.cy.ts
@@ -80,13 +80,13 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
it('redirects to the specs list with error if a spec is not found', () => {
cy.visitApp()
- const { noSpecErrorTitle, noSpecErrorIntro, noSpecErrorExplainer } = defaultMessages.specPage
+ const { title, intro, explainer } = defaultMessages.specPage.noSpecError
const badFilePath = 'src/DoesNotExist.spec.js'
cy.visitApp(`/specs/runner?file=${badFilePath}`)
- cy.contains(noSpecErrorTitle).should('be.visible')
- cy.contains(noSpecErrorIntro).should('be.visible')
- cy.contains(noSpecErrorExplainer).should('be.visible')
+ cy.contains(title).should('be.visible')
+ cy.contains(intro).should('be.visible')
+ cy.contains(explainer).should('be.visible')
cy.contains(getPathForPlatform(badFilePath)).should('be.visible')
cy.location()
.its('href')
@@ -94,11 +94,11 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
// should clear after reload
cy.reload()
- cy.contains(noSpecErrorTitle).should('not.exist')
+ cy.contains(title).should('not.exist')
})
it('redirects to the specs list with error if an open spec is not found when specs list updates', () => {
- const { noSpecErrorTitle, noSpecErrorIntro, noSpecErrorExplainer } = defaultMessages.specPage
+ const { title, intro, explainer } = defaultMessages.specPage.noSpecError
const goodFilePath = 'src/TestComponent.spec.jsx'
@@ -109,9 +109,9 @@ describe('Cypress In Cypress CT', { viewportWidth: 1500, defaultCommandTimeout:
cy.withCtx((ctx, o) => {
ctx.actions.project.setSpecs(ctx.project.specs.filter((spec) => !spec.absolute.includes(o.path)))
}, { path: goodFilePath }).then(() => {
- cy.contains(noSpecErrorTitle).should('be.visible')
- cy.contains(noSpecErrorIntro).should('be.visible')
- cy.contains(noSpecErrorExplainer).should('be.visible')
+ cy.contains(title).should('be.visible')
+ cy.contains(intro).should('be.visible')
+ cy.contains(explainer).should('be.visible')
cy.contains(getPathForPlatform(goodFilePath)).should('be.visible')
cy.location()
.its('href')
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 7da4e7badfcd..c657da01ae69 100644
--- a/packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts
+++ b/packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts
@@ -98,13 +98,13 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
})
it('redirects to the specs list with error if a spec is not found when navigating', () => {
- const { noSpecErrorTitle, noSpecErrorIntro, noSpecErrorExplainer } = defaultMessages.specPage
+ const { title, intro, explainer } = defaultMessages.specPage.noSpecError
const badFilePath = 'cypress/e2e/does-not-exist.spec.js'
cy.visitApp(`/specs/runner?file=${badFilePath}`)
- cy.contains(noSpecErrorTitle).should('be.visible')
- cy.contains(noSpecErrorIntro).should('be.visible')
- cy.contains(noSpecErrorExplainer).should('be.visible')
+ cy.contains(title).should('be.visible')
+ cy.contains(intro).should('be.visible')
+ cy.contains(explainer).should('be.visible')
cy.contains(getPathForPlatform(badFilePath)).should('be.visible')
cy.location()
.its('href')
@@ -114,11 +114,11 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
// should clear after reload
cy.reload()
- cy.contains(noSpecErrorTitle).should('not.exist')
+ cy.contains(title).should('not.exist')
})
it('redirects to the specs list with error if an open spec is not found when specs list updates', () => {
- const { noSpecErrorTitle, noSpecErrorIntro, noSpecErrorExplainer } = defaultMessages.specPage
+ const { title, intro, explainer } = defaultMessages.specPage.noSpecError
const goodFilePath = 'cypress/e2e/dom-content.spec.js'
@@ -129,9 +129,9 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout:
cy.withCtx((ctx, o) => {
ctx.actions.project.setSpecs(ctx.project.specs.filter((spec) => !spec.absolute.includes(o.path)))
}, { path: goodFilePath }).then(() => {
- cy.contains(noSpecErrorTitle).should('be.visible')
- cy.contains(noSpecErrorIntro).should('be.visible')
- cy.contains(noSpecErrorExplainer).should('be.visible')
+ cy.contains(title).should('be.visible')
+ cy.contains(intro).should('be.visible')
+ cy.contains(explainer).should('be.visible')
cy.contains(getPathForPlatform(goodFilePath)).should('be.visible')
cy.location()
.its('href')
diff --git a/packages/app/cypress/e2e/reporter_header.cy.ts b/packages/app/cypress/e2e/reporter_header.cy.ts
index d4e5abc05ad1..3f5186584463 100644
--- a/packages/app/cypress/e2e/reporter_header.cy.ts
+++ b/packages/app/cypress/e2e/reporter_header.cy.ts
@@ -13,7 +13,7 @@ describe('Reporter Header', () => {
cy.get('body').type('f')
cy.get('[data-selected-spec="true"]').should('contain', 'dom-content').should('have.length', '1')
- cy.get('[data-selected-spec="false"]').should('have.length', '18')
+ cy.get('[data-selected-spec="false"]').should('have.length', '27')
})
it('filters the list of specs when searching for specs', () => {
@@ -26,7 +26,7 @@ describe('Reporter Header', () => {
cy.get('input').clear()
- cy.get('[data-cy="spec-file-item"]').should('have.length', '3')
+ cy.get('[data-cy="spec-file-item"]').should('have.length', 3)
cy.get('input').type('asdf', { force: true })
diff --git a/packages/app/cypress/e2e/runs.cy.ts b/packages/app/cypress/e2e/runs.cy.ts
index ff6b60ae315f..09ca8bb91bee 100644
--- a/packages/app/cypress/e2e/runs.cy.ts
+++ b/packages/app/cypress/e2e/runs.cy.ts
@@ -10,7 +10,7 @@ function scaffoldTestingTypeAndVisitRunsPage (testingType: 'e2e' | 'component')
// make sure there are no runs found for the project ID
cy.remoteGraphQLIntercept(async (obj) => {
- if (obj.result.data?.cloudProjectBySlug) {
+ if (obj.result.data?.cloudProjectBySlug?.runs?.nodes) {
obj.result.data.cloudProjectBySlug.runs.nodes = []
}
@@ -136,7 +136,7 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
cy.visitApp()
cy.remoteGraphQLIntercept(async (obj) => {
- if ((obj.operationName === 'CheckCloudOrganizations_cloudViewerChange_cloudViewer' || obj.operationName === 'Runs_cloudViewer')) {
+ if ((obj.operationName === 'CheckCloudOrganizations_cloudViewerChange_cloudViewer' || obj.operationName === 'Runs_cloudViewer' || obj.operationName === 'SpecsPageContainer_cloudViewer')) {
if (obj.result.data?.cloudViewer?.organizations?.nodes) {
obj.result.data.cloudViewer.organizations.nodes = []
}
@@ -597,8 +597,6 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
let cloudData: any
cy.loginUser()
- cy.visitApp()
-
cy.remoteGraphQLIntercept((obj) => {
if (obj.operationName === 'Runs_currentProject_cloudProject_cloudProjectBySlug') {
cloudData = obj.result
@@ -610,7 +608,10 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
return obj.result
})
+ cy.visitApp()
+
cy.findByTestId('sidebar-link-runs-page').click()
+
cy.contains('h2', 'Cannot connect to the Cypress Dashboard')
cy.percySnapshot()
diff --git a/packages/app/cypress/e2e/sidebar_navigation.cy.ts b/packages/app/cypress/e2e/sidebar_navigation.cy.ts
index 27e07abe718e..5fbd5cdd1b36 100644
--- a/packages/app/cypress/e2e/sidebar_navigation.cy.ts
+++ b/packages/app/cypress/e2e/sidebar_navigation.cy.ts
@@ -221,7 +221,8 @@ describe('Sidebar Navigation', () => {
it('has a menu item labeled "Runs" which takes you to the Runs page', () => {
cy.get('[data-cy="app-header-bar"]').findByText('Runs').should('not.exist')
- cy.findByText('Runs').should('be.visible').click()
+
+ cy.findByTestId('sidebar-link-runs-page').should('have.text', 'Runs').should('be.visible').click()
cy.get('[data-cy="app-header-bar"]').findByText('Runs').should('be.visible')
cy.get('.router-link-active').findByText('Runs').should('be.visible')
})
diff --git a/packages/app/cypress/e2e/specs.cy.ts b/packages/app/cypress/e2e/specs.cy.ts
index 1716658ce2e4..d71a2e703e12 100644
--- a/packages/app/cypress/e2e/specs.cy.ts
+++ b/packages/app/cypress/e2e/specs.cy.ts
@@ -95,7 +95,7 @@ describe('App: Specs', () => {
const expectedScaffoldPathsForPlatform = expectedScaffoldPaths.map(getPathForPlatform)
- it('scaffolds example files when card is clicked', () => {
+ it('scaffolds example files when card is clicked', { viewportHeight: 1200 }, () => {
cy.get('@ScaffoldCard').click()
cy.findByRole('dialog', {
diff --git a/packages/app/cypress/e2e/specs_list_e2e.cy.ts b/packages/app/cypress/e2e/specs_list_e2e.cy.ts
index 0ef87875ac69..2ec0cc25a7c7 100644
--- a/packages/app/cypress/e2e/specs_list_e2e.cy.ts
+++ b/packages/app/cypress/e2e/specs_list_e2e.cy.ts
@@ -112,19 +112,19 @@ describe('App: Spec List (E2E)', () => {
describe('typing the filter', function () {
it('displays only matching spec', function () {
- cy.get('button').contains('14 Matches')
+ cy.get('button').contains('23 Matches')
cy.findByLabelText('Search Specs').type('content')
cy.get('[data-cy="spec-item"]')
.should('have.length', 2)
.and('contain', 'dom-content.spec.js')
- cy.get('button').contains('2 of 14 Matches')
+ cy.get('button').contains('2 of 23 Matches')
cy.findByLabelText('Search Specs').clear().type('asdf')
cy.get('[data-cy="spec-item"]')
.should('have.length', 0)
- cy.get('button').contains('0 of 14 Matches')
+ cy.get('button').contains('0 of 23 Matches')
})
it('only shows matching folders', () => {
@@ -176,7 +176,7 @@ describe('App: Spec List (E2E)', () => {
.should('have.value', '')
cy.get('[data-cy="spec-item"]')
- .should('have.length', 14)
+ .should('have.length', 23)
})
it('clears the filter if the user presses ESC key', function () {
@@ -187,8 +187,7 @@ describe('App: Spec List (E2E)', () => {
cy.findByLabelText('Search Specs')
.should('have.value', '')
- cy.get('[data-cy="spec-item"]')
- .should('have.length', 14)
+ cy.get('button').contains('23 Matches')
})
it('shows empty message if no results', function () {
@@ -203,8 +202,7 @@ describe('App: Spec List (E2E)', () => {
cy.findByText('Clear Search').click()
cy.focused().should('have.id', 'spec-filter')
- cy.get('[data-cy="spec-item"]')
- .should('have.length', 14)
+ cy.get('button').contains('23 Matches')
})
//TODO: https://cypress-io.atlassian.net/browse/UNIFY-1588
diff --git a/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts b/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts
new file mode 100644
index 000000000000..28a76b60039b
--- /dev/null
+++ b/packages/app/cypress/e2e/specs_list_latest_runs.cy.ts
@@ -0,0 +1,633 @@
+import defaultMessages from '@packages/frontend-shared/src/locales/en-US.json'
+import type { CloudRunStatus } from '@packages/frontend-shared/src/generated/graphql'
+
+function specRowSelector (specFileName: string) {
+ return `[data-cy-row="${specFileName}"]`
+}
+
+function dotSelector (specFileName: string, dotNumber: 0 | 1 | 2 |'latest') {
+ return `${specRowSelector(specFileName)} [data-cy="run-status-dot-${dotNumber}"]`
+}
+
+function dotsSkeletonSelector (specFileName: string) {
+ return `${specRowSelector(specFileName)} [data-cy="run-status-dots-loading"]`
+}
+
+function averageDurationSelector (specFileName: string) {
+ return `${specRowSelector(specFileName)} [data-cy="average-duration"]`
+}
+
+function specShouldShow (specFileName: string, runDotsClasses: string[], latestRunStatus: CloudRunStatus|'PLACEHOLDER') {
+ const latestStatusSpinning = latestRunStatus === 'RUNNING'
+
+ type dotIndex = Parameters[1];
+ const indexes: dotIndex[] = [0, 1, 2]
+
+ indexes.forEach((i) => {
+ return cy.get(dotSelector(specFileName, i)).should('have.class', `icon-light-${runDotsClasses.length > i ? runDotsClasses[i] : 'gray-300'}`)
+ })
+
+ cy.get(dotSelector(specFileName, 'latest'))
+ .should(`${latestStatusSpinning ? '' : 'not.'}have.class`, 'animate-spin')
+ .and('have.attr', 'data-cy-run-status', latestRunStatus)
+
+ // TODO: add link verification
+ // if (latestRunStatus !== 'PLACEHOLDER') {
+ // cy.get(`${specRowSelector(specFileName)} [data-cy="run-status-dots"]`).validateExternalLink('https://google.com')
+ // }
+}
+
+function simulateRunData () {
+ cy.remoteGraphQLIntercept(async (obj) => {
+ const fakeRuns = (statuses: string[], idPrefix: string) => {
+ return statuses.map((s, idx) => {
+ return {
+ __typename: 'CloudSpecRun',
+ id: `SpecRun_${idPrefix}_${idx}`,
+ status: s,
+ createdAt: new Date('2022-05-08T03:17:00').toISOString(),
+ completedAt: new Date('2022-05-08T05:17:00').toISOString(),
+ runNumber: 432,
+ groupCount: 2,
+ specDuration: {
+ min: 143003, // 2:23
+ max: 159120, // 3:40
+ __typename: 'SpecDataAggregate',
+ },
+ testsFailed: {
+ min: 1,
+ max: 2,
+ __typename: 'SpecDataAggregate',
+ },
+ testsPassed: {
+ min: 22,
+ max: 23,
+ __typename: 'SpecDataAggregate',
+ },
+ testsSkipped: {
+ min: null,
+ max: null,
+ __typename: 'SpecDataAggregate',
+ },
+ testsPending: {
+ min: 1,
+ max: 2,
+ __typename: 'SpecDataAggregate',
+ },
+ url: 'https://google.com',
+ }
+ })
+ }
+
+ if (obj.result.data && 'cloudSpecByPath' in obj.result.data) {
+ // simulate network latency to allow for caching to register
+ await new Promise((r) => setTimeout(r, 20))
+
+ const statuses = obj.variables.specPath?.includes('accounts_list.spec.js') ?
+ ['PASSED', 'FAILED', 'CANCELLED', 'ERRORED'] :
+ obj.variables.specPath?.includes('app.spec.js') ?
+ [] :
+ ['RUNNING', 'PASSED']
+
+ const runs = fakeRuns(statuses, obj.variables.specPath)
+ const averageDuration = obj.variables.specPath?.includes('accounts_list.spec.js') ?
+ 12000 : // 0:12
+ 123000 // 2:03
+
+ obj.result.data.cloudSpecByPath = {
+ __typename: 'CloudProjectSpec',
+ retrievedAt: new Date().toISOString(),
+ id: `id${obj.variables.specPath}`,
+ specRuns: {
+ __typename: 'CloudSpecRunConnection',
+ nodes: runs,
+ },
+ averageDuration,
+ }
+ }
+
+ return obj.result
+ })
+}
+
+function allVisibleSpecsShouldBePlaceholders () {
+ cy.findAllByTestId('run-status-dot-0').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-1').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-2').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-latest')
+ .should('not.have.class', 'animate-spin')
+ .and('have.attr', 'data-cy-run-status', 'PLACEHOLDER')
+
+ cy.get('.spec-list-container').scrollTo('bottom')
+ cy.get('.spec-list-container').scrollTo('bottom')
+}
+
+describe('App/Cloud Integration - Latest runs and Average duration', { viewportWidth: 1200, viewportHeight: 900 }, () => {
+ beforeEach(() => {
+ cy.scaffoldProject('cypress-in-cypress')
+ cy.openProject('cypress-in-cypress')
+ cy.startAppServer()
+
+ cy.withCtx((ctx, o) => {
+ o.sinon.stub(ctx.lifecycleManager.git!, 'currentBranch').value('fakeBranch')
+ })
+ })
+
+ context('when no runs are recorded', () => {
+ beforeEach(() => {
+ cy.loginUser()
+
+ cy.remoteGraphQLIntercept(async (obj) => {
+ if (obj.result.data && 'cloudSpecByPath' in obj.result.data) {
+ obj.result.data.cloudSpecByPath = {
+ __typename: 'CloudProjectSpecNotFound',
+ retrievedAt: new Date().toISOString(),
+ id: `id${obj.variables.specPath}`,
+ specRuns: {
+ __typename: 'CloudSpecRunConnection',
+ nodes: [],
+ },
+ averageDuration: null,
+ }
+ }
+
+ return obj.result
+ })
+
+ cy.visitApp()
+ cy.findByTestId('sidebar-link-specs-page').click()
+ })
+
+ it('shows placeholders for all visible specs', () => {
+ allVisibleSpecsShouldBePlaceholders()
+ })
+ })
+
+ context('when logged out', () => {
+ beforeEach(() => {
+ cy.visitApp()
+ cy.findByTestId('sidebar-link-specs-page').click()
+ })
+
+ it('shows placeholders for all visible specs', () => {
+ allVisibleSpecsShouldBePlaceholders()
+ })
+
+ it('shows correct tooltips with log in buttons', () => {
+ cy.findByTestId('latest-runs-header').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown')
+ .should('contain', 'Connect to the Cypress Dashboard to see the status of your latest runs')
+ .find('button')
+ .should('have.text', 'Log in to the Dashboard')
+ .click()
+
+ cy.findByRole('dialog', { name: 'Log in to Cypress' }).within(() => {
+ cy.get('button').contains('Log In')
+ cy.get('[aria-label="Close"]').click()
+ })
+
+ cy.findByTestId('latest-runs-header').trigger('mouseleave')
+
+ cy.findByTestId('average-duration-header').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown')
+ .should('contain', 'Connect to the Cypress Dashboard to see the average spec durations of your latest runs')
+ .find('button')
+ .should('have.text', 'Log in to the Dashboard')
+ .click()
+
+ cy.findByRole('dialog', { name: 'Log in to Cypress' }).within(() => {
+ cy.get('button').contains('Log In')
+ cy.get('[aria-label="Close"]').click()
+ })
+
+ cy.findByTestId('average-duration-header').trigger('mouseleave')
+ })
+ })
+
+ context('when project disconnected', () => {
+ beforeEach(() => {
+ cy.loginUser()
+ cy.withCtx((ctx, o) => {
+ o.sinon.stub(ctx.project, 'projectId').resolves(null)
+ })
+
+ cy.visitApp()
+ cy.findByTestId('sidebar-link-specs-page').click()
+ })
+
+ it('shows placeholders for all visible specs', () => {
+ allVisibleSpecsShouldBePlaceholders()
+ })
+
+ it('shows correct tooltips with log in buttons', () => {
+ cy.findByTestId('latest-runs-header').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown')
+ .should('contain', 'Connect to the Cypress Dashboard to see the status of your latest runs')
+ .find('button')
+ .should('have.text', 'Connect your project')
+ .click()
+
+ cy.findByRole('dialog', { name: 'Create project' }).within(() => {
+ cy.get('[aria-label="Close"]').click({ force: true })
+ })
+
+ cy.findByTestId('latest-runs-header').trigger('mouseleave')
+
+ cy.findByTestId('average-duration-header').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown')
+ .should('contain', 'Connect to the Cypress Dashboard to see the average spec durations of your latest runs')
+ .find('button')
+ .should('have.text', 'Connect your project')
+ .click()
+
+ cy.findByRole('dialog', { name: 'Create project' }).within(() => {
+ cy.get('[aria-label="Close"]').click({ force: true })
+ })
+
+ cy.findByTestId('average-duration-header').trigger('mouseleave')
+ })
+ })
+
+ context('when not using a branch', () => {
+ beforeEach(() => {
+ cy.withCtx((ctx, o) => {
+ o.sinon.stub(ctx.lifecycleManager.git!, 'currentBranch').value(undefined)
+ })
+
+ cy.loginUser()
+
+ cy.visitApp()
+ cy.findByTestId('sidebar-link-specs-page').click()
+ })
+
+ it('shows placeholders for all visible specs', () => {
+ allVisibleSpecsShouldBePlaceholders()
+ })
+ })
+
+ context('when runs are recorded', () => {
+ beforeEach(() => {
+ cy.loginUser()
+
+ simulateRunData()
+
+ cy.visitApp()
+ cy.findByTestId('sidebar-link-specs-page').click()
+ })
+
+ it('shows correct tooltips', () => {
+ cy.findByTestId('latest-runs-header').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown')
+ .should('contain', 'The status of your latest runs in the Cypress Dashboard')
+ .find('button')
+ .should('not.exist')
+
+ cy.findByTestId('latest-runs-header').trigger('mouseleave')
+
+ cy.findByTestId('average-duration-header').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown')
+ .should('contain', 'The average spec durations of your latest runs in the Cypress Dashboard')
+ .find('button')
+ .should('not.exist')
+
+ cy.findByTestId('average-duration-header').trigger('mouseleave')
+ })
+
+ it('shows accurate latest runs and average duration data', () => {
+ specShouldShow('accounts_list.spec.js', ['orange-400', 'gray-300', 'red-400'], 'PASSED')
+ cy.get(averageDurationSelector('accounts_list.spec.js')).contains('0:12')
+
+ // all should use placeholder
+ specShouldShow('app.spec.js', [], 'PLACEHOLDER')
+ cy.get(averageDurationSelector('app.spec.js')).contains('2:03')
+ // shouldn't have a tooltip
+ cy.get(dotSelector('app.spec.js', 'latest')).trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').should('not.exist')
+ cy.get(dotSelector('app.spec.js', 'latest')).trigger('mouseleave')
+
+ // oldest 2 status dots will use placeholder
+ specShouldShow('accounts_new.spec.js', ['gray-300', 'gray-300', 'jade-400'], 'RUNNING')
+ cy.get(dotSelector('accounts_new.spec.js', 'latest')).trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').should('exist')
+ // TODO: verify the contents of the tooltip
+ cy.get(dotSelector('accounts_new.spec.js', 'latest')).trigger('mouseleave')
+ cy.get(averageDurationSelector('accounts_new.spec.js')).contains('2:03')
+ })
+
+ it('lazily loads data for off-screen specs', () => {
+ // make sure the virtualized list didn't load z008.spec.js
+ cy.get(specRowSelector('z008.spec.js')).should('not.exist')
+
+ cy.get('.spec-list-container').scrollTo('bottom')
+ // scrolling down should load z008.spec.js with loading status
+ cy.get(dotsSkeletonSelector('z008.spec.js')).should('exist')
+
+ // then z008.spec.js should show proper data
+ specShouldShow('z008.spec.js', ['gray-300', 'gray-300', 'jade-400'], 'RUNNING')
+ cy.get(averageDurationSelector('z008.spec.js')).contains('2:03')
+ })
+
+ describe('preserving tree expansion state', () => {
+ it('should preserve state when row data is updated without additions/deletions', () => {
+ // Collapse a directory
+ cy.get('button[data-cy="row-directory-depth-1"]').first()
+ .should('have.attr', 'aria-expanded', 'true')
+ .click()
+ .should('have.attr', 'aria-expanded', 'false')
+
+ // Trigger cloud specs list change by scrolling
+ cy.get('.spec-list-container')
+ .scrollTo('bottom', { duration: 500 })
+ .wait(100)
+ .scrollTo('top', { duration: 500 })
+
+ // Directory should still be collapsed
+ cy.get('button[data-cy="row-directory-depth-1"]').first()
+ .should('have.attr', 'aria-expanded', 'false')
+ })
+
+ it('should expand all directories when search is performed', () => {
+ // Collapse a directory
+ cy.get('button[data-cy="row-directory-depth-0"]').first()
+ .should('have.attr', 'aria-expanded', 'true')
+ .click()
+ .should('have.attr', 'aria-expanded', 'false')
+ .then((dir) => {
+ // Perform a search/filter operation
+ cy.findByLabelText('Search Specs').type(dir.text()[0])
+ })
+
+ // Previously-collapsed directory should automatically expand
+ cy.get('button[data-cy="row-directory-depth-0"]').first()
+ .should('have.attr', 'aria-expanded', 'true')
+ })
+ })
+
+ it('should retain data after app navigation', () => {
+ // App/Cloud Integration data should load and render to start
+ specShouldShow('accounts_list.spec.js', ['orange-400', 'gray-300', 'red-400'], 'PASSED')
+ cy.get(averageDurationSelector('accounts_list.spec.js')).contains('0:12')
+
+ // Move to Settings page and wait for render
+ cy.get('a[href="#/settings"]').click()
+ cy.location('hash').should('include', '/settings')
+ cy.findByText('Project Settings').should('be.visible')
+
+ // Move back to Specs page and wait for render
+ cy.get('a[href="#/specs"]').click()
+ cy.location('hash').should('include', '/specs')
+ cy.findByText('E2E specs').should('be.visible')
+
+ // App/Cloud Integration data should still be loaded and rendered
+ specShouldShow('accounts_list.spec.js', ['orange-400', 'gray-300', 'red-400'], 'PASSED')
+ cy.get(averageDurationSelector('accounts_list.spec.js')).contains('0:12')
+ })
+ })
+
+ context('polling indicates new data', () => {
+ beforeEach(() => {
+ cy.loginUser()
+
+ cy.remoteGraphQLIntercept(async (obj, testState) => {
+ const fakeRuns = (statuses: string[], idPrefix: string) => {
+ return statuses.map((s, idx) => {
+ return {
+ __typename: 'CloudSpecRun',
+ id: `SpecRun_${idPrefix}_${idx}`,
+ status: s,
+ createdAt: new Date('2022-05-08T03:17:00').toISOString(),
+ completedAt: new Date('2022-05-08T05:17:00').toISOString(),
+ runNumber: 432,
+ groupCount: 2,
+ specDuration: {
+ min: 143003, // 2:23
+ max: 159120, // 3:40
+ __typename: 'SpecDataAggregate',
+ },
+ testsFailed: {
+ min: 1,
+ max: 2,
+ __typename: 'SpecDataAggregate',
+ },
+ testsPassed: {
+ min: 22,
+ max: 23,
+ __typename: 'SpecDataAggregate',
+ },
+ testsSkipped: {
+ min: null,
+ max: null,
+ __typename: 'SpecDataAggregate',
+ },
+ testsPending: {
+ min: 1,
+ max: 2,
+ __typename: 'SpecDataAggregate',
+ },
+ url: 'https://google.com',
+ }
+ })
+ }
+
+ const pollingCounter = testState.pollingCounter ?? 0
+
+ if (obj.result.data && 'cloudSpecByPath' in obj.result.data) {
+ // simulate network latency to allow for caching to register
+ await new Promise((r) => setTimeout(r, 20))
+
+ const statuses = pollingCounter < 2 ? ['PASSED', 'FAILED', 'CANCELLED', 'ERRORED'] : ['FAILED', 'PASSED', 'FAILED', 'CANCELLED', 'ERRORED']
+ const runs = fakeRuns(statuses, obj.variables.specPath)
+ const averageDuration = pollingCounter < 2 ? 12000 : 13000
+
+ obj.result.data.cloudSpecByPath = {
+ __typename: 'CloudProjectSpec',
+ retrievedAt: new Date().toISOString(),
+ id: `id${obj.variables.specPath}`,
+ specRuns: {
+ __typename: 'CloudSpecRunConnection',
+ nodes: runs,
+ },
+ averageDuration,
+ }
+ } else if (obj.result.data && 'cloudLatestRunUpdateSpecData' in obj.result.data) {
+ const mostRecentUpdate = pollingCounter > 1 ? new Date().toISOString() : new Date('2022-06-10').toISOString()
+ // initial polling interval is set to every second to avoid long wait times
+ const pollingInterval = pollingCounter > 1 ? 30 : 1
+
+ obj.result.data.cloudLatestRunUpdateSpecData = {
+ __typename: 'CloudLatestRunUpdateSpecData',
+ mostRecentUpdate,
+ pollingInterval,
+ }
+
+ testState.pollingCounter = pollingCounter + 1
+ }
+
+ return obj.result
+ })
+
+ cy.visitApp()
+ cy.findByTestId('sidebar-link-specs-page').click()
+ })
+
+ it('refreshes view to reflect new data', () => {
+ specShouldShow('accounts_list.spec.js', ['orange-400', 'gray-300', 'red-400'], 'PASSED')
+ cy.get(dotSelector('accounts_new.spec.js', 'latest')).trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').should('exist')
+ // TODO: verify the contents of the tooltip
+ cy.get(dotSelector('accounts_new.spec.js', 'latest')).trigger('mouseleave')
+ cy.get(averageDurationSelector('accounts_list.spec.js')).contains('0:12')
+
+ cy.wait(1200)
+
+ // new results should be shown
+ specShouldShow('accounts_list.spec.js', ['gray-300', 'red-400', 'jade-400'], 'FAILED')
+ cy.get(dotSelector('accounts_new.spec.js', 'latest')).trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').should('exist')
+ // TODO: verify the contents of the tooltip
+ cy.get(dotSelector('accounts_new.spec.js', 'latest')).trigger('mouseleave')
+ cy.get(averageDurationSelector('accounts_list.spec.js')).contains('0:13')
+ })
+ })
+
+ context('polling indicates no new data', () => {
+ beforeEach(() => {
+ cy.loginUser()
+
+ cy.remoteGraphQLIntercept(async (obj, testState) => {
+ const fakeRuns = (statuses: string[], idPrefix: string) => {
+ return statuses.map((s, idx) => {
+ return {
+ __typename: 'CloudSpecRun',
+ id: `SpecRun_${idPrefix}_${idx}`,
+ status: s,
+ createdAt: new Date('2022-05-08T03:17:00').toISOString(),
+ completedAt: new Date('2022-05-08T05:17:00').toISOString(),
+ runNumber: 432,
+ groupCount: 2,
+ specDuration: {
+ min: 143003, // 2:23
+ max: 159120, // 3:40
+ __typename: 'SpecDataAggregate',
+ },
+ testsFailed: {
+ min: 1,
+ max: 2,
+ __typename: 'SpecDataAggregate',
+ },
+ testsPassed: {
+ min: 22,
+ max: 23,
+ __typename: 'SpecDataAggregate',
+ },
+ testsSkipped: {
+ min: null,
+ max: null,
+ __typename: 'SpecDataAggregate',
+ },
+ testsPending: {
+ min: 1,
+ max: 2,
+ __typename: 'SpecDataAggregate',
+ },
+ url: 'https://google.com',
+ }
+ })
+ }
+
+ const pollingCounter = testState.pollingCounter ?? 0
+
+ if (obj.result.data && 'cloudSpecByPath' in obj.result.data) {
+ // simulate network latency to allow for caching to register
+ await new Promise((r) => setTimeout(r, 20))
+
+ const statuses = pollingCounter < 2 ? ['PASSED', 'FAILED', 'CANCELLED', 'ERRORED'] : ['FAILED', 'PASSED', 'FAILED', 'CANCELLED', 'ERRORED']
+ const runs = fakeRuns(statuses, obj.variables.specPath)
+ const averageDuration = pollingCounter < 2 ? 12000 : 13000
+
+ obj.result.data.cloudSpecByPath = {
+ __typename: 'CloudProjectSpec',
+ retrievedAt: new Date().toISOString(),
+ id: `id${obj.variables.specPath}`,
+ specRuns: {
+ __typename: 'CloudSpecRunConnection',
+ nodes: runs,
+ },
+ averageDuration,
+ }
+ } else if (obj.result.data && 'cloudLatestRunUpdateSpecData' in obj.result.data) {
+ const mostRecentUpdate = new Date('2022-06-10').toISOString()
+ // initial polling interval is set to every second to avoid long wait times
+ const pollingInterval = pollingCounter > 1 ? 30 : 1
+
+ obj.result.data.cloudLatestRunUpdateSpecData = {
+ __typename: 'CloudLatestRunUpdateSpecData',
+ mostRecentUpdate,
+ pollingInterval,
+ }
+
+ testState.pollingCounter = pollingCounter + 1
+ }
+
+ return obj.result
+ })
+
+ cy.visitApp()
+ cy.findByTestId('sidebar-link-specs-page').click()
+ })
+
+ it('shows the same data after polling', () => {
+ specShouldShow('accounts_list.spec.js', ['orange-400', 'gray-300', 'red-400'], 'PASSED')
+ cy.get(dotSelector('accounts_new.spec.js', 'latest')).trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').should('exist')
+ // TODO: verify the contents of the tooltip
+ cy.get(dotSelector('accounts_new.spec.js', 'latest')).trigger('mouseleave')
+ cy.get(averageDurationSelector('accounts_list.spec.js')).contains('0:12')
+
+ cy.wait(1200)
+
+ // new results should be shown
+ specShouldShow('accounts_list.spec.js', ['orange-400', 'gray-300', 'red-400'], 'PASSED')
+ cy.get(dotSelector('accounts_new.spec.js', 'latest')).trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').should('exist')
+ // TODO: verify the contents of the tooltip
+ cy.get(dotSelector('accounts_new.spec.js', 'latest')).trigger('mouseleave')
+ cy.get(averageDurationSelector('accounts_list.spec.js')).contains('0:12')
+ })
+ })
+})
+
+describe('App/Cloud Integration - Latest runs and Average duration', { viewportWidth: 1200 }, () => {
+ context('when offline', () => {
+ beforeEach(() => {
+ cy.scaffoldProject('cypress-in-cypress')
+ cy.goOffline()
+ cy.wait(300)
+ cy.openProject('cypress-in-cypress')
+ cy.startAppServer()
+
+ cy.loginUser()
+
+ simulateRunData()
+ cy.visitApp()
+
+ cy.findByTestId('sidebar-link-specs-page').click()
+
+ // after navigating to a new page, the browser needs to go offline again
+ cy.goOffline()
+ })
+
+ it('shows placeholders for all visible specs', () => {
+ allVisibleSpecsShouldBePlaceholders()
+ })
+
+ it('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)
+
+ cy.goOnline()
+ cy.findByTestId('offline-alert').should('not.exist')
+ })
+ })
+})
diff --git a/packages/app/cypress/e2e/subscriptions/authChange-subscription.cy.ts b/packages/app/cypress/e2e/subscriptions/authChange-subscription.cy.ts
index 6ea15de793d6..acbfa8274f87 100644
--- a/packages/app/cypress/e2e/subscriptions/authChange-subscription.cy.ts
+++ b/packages/app/cypress/e2e/subscriptions/authChange-subscription.cy.ts
@@ -33,7 +33,7 @@ describe('authChange subscription', () => {
cy.contains('Log In')
cy.wait(500)
cy.withCtx(async (ctx) => {
- await ctx.actions.auth.login()
+ await ctx.actions.auth.login('testing', 'testing')
})
cy.contains('Test User')
@@ -62,7 +62,7 @@ describe('authChange subscription', () => {
cy.contains('Log In')
cy.wait(500)
cy.withCtx(async (ctx) => {
- await ctx.actions.auth.login()
+ await ctx.actions.auth.login('testing', 'testing')
})
cy.contains('Test User')
@@ -90,7 +90,7 @@ describe('authChange subscription', () => {
cy.contains('Log In')
cy.wait(500)
cy.withCtx(async (ctx) => {
- await ctx.actions.auth.login()
+ await ctx.actions.auth.login('testing', 'testing')
})
cy.contains('Test User')
diff --git a/packages/app/cypress/e2e/subscriptions/createCloudOrgModal-subscription.cy.ts b/packages/app/cypress/e2e/subscriptions/createCloudOrgModal-subscription.cy.ts
index f6a6cee32c24..d667d7e15685 100644
--- a/packages/app/cypress/e2e/subscriptions/createCloudOrgModal-subscription.cy.ts
+++ b/packages/app/cypress/e2e/subscriptions/createCloudOrgModal-subscription.cy.ts
@@ -15,11 +15,10 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
cy.startAppServer('component')
cy.loginUser()
- cy.visitApp()
// Simulate no orgs
cy.remoteGraphQLIntercept(async (obj) => {
- if ((obj.operationName === 'CheckCloudOrganizations_cloudViewerChange_cloudViewer' || obj.operationName === 'Runs_cloudViewer')) {
+ if ((obj.operationName === 'CheckCloudOrganizations_cloudViewerChange_cloudViewer' || obj.operationName === 'Runs_cloudViewer' || obj.operationName === 'SpecsPageContainer_cloudViewer')) {
if (obj.result.data?.cloudViewer?.organizations?.nodes) {
obj.result.data.cloudViewer.organizations.nodes = []
}
@@ -28,6 +27,8 @@ describe('App: Runs', { viewportWidth: 1200 }, () => {
return obj.result
})
+ cy.visitApp()
+
cy.findByTestId('sidebar-link-runs-page').click()
cy.findByText(defaultMessages.runs.connect.buttonProject).click()
diff --git a/packages/app/cypress/e2e/subscriptions/specChange-subscription.cy.ts b/packages/app/cypress/e2e/subscriptions/specChange-subscription.cy.ts
index 95e5a37f3b61..9cd761419f6d 100644
--- a/packages/app/cypress/e2e/subscriptions/specChange-subscription.cy.ts
+++ b/packages/app/cypress/e2e/subscriptions/specChange-subscription.cy.ts
@@ -12,7 +12,8 @@ describe('specChange subscription', () => {
describe('specs list', () => {
it('responds to specChange event for an added file', () => {
cy.get('[data-cy="spec-item-link"]')
- .should('have.length', 14)
+ // cannot assert a length since this is a virtualized list
+ // .should('have.length', 14)
.should('contain', 'blank-contents.spec.js')
.should('contain', 'dom-container.spec.js')
.should('contain', 'dom-content.spec.js')
@@ -23,7 +24,8 @@ describe('specChange subscription', () => {
}, { path: getPathForPlatform('cypress/e2e/new-file.spec.js') })
cy.get('[data-cy="spec-item-link"]')
- .should('have.length', 15)
+ // cannot assert a length since this is a virtualized list
+ // .should('have.length', 15)
.should('contain', 'blank-contents.spec.js')
.should('contain', 'dom-container.spec.js')
.should('contain', 'dom-content.spec.js')
@@ -33,7 +35,8 @@ describe('specChange subscription', () => {
it('responds to specChange event for a removed file', () => {
cy.get('[data-cy="spec-item-link"]')
- .should('have.length', 14)
+ // cannot assert a length since this is a virtualized list
+ // .should('have.length', 14)
.should('contain', 'blank-contents.spec.js')
.should('contain', 'dom-container.spec.js')
.should('contain', 'dom-content.spec.js')
@@ -44,10 +47,12 @@ describe('specChange subscription', () => {
}, { path: getPathForPlatform('cypress/e2e/dom-list.spec.js') })
cy.get('[data-cy="spec-item-link"]')
- .should('have.length', 13)
+ // cannot assert a length since this is a virtualized list
+ // .should('have.length', 13)
.should('contain', 'blank-contents.spec.js')
.should('contain', 'dom-container.spec.js')
.should('contain', 'dom-content.spec.js')
+ .should('not.contain', 'dom-list.spec.js')
})
it('handles adding the first file', () => {
@@ -69,6 +74,15 @@ describe('specChange subscription', () => {
getPathForPlatform('cypress/e2e/accounts/accounts_new.spec.js'),
getPathForPlatform('cypress/e2e/admin_users/admin_users_list.spec.js'),
getPathForPlatform('cypress/e2e/admin_users/admin.user/foo_list.spec.js'),
+ getPathForPlatform('cypress/e2e/z001.spec.js'),
+ getPathForPlatform('cypress/e2e/z002.spec.js'),
+ getPathForPlatform('cypress/e2e/z003.spec.js'),
+ getPathForPlatform('cypress/e2e/z004.spec.js'),
+ getPathForPlatform('cypress/e2e/z005.spec.js'),
+ getPathForPlatform('cypress/e2e/z006.spec.js'),
+ getPathForPlatform('cypress/e2e/z007.spec.js'),
+ getPathForPlatform('cypress/e2e/z008.spec.js'),
+ getPathForPlatform('cypress/e2e/z009.spec.js'),
],
})
@@ -102,6 +116,15 @@ describe('specChange subscription', () => {
getPathForPlatform('cypress/e2e/accounts/accounts_new.spec.js'),
getPathForPlatform('cypress/e2e/admin_users/admin_users_list.spec.js'),
getPathForPlatform('cypress/e2e/admin_users/admin.user/foo_list.spec.js'),
+ getPathForPlatform('cypress/e2e/z001.spec.js'),
+ getPathForPlatform('cypress/e2e/z002.spec.js'),
+ getPathForPlatform('cypress/e2e/z003.spec.js'),
+ getPathForPlatform('cypress/e2e/z004.spec.js'),
+ getPathForPlatform('cypress/e2e/z005.spec.js'),
+ getPathForPlatform('cypress/e2e/z006.spec.js'),
+ getPathForPlatform('cypress/e2e/z007.spec.js'),
+ getPathForPlatform('cypress/e2e/z008.spec.js'),
+ getPathForPlatform('cypress/e2e/z009.spec.js'),
],
})
@@ -119,7 +142,8 @@ describe('specChange subscription', () => {
it('responds to a cypress.config.js file change', () => {
cy.get('[data-cy="spec-item-link"]')
- .should('have.length', 14)
+ // cannot assert a length since this is a virtualized list
+ // .should('have.length', 14)
.should('contain', 'blank-contents.spec.js')
.should('contain', 'dom-container.spec.js')
.should('contain', 'dom-content.spec.js')
@@ -161,7 +185,7 @@ e2e: {
cy.get('body').type('f')
cy.get('[data-cy="spec-file-item"]')
- .should('have.length', 14)
+ .should('have.length', 23)
.should('contain', 'blank-contents.spec.js')
.should('contain', 'dom-container.spec.js')
.should('contain', 'dom-content.spec.js')
@@ -172,7 +196,7 @@ e2e: {
}, { path: getPathForPlatform('cypress/e2e/new-file.spec.js') })
cy.get('[data-cy="spec-file-item"]')
- .should('have.length', 15)
+ .should('have.length', 24)
.should('contain', 'blank-contents.spec.js')
.should('contain', 'dom-container.spec.js')
.should('contain', 'dom-content.spec.js')
@@ -187,7 +211,7 @@ e2e: {
cy.get('body').type('f')
cy.get('[data-cy="spec-file-item"]')
- .should('have.length', 14)
+ .should('have.length', 23)
.should('contain', 'blank-contents.spec.js')
.should('contain', 'dom-container.spec.js')
.should('contain', 'dom-content.spec.js')
@@ -198,7 +222,7 @@ e2e: {
}, { path: getPathForPlatform('cypress/e2e/dom-list.spec.js') })
cy.get('[data-cy="spec-file-item"]')
- .should('have.length', 13)
+ .should('have.length', 22)
.should('contain', 'blank-contents.spec.js')
.should('contain', 'dom-container.spec.js')
.should('contain', 'dom-content.spec.js')
@@ -226,6 +250,15 @@ e2e: {
getPathForPlatform('cypress/e2e/accounts/accounts_new.spec.js'),
getPathForPlatform('cypress/e2e/admin_users/admin_users_list.spec.js'),
getPathForPlatform('cypress/e2e/admin_users/admin.user/foo_list.spec.js'),
+ getPathForPlatform('cypress/e2e/z001.spec.js'),
+ getPathForPlatform('cypress/e2e/z002.spec.js'),
+ getPathForPlatform('cypress/e2e/z003.spec.js'),
+ getPathForPlatform('cypress/e2e/z004.spec.js'),
+ getPathForPlatform('cypress/e2e/z005.spec.js'),
+ getPathForPlatform('cypress/e2e/z006.spec.js'),
+ getPathForPlatform('cypress/e2e/z007.spec.js'),
+ getPathForPlatform('cypress/e2e/z008.spec.js'),
+ getPathForPlatform('cypress/e2e/z009.spec.js'),
],
})
@@ -248,7 +281,7 @@ e2e: {
cy.get('body').type('f')
cy.get('[data-cy="spec-file-item"]')
- .should('have.length', 14)
+ .should('have.length', 23)
.should('contain', 'blank-contents.spec.js')
.should('contain', 'dom-container.spec.js')
.should('contain', 'dom-content.spec.js')
@@ -290,14 +323,14 @@ e2e: {
cy.get('[data-cy="spec-pattern"]').contains('cypress/e2e/**/*.spec.{js,ts}')
cy.get('[data-cy="file-match-indicator"]')
- .should('contain', '14 Matches')
+ .should('contain', '23 Matches')
cy.withCtx(async (ctx, o) => {
await ctx.actions.file.writeFileInProject(o.path, '')
}, { path: getPathForPlatform('cypress/e2e/new-file.spec.js') })
cy.get('[data-cy="file-match-indicator"]')
- .should('contain', '15 Matches')
+ .should('contain', '24 Matches')
})
it('responds to specChange event for a removed file', () => {
@@ -307,14 +340,14 @@ e2e: {
cy.get('[data-cy="spec-pattern"]').contains('cypress/e2e/**/*.spec.{js,ts}')
cy.get('[data-cy="file-match-indicator"]')
- .should('contain', '14 Matches')
+ .should('contain', '23 Matches')
cy.withCtx(async (ctx, o) => {
await ctx.actions.file.removeFileInProject(o.path)
}, { path: getPathForPlatform('cypress/e2e/dom-list.spec.js') })
cy.get('[data-cy="file-match-indicator"]')
- .should('contain', '13 Matches')
+ .should('contain', '22 Matches')
})
it('handles removing the last file', () => {
@@ -340,6 +373,15 @@ e2e: {
getPathForPlatform('cypress/e2e/accounts/accounts_new.spec.js'),
getPathForPlatform('cypress/e2e/admin_users/admin_users_list.spec.js'),
getPathForPlatform('cypress/e2e/admin_users/admin.user/foo_list.spec.js'),
+ getPathForPlatform('cypress/e2e/z001.spec.js'),
+ getPathForPlatform('cypress/e2e/z002.spec.js'),
+ getPathForPlatform('cypress/e2e/z003.spec.js'),
+ getPathForPlatform('cypress/e2e/z004.spec.js'),
+ getPathForPlatform('cypress/e2e/z005.spec.js'),
+ getPathForPlatform('cypress/e2e/z006.spec.js'),
+ getPathForPlatform('cypress/e2e/z007.spec.js'),
+ getPathForPlatform('cypress/e2e/z008.spec.js'),
+ getPathForPlatform('cypress/e2e/z009.spec.js'),
],
})
@@ -361,7 +403,7 @@ e2e: {
cy.get('[data-cy="spec-pattern"]').contains('cypress/e2e/**/*.spec.{js,ts}')
cy.get('[data-cy="file-match-indicator"]')
- .should('contain', '14 Matches')
+ .should('contain', '23 Matches')
cy.withCtx(async (ctx) => {
await ctx.actions.file.writeFileInProject('cypress.config.js',
diff --git a/packages/app/cypress/e2e/support/execute-spec.ts b/packages/app/cypress/e2e/support/execute-spec.ts
index e27b85a0512b..5478bbf37c6a 100644
--- a/packages/app/cypress/e2e/support/execute-spec.ts
+++ b/packages/app/cypress/e2e/support/execute-spec.ts
@@ -9,7 +9,7 @@ declare global {
* 3. Waits (with a timeout of 30s) for the Rerun all tests button to be present. This ensures all tests have completed
*
*/
- waitForSpecToFinish()
+ waitForSpecToFinish(): void
}
}
}
diff --git a/packages/app/package.json b/packages/app/package.json
index 2f064685b791..99d9eebea668 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -34,7 +34,6 @@
"@vitejs/plugin-vue": "2.2.4",
"@vitejs/plugin-vue-jsx": "1.3.8",
"@vueuse/core": "7.2.2",
- "@windicss/plugin-interaction-variants": "1.0.0",
"ansi-to-html": "0.6.14",
"bluebird": "3.5.3",
"classnames": "2.3.1",
@@ -69,7 +68,6 @@
"vue-i18n": "9.2.0-beta.7",
"vue-router": "4",
"vue-tsc": "^0.3.0",
- "windicss": "3.1.4",
"wonka": "^4.0.15"
},
"files": [
diff --git a/packages/app/src/pages/Specs/Index.vue b/packages/app/src/pages/Specs/Index.vue
index bc39deb8e615..eb6945a9fb6f 100644
--- a/packages/app/src/pages/Specs/Index.vue
+++ b/packages/app/src/pages/Specs/Index.vue
@@ -11,6 +11,7 @@
import { computed, ref } from 'vue'
-import { gql, useQuery, useSubscription } from '@urql/vue'
+import { gql, SubscriptionHandlerArg, useQuery, useSubscription } from '@urql/vue'
import { useI18n } from '@cy/i18n'
import SpecsList from '../../specs/SpecsList.vue'
import NoSpecsPage from '../../specs/NoSpecsPage.vue'
import CreateSpecModal from '../../specs/CreateSpecModal.vue'
-import { SpecsPageContainerDocument, SpecsPageContainer_SpecsChangeDocument } from '../../generated/graphql'
+import { SpecsPageContainerDocument, SpecsPageContainer_SpecsChangeDocument, SpecsPageContainer_SpecListPollingDocument, SpecsPageContainer_BranchInfoDocument } from '../../generated/graphql'
const { t } = useI18n()
gql`
-query SpecsPageContainer {
+query SpecsPageContainer_BranchInfo {
+ currentProject {
+ id
+ branch
+ projectId
+ }
+}
+`
+
+gql`
+query SpecsPageContainer($fromBranch: String!, $hasBranch: Boolean!) {
...Specs_SpecsList
...NoSpecsPage
...CreateSpecModal
@@ -47,7 +58,7 @@ query SpecsPageContainer {
`
gql`
-subscription SpecsPageContainer_specsChange {
+subscription SpecsPageContainer_specsChange($fromBranch: String!, $hasBranch: Boolean!) {
specsChange {
id
specs {
@@ -58,9 +69,48 @@ subscription SpecsPageContainer_specsChange {
}
`
-useSubscription({ query: SpecsPageContainer_SpecsChangeDocument })
+gql`
+subscription SpecsPageContainer_specListPolling($fromBranch: String, $projectId: String) {
+ startPollingForSpecs(branchName: $fromBranch, projectId: $projectId)
+}
+`
-const query = useQuery({ query: SpecsPageContainerDocument })
+const branchInfo = useQuery({ query: SpecsPageContainer_BranchInfoDocument })
+
+const variables = computed(() => {
+ const fromBranch = branchInfo.data.value?.currentProject?.branch ?? ''
+ const hasBranch = Boolean(fromBranch)
+
+ return { fromBranch, hasBranch }
+})
+
+const pollingVariables = computed(() => {
+ const fromBranch = branchInfo.data.value?.currentProject?.branch ?? null
+ const projectId = branchInfo.data.value?.currentProject?.projectId ?? null
+
+ return { fromBranch, projectId }
+})
+
+useSubscription({
+ query: SpecsPageContainer_SpecsChangeDocument,
+ variables,
+})
+
+const mostRecentUpdate = ref(null)
+
+const updateMostRecentUpdate: SubscriptionHandlerArg = (_, reportedUpdate) => {
+ mostRecentUpdate.value = reportedUpdate?.startPollingForSpecs ?? null
+}
+
+useSubscription({
+ query: SpecsPageContainer_SpecListPollingDocument,
+ variables: pollingVariables,
+}, updateMostRecentUpdate)
+
+const query = useQuery({
+ query: SpecsPageContainerDocument,
+ variables,
+})
const isDefaultSpecPattern = computed(() => !!query.data.value?.currentProject?.isDefaultSpecPattern)
@@ -83,7 +133,6 @@ const closeCreateSpecModal = () => {
modalIsShown.value = false
generator.value = null
}
-
diff --git a/packages/app/src/runner/event-manager.ts b/packages/app/src/runner/event-manager.ts
index b43db785e39a..5b8be0ed6ae1 100644
--- a/packages/app/src/runner/event-manager.ts
+++ b/packages/app/src/runner/event-manager.ts
@@ -39,7 +39,7 @@ const driverToSocketEvents = 'backend:request automation:request mocha recorder:
const driverTestEvents = 'test:before:run:async test:after:run'.split(' ')
const driverToLocalEvents = 'viewport:changed config stop url:changed page:loading visit:failed visit:blank cypress:in:cypress:runner:event'.split(' ')
const socketRerunEvents = 'runner:restart watched:file:changed'.split(' ')
-const socketToDriverEvents = 'net:stubbing:event request:event script:error'.split(' ')
+const socketToDriverEvents = 'net:stubbing:event request:event script:error cross:origin:automation:cookies'.split(' ')
const localToReporterEvents = 'reporter:log:add reporter:log:state:changed reporter:log:remove'.split(' ')
/**
diff --git a/packages/app/src/runs/CloudConnectButton.vue b/packages/app/src/runs/CloudConnectButton.vue
index bc2e681d3645..fa0d25d620c6 100644
--- a/packages/app/src/runs/CloudConnectButton.vue
+++ b/packages/app/src/runs/CloudConnectButton.vue
@@ -10,6 +10,7 @@
diff --git a/packages/app/src/runs/RunResults.cy.tsx b/packages/app/src/runs/RunResults.cy.tsx
index f374dc3f9f57..efd23fc9146d 100644
--- a/packages/app/src/runs/RunResults.cy.tsx
+++ b/packages/app/src/runs/RunResults.cy.tsx
@@ -14,8 +14,8 @@ describe(' ', { viewportHeight: 150, viewportWidth: 250 }, () => {
result[key] = res[key]
})
},
- render (gql) {
- return
+ render (props) {
+ return
},
})
diff --git a/packages/app/src/runs/RunResults.vue b/packages/app/src/runs/RunResults.vue
index e8b8ec861cb3..fe79447f28f5 100644
--- a/packages/app/src/runs/RunResults.vue
+++ b/packages/app/src/runs/RunResults.vue
@@ -4,36 +4,19 @@
v-if="props.gql.totalFlakyTests"
class="rounded-md font-semibold bg-warning-100 text-sm py-2px px-4px text-warning-600 whitespace-nowrap"
>{{ props.gql.totalFlakyTests }} Flaky
-
-
-
- {{ result.name }}
- {{ result.value }}
-
-
+
diff --git a/packages/app/src/runs/RunsError.spec.tsx b/packages/app/src/runs/RunsError.spec.tsx
index f168bcee2e65..0b3261528c0b 100644
--- a/packages/app/src/runs/RunsError.spec.tsx
+++ b/packages/app/src/runs/RunsError.spec.tsx
@@ -6,17 +6,19 @@ describe(' ', () => {
cy.mount({
name: 'RunsError',
render () {
- return (
-
- The request timed out when trying to retrieve the recorded runs from the Cypress Dashboard.
- Please refresh the page to try again and visit our Status Page if this behavior continues.
-
-
)
+ return (
+
+
+ The request timed out when trying to retrieve the recorded runs from the Cypress Dashboard.
+ Please refresh the page to try again and visit our Status Page if this behavior continues.
+
+
+ )
},
})
})
diff --git a/packages/app/src/runs/RunsErrorRenderer.vue b/packages/app/src/runs/RunsErrorRenderer.vue
index 8ab117956f16..d9278287d8a8 100644
--- a/packages/app/src/runs/RunsErrorRenderer.vue
+++ b/packages/app/src/runs/RunsErrorRenderer.vue
@@ -38,7 +38,7 @@
diff --git a/packages/app/src/specs/InlineSpecListHeader.cy.tsx b/packages/app/src/specs/InlineSpecListHeader.cy.tsx
index 8ee30fd332de..3d31fa26f187 100644
--- a/packages/app/src/specs/InlineSpecListHeader.cy.tsx
+++ b/packages/app/src/specs/InlineSpecListHeader.cy.tsx
@@ -10,7 +10,6 @@ describe('InlineSpecListHeader', () => {
cy.wrap(search).as('search')
const methods = {
- search: search.value,
'onUpdate:search': (val: string) => {
search.value = val
},
@@ -19,7 +18,7 @@ describe('InlineSpecListHeader', () => {
cy.mount(() =>
(
-
+
))
}
@@ -28,6 +27,7 @@ describe('InlineSpecListHeader', () => {
const searchString = 'my/component.cy.tsx'
cy.findByLabelText(defaultMessages.specPage.searchPlaceholder)
+ // `force` necessary due to the field label being overlaid on top of the input
.type(searchString, { delay: 0, force: true })
.get('@search').its('value').should('eq', searchString)
})
@@ -40,6 +40,21 @@ describe('InlineSpecListHeader', () => {
.should('have.been.called')
})
+ it('clears search field when clear button is clicked', () => {
+ mountWithResultCount(0)
+
+ cy.findByTestId('clear-search-button')
+ .should('not.exist')
+
+ cy.findByLabelText(defaultMessages.specPage.searchPlaceholder)
+ // `force` necessary due to the field label being overlaid on top of the input
+ .type('abcd', { delay: 0, force: true })
+ .get('@search').its('value').should('eq', 'abcd')
+
+ cy.findByTestId('clear-search-button').click()
+ cy.get('@search').its('value').should('eq', '')
+ })
+
it('exposes the result count correctly to assistive tech', () => {
mountWithResultCount(0)
cy.contains('No Matches')
diff --git a/packages/app/src/specs/InlineSpecListHeader.vue b/packages/app/src/specs/InlineSpecListHeader.vue
index ac9a9617a760..b388a71e9567 100644
--- a/packages/app/src/specs/InlineSpecListHeader.vue
+++ b/packages/app/src/specs/InlineSpecListHeader.vue
@@ -3,7 +3,7 @@
class="border-b-1 border-gray-900 h-64px mx-16px grid gap-8px grid-cols-[minmax(0,1fr),24px] pointer-cursor items-center"
>
{{ t('specPage.searchPlaceholder') }}
+
+
+
)
+ }
+
+ it('mounts correctly with git available', () => {
+ mountWithProps(true)
+
+ cy.findByTestId('last-updated-header').trigger('mouseenter')
+
+ const expectedTooltipText = defaultMessages.specPage.lastUpdated.tooltip.gitInfoAvailable
+ .replace('{0}', defaultMessages.specPage.lastUpdated.tooltip.gitStatus)
+
+ cy.get('.v-popper__popper--shown').should('have.text', expectedTooltipText)
+
+ cy.percySnapshot()
+ })
+
+ it('mounts correctly with git unavailable', () => {
+ mountWithProps(false)
+
+ cy.findByTestId('last-updated-header').trigger('mouseenter')
+
+ const expectedTooltipText = defaultMessages.specPage.lastUpdated.tooltip.gitInfoUnavailable
+ .replace('{0}', defaultMessages.specPage.lastUpdated.tooltip.gitInfo)
+
+ cy.get('.v-popper__popper--shown').should('have.text', expectedTooltipText)
+
+ cy.percySnapshot()
+ })
+})
diff --git a/packages/app/src/specs/LastUpdatedHeader.vue b/packages/app/src/specs/LastUpdatedHeader.vue
new file mode 100644
index 000000000000..a7a4968fcffe
--- /dev/null
+++ b/packages/app/src/specs/LastUpdatedHeader.vue
@@ -0,0 +1,69 @@
+
+
+
+ {{ t('specPage.lastUpdated.header') }}
+
+
+
+
+
+ {{ t('specPage.lastUpdated.tooltip.gitStatus') }}
+
+
+
+
+
+ {{ t('specPage.lastUpdated.tooltip.gitInfo') }}
+
+
+
+
+
+
+
+
diff --git a/packages/app/src/specs/RunStatusDots.cy.tsx b/packages/app/src/specs/RunStatusDots.cy.tsx
new file mode 100644
index 000000000000..d099c8d91eb7
--- /dev/null
+++ b/packages/app/src/specs/RunStatusDots.cy.tsx
@@ -0,0 +1,128 @@
+import type { RunStatusDotsFragment } from '../generated/graphql'
+import RunStatusDots from './RunStatusDots.vue'
+import { fakeRuns } from '@packages/frontend-shared/cypress/support/mock-graphql/fakeCloudSpecRun'
+import { fill } from 'lodash'
+import type { CloudSpecRun } from '@packages/graphql/src/gen/cloud-source-types.gen'
+
+function mountWithRuns (runs: Required[]) {
+ const gql: RunStatusDotsFragment = {
+ id: 'id',
+ data: {
+ __typename: 'CloudProjectSpec',
+ retrievedAt: new Date().toISOString(),
+ id: 'id',
+ specRuns: {
+ nodes: [
+ ...runs as any, // suppress TS compiler
+ ],
+ },
+ },
+ }
+
+ cy.mount(() => {
+ return (
+
+
+
+ )
+ })
+}
+
+describe(' ', () => {
+ context('runs scenario 1', () => {
+ beforeEach(() => {
+ const runs = fakeRuns(['PASSED', 'FAILED', 'CANCELLED', 'ERRORED'])
+
+ mountWithRuns(runs)
+ })
+
+ it('renders as expected', () => {
+ cy.findByTestId('run-status-dots').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').contains('spec.cy.ts')
+ cy.findAllByTestId('run-status-dot-0').should('have.class', 'icon-light-orange-400')
+ cy.findAllByTestId('run-status-dot-1').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-2').should('have.class', 'icon-light-red-400')
+ cy.findAllByTestId('run-status-dot-latest').should('not.have.class', 'animate-spin')
+ })
+ })
+
+ context('runs scenario 2', () => {
+ beforeEach(() => {
+ const runs = fakeRuns(['NOTESTS', 'UNCLAIMED', 'RUNNING', 'TIMEDOUT'])
+
+ mountWithRuns(runs)
+ })
+
+ it('renders as expected', () => {
+ cy.findByTestId('run-status-dots').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').contains('spec.cy.ts')
+ cy.findAllByTestId('run-status-dot-0').should('have.class', 'icon-light-orange-400')
+ cy.findAllByTestId('run-status-dot-1').should('have.class', 'icon-light-indigo-400')
+ cy.findAllByTestId('run-status-dot-2').should('have.class', 'icon-light-gray-400')
+ cy.findAllByTestId('run-status-dot-latest').should('not.have.class', 'animate-spin')
+ })
+ })
+
+ context('single RUNNING status', () => {
+ beforeEach(() => {
+ const runs = fakeRuns(['RUNNING'])
+
+ mountWithRuns(runs)
+ })
+
+ it('renders as expected', () => {
+ cy.findByTestId('run-status-dots').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').contains('spec.cy.ts')
+ cy.findAllByTestId('run-status-dot-0').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-1').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-2').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-latest').should('have.class', 'animate-spin')
+ })
+ })
+
+ context('single UNCLAIMED status', () => {
+ beforeEach(() => {
+ const runs = fakeRuns(['UNCLAIMED'])
+
+ mountWithRuns(runs)
+ })
+
+ it('renders as expected', () => {
+ cy.findByTestId('run-status-dots').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').contains('spec.cy.ts')
+ cy.findAllByTestId('run-status-dot-0').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-1').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-2').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-latest').should('not.have.class', 'animate-spin')
+ })
+ })
+
+ context('no runs', () => {
+ beforeEach(() => {
+ mountWithRuns([])
+ })
+
+ it('renders placeholder without tooltip or link', () => {
+ cy.findByTestId('external').should('not.exist')
+ cy.findByTestId('run-status-dots').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').should('not.exist')
+ })
+ })
+
+ context('unknown/unhandled statuses', () => {
+ beforeEach(() => {
+ const runs = fakeRuns(fill(['', '', '', ''], 'FAKE_UNKNOWN_STATUS' as any))
+
+ mountWithRuns(runs)
+ })
+
+ it('renders as expected', () => {
+ cy.findByTestId('run-status-dots').trigger('mouseenter')
+ cy.get('.v-popper__popper--shown').contains('spec.cy.ts')
+ cy.findAllByTestId('run-status-dot-0').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-1').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-2').should('have.class', 'icon-light-gray-300')
+ cy.findAllByTestId('run-status-dot-latest').should('not.have.class', 'animate-spin')
+ })
+ })
+})
diff --git a/packages/app/src/specs/RunStatusDots.vue b/packages/app/src/specs/RunStatusDots.vue
new file mode 100644
index 000000000000..14620caa480d
--- /dev/null
+++ b/packages/app/src/specs/RunStatusDots.vue
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/app/src/specs/SpecHeaderCloudDataTooltip.cy.tsx b/packages/app/src/specs/SpecHeaderCloudDataTooltip.cy.tsx
new file mode 100644
index 000000000000..5f765be706c8
--- /dev/null
+++ b/packages/app/src/specs/SpecHeaderCloudDataTooltip.cy.tsx
@@ -0,0 +1,225 @@
+import { SpecHeaderCloudDataTooltipFragmentDoc, SpecHeaderCloudDataTooltip_RequestAccessDocument } from '../generated/graphql-test'
+import SpecHeaderCloudDataTooltip from './SpecHeaderCloudDataTooltip.vue'
+import { get, set } from 'lodash'
+import { defaultMessages } from '@cy/i18n'
+
+describe('SpecHeaderCloudDataTooltip', () => {
+ function mountWithStatus (
+ status: 'NOT_FOUND' | 'LOGGED_OUT' | 'CONNECTED' | 'NOT_CONNECTED' | 'UNAUTHORIZED' | 'ACCESS_REQUESTED',
+ mode: string,
+ msgKeys: {
+ header: string
+ connected: string
+ notConnected: string
+ noAccess: string
+ docs: string
+ },
+ ) {
+ cy.mountFragment(SpecHeaderCloudDataTooltipFragmentDoc, {
+ onResult: (ctx) => {
+ set(ctx, 'cloudViewer', { __typename: 'CloudUser', id: 'abc123' })
+
+ switch (status) {
+ case 'LOGGED_OUT':
+ set(ctx, 'cloudViewer', null)
+ break
+ case 'NOT_CONNECTED':
+ set(ctx, 'currentProject.cloudProject.__typename', null)
+ break
+ case 'NOT_FOUND':
+ set(ctx, 'currentProject.cloudProject.__typename', 'CloudProjectNotFound')
+ break
+ case 'ACCESS_REQUESTED':
+ set(ctx, 'currentProject.cloudProject.__typename', 'CloudProjectUnauthorized')
+ set(ctx, 'currentProject.cloudProject.hasRequestedAccess', true)
+ break
+ case 'UNAUTHORIZED':
+ set(ctx, 'currentProject.cloudProject.__typename', 'CloudProjectUnauthorized')
+ break
+ case 'CONNECTED':
+ default:
+ set(ctx, 'currentProject.cloudProject.__typename', 'CloudProjectSpec')
+ break
+ }
+ },
+ render: (gql) => {
+ const showLoginSpy = cy.spy().as('showLoginSpy')
+ const showConnectToProjectSpy = cy.spy().as('showConnectToProjectSpy')
+
+ return (
+
+
+
)
+ },
+ })
+ }
+
+ [{
+ mode: 'AVG_DURATION',
+ msgKeys: {
+ header: 'specPage.averageDuration.header',
+ connected: 'specPage.averageDuration.tooltip.connected',
+ notConnected: 'specPage.averageDuration.tooltip.notConnected',
+ noAccess: 'specPage.averageDuration.tooltip.noAccess',
+ docs: 'specPage.averageDuration.tooltip.linkText',
+ },
+ }, {
+ mode: 'LATEST_RUNS',
+ msgKeys: {
+ header: 'specPage.latestRuns.header',
+ connected: 'specPage.latestRuns.tooltip.connected',
+ notConnected: 'specPage.latestRuns.tooltip.notConnected',
+ noAccess: 'specPage.latestRuns.tooltip.noAccess',
+ docs: 'specPage.latestRuns.tooltip.linkText',
+ },
+ }].forEach(({ mode, msgKeys }) => {
+ context(mode, () => {
+ context('connected', () => {
+ beforeEach(() => {
+ mountWithStatus('CONNECTED', mode, msgKeys)
+ })
+
+ it('should render expected tooltip content', () => {
+ cy.get('.v-popper').trigger('mouseenter')
+
+ cy.findByTestId('cloud-data-tooltip-content')
+ .should('be.visible')
+ .and('contain', get(defaultMessages, msgKeys.connected).replace('{0}', get(defaultMessages, msgKeys.docs)))
+
+ cy.get('button').should('not.exist')
+
+ cy.percySnapshot()
+ })
+ })
+
+ context('not connected', () => {
+ beforeEach(() => {
+ mountWithStatus('NOT_CONNECTED', mode, msgKeys)
+ })
+
+ it('should render expected tooltip content', () => {
+ cy.get('.v-popper').trigger('mouseenter')
+
+ cy.findByTestId('cloud-data-tooltip-content')
+ .should('be.visible')
+ .and('contain', get(defaultMessages, msgKeys.notConnected).replace('{0}', get(defaultMessages, msgKeys.docs)))
+
+ cy.findByTestId('connect-button')
+ .should('be.visible')
+ .click()
+
+ cy.get('@showConnectToProjectSpy').should('have.been.calledOnce')
+
+ cy.percySnapshot()
+ })
+ })
+
+ context('unauthorized', () => {
+ beforeEach(() => {
+ mountWithStatus('UNAUTHORIZED', mode, msgKeys)
+ })
+
+ it('should render expected tooltip content', () => {
+ cy.get('.v-popper').trigger('mouseenter')
+
+ cy.findByTestId('cloud-data-tooltip-content')
+ .should('be.visible')
+ .and('contain', get(defaultMessages, msgKeys.noAccess).replace('{0}', get(defaultMessages, msgKeys.docs)))
+
+ cy.percySnapshot()
+ })
+
+ it('should update to "Request Sent" when button is triggered', () => {
+ cy.stubMutationResolver(SpecHeaderCloudDataTooltip_RequestAccessDocument, (defineResult) => {
+ return defineResult({
+ cloudProjectRequestAccess: {
+ __typename: 'CloudProjectUnauthorized',
+ message: 'msg',
+ hasRequestedAccess: true,
+ },
+ })
+ })
+
+ cy.get('.v-popper').trigger('mouseenter')
+
+ cy.findByTestId('request-access-button')
+ .should('be.visible')
+ .click()
+
+ cy.findByTestId('access-requested-button')
+ .should('be.visible')
+ .should('be.disabled')
+ })
+ })
+
+ context('access requested', () => {
+ beforeEach(() => {
+ mountWithStatus('ACCESS_REQUESTED', mode, msgKeys)
+ })
+
+ it('should render expected tooltip content', () => {
+ cy.get('.v-popper').trigger('mouseenter')
+
+ cy.findByTestId('cloud-data-tooltip-content')
+ .should('be.visible')
+ .and('contain', get(defaultMessages, msgKeys.noAccess).replace('{0}', get(defaultMessages, msgKeys.docs)))
+
+ cy.findByTestId('access-requested-button')
+ .should('be.visible')
+ .should('be.disabled')
+
+ cy.percySnapshot()
+ })
+ })
+
+ context('logged out', () => {
+ beforeEach(() => {
+ mountWithStatus('LOGGED_OUT', mode, msgKeys)
+ })
+
+ it('should render expected tooltip content', () => {
+ cy.get('.v-popper').trigger('mouseenter')
+
+ cy.findByTestId('cloud-data-tooltip-content')
+ .should('be.visible')
+ .and('contain', get(defaultMessages, msgKeys.notConnected).replace('{0}', get(defaultMessages, msgKeys.docs)))
+
+ cy.findByTestId('login-button')
+ .should('be.visible')
+ .click()
+
+ cy.get('@showLoginSpy').should('have.been.calledOnce')
+
+ cy.percySnapshot()
+ })
+ })
+
+ context('not found', () => {
+ beforeEach(() => {
+ mountWithStatus('NOT_FOUND', mode, msgKeys)
+ })
+
+ it('should render expected tooltip content', () => {
+ cy.get('.v-popper').trigger('mouseenter')
+
+ cy.findByTestId('cloud-data-tooltip-content')
+ .should('be.visible')
+ .and('contain', get(defaultMessages, msgKeys.notConnected).replace('{0}', get(defaultMessages, msgKeys.docs)))
+
+ cy.findByTestId('reconnect-button')
+ .should('be.visible')
+ .click()
+
+ cy.get('@showConnectToProjectSpy').should('have.been.calledOnce')
+
+ cy.percySnapshot()
+ })
+ })
+ })
+ })
+})
diff --git a/packages/app/src/specs/SpecHeaderCloudDataTooltip.vue b/packages/app/src/specs/SpecHeaderCloudDataTooltip.vue
new file mode 100644
index 000000000000..d8cbf57383c3
--- /dev/null
+++ b/packages/app/src/specs/SpecHeaderCloudDataTooltip.vue
@@ -0,0 +1,244 @@
+
+
+
+ {{ t(VALUES[mode].header) }}
+ {{ t(VALUES[mode].shortHeader || VALUES[mode].header) }}
+
+
+
+
+
+
+ {{ t(VALUES[mode].docs) }}
+
+
+
+
+
+ {{ t('specPage.dashboardLoginButton') }}
+
+
+ {{ t("specPage.connectProjectButton") }}
+
+
+ {{ t("specPage.reconnectProjectButton") }}
+
+
+ {{ t("specPage.requestAccessButton") }}
+
+
+ {{ t("specPage.requestSentButton") }}
+
+
+
+
+
+
+
+
diff --git a/packages/app/src/specs/SpecListGitInfo.cy.tsx b/packages/app/src/specs/SpecListGitInfo.cy.tsx
new file mode 100644
index 000000000000..f448d46f730b
--- /dev/null
+++ b/packages/app/src/specs/SpecListGitInfo.cy.tsx
@@ -0,0 +1,81 @@
+import { SpecListRowFragmentDoc } from '../generated/graphql-test'
+import SpecListGitInfo from './SpecListGitInfo.vue'
+
+describe('SpecListGitInfo', () => {
+ const mountWithStatus = (status: 'created' | 'modified' | 'unmodified') => {
+ cy.mountFragment(SpecListRowFragmentDoc, {
+ onResult: (ctx) => {
+ ctx.author = 'Bob'
+ ctx.lastModifiedHumanReadable = 'Last Tuesday'
+ ctx.lastModifiedTimestamp = new Date('02-02-2022').toISOString()
+ ctx.statusType = status
+ ctx.shortHash = 'abc123'
+ ctx.subject = 'chore: did stuff'
+ },
+ render: (gql) => ,
+ })
+
+ cy.findByTestId('git-info-row').as('row')
+ }
+
+ context('created', () => {
+ beforeEach(() => {
+ mountWithStatus('created')
+ })
+
+ it('renders created icon and expected text', () => {
+ cy.get('@row').should('have.text', 'Last Tuesday')
+ cy.findByTestId('created-icon').should('be.visible')
+ })
+
+ it('provides expected tooltip content', () => {
+ cy.findByTestId('git-info-tooltip').should('not.exist')
+ cy.get('.v-popper').trigger('mouseenter')
+ cy.findByTestId('git-info-tooltip').should('be.visible')
+ .and('have.text', 'Created')
+
+ cy.percySnapshot()
+ })
+ })
+
+ context('modified', () => {
+ beforeEach(() => {
+ mountWithStatus('modified')
+ })
+
+ it('renders created icon and expected text', () => {
+ cy.get('@row').should('have.text', 'Last Tuesday')
+ cy.findByTestId('modified-icon').should('be.visible')
+ })
+
+ it('provides expected tooltip content', () => {
+ cy.findByTestId('git-info-tooltip').should('not.exist')
+ cy.get('.v-popper').trigger('mouseenter')
+ cy.findByTestId('git-info-tooltip').should('be.visible')
+ .and('have.text', 'Modified')
+
+ cy.percySnapshot()
+ })
+ })
+
+ context('unmodified', () => {
+ beforeEach(() => {
+ mountWithStatus('unmodified')
+ })
+
+ it('renders created icon and expected text', () => {
+ cy.get('@row').should('have.text', 'Last Tuesday')
+ cy.findByTestId('unmodified-icon').should('be.visible')
+ })
+
+ it('provides expected tooltip content', () => {
+ cy.findByTestId('git-info-tooltip').should('not.exist')
+ cy.get('.v-popper').trigger('mouseenter')
+ cy.findByTestId('git-info-tooltip').should('be.visible')
+ .and('contain', 'chore: did stuff')
+ .and('contain', 'abc123 by Bob')
+
+ cy.percySnapshot()
+ })
+ })
+})
diff --git a/packages/app/src/specs/SpecListGitInfo.vue b/packages/app/src/specs/SpecListGitInfo.vue
index 94b1a0144fdc..ce34c395d2ec 100644
--- a/packages/app/src/specs/SpecListGitInfo.vue
+++ b/packages/app/src/specs/SpecListGitInfo.vue
@@ -1,23 +1,33 @@
-
+
+
+
+
+
+ {{ props.gql?.lastModifiedHumanReadable ?? '' }}
+
+
-
+
{{ tooltipMainText }}
@@ -31,6 +41,7 @@
{{ props.gql?.lastModifiedHumanReadable ?? '' }}
@@ -70,14 +81,17 @@ const classes = computed(() => {
created: {
icon: DocumentIconPlus,
iconClasses: 'icon-dark-jade-400 icon-light-jade-50',
+ testId: 'created-icon',
},
modified: {
icon: DocumentIconPlusMinus,
iconClasses: 'icon-dark-orange-400 icon-light-orange-50',
+ testId: 'modified-icon',
},
unmodified: {
icon: CommitIcon,
iconClasses: 'icon-light-gray-500',
+ testId: 'unmodified-icon',
},
noGitInfo: {},
}[props.gql?.statusType || 'unmodified']
diff --git a/packages/app/src/specs/SpecRunSummary.cy.tsx b/packages/app/src/specs/SpecRunSummary.cy.tsx
new file mode 100644
index 000000000000..e711be4dd4a6
--- /dev/null
+++ b/packages/app/src/specs/SpecRunSummary.cy.tsx
@@ -0,0 +1,213 @@
+import SpecRunSummary from './SpecRunSummary.vue'
+import { exampleRuns } from '@packages/frontend-shared/cypress/support/mock-graphql/fakeCloudSpecRun'
+import type { CloudSpecRun } from '@packages/graphql/src/gen/cloud-source-types.gen'
+
+function validateTopBorder (color: string): void {
+ cy.findByTestId('spec-run-summary')
+ .should('have.css', 'border-top', `4px solid ${color}`)
+}
+
+function validateFilename (expected: string): void {
+ cy.findByTestId('spec-run-filename').should('have.text', expected)
+}
+
+function validateTimeAgo (expected: string): void {
+ cy.findByTestId('spec-run-time-ago')
+ .should('have.text', expected)
+}
+
+function validateStatus (status: string, color: string): void {
+ cy.findByTestId('spec-run-status')
+ .should('have.css', 'color', color)
+ .and('have.text', status)
+}
+
+function validateDuration1 (expected: string): void {
+ cy.findByTestId('spec-run-duration-1')
+ .should('have.text', expected)
+}
+
+function validateDuration2 (expected: string): void {
+ cy.findByTestId('spec-run-duration-2')
+ .should('have.text', expected)
+}
+
+function validateResultCountsVisible (): void {
+ cy.findByTestId('spec-run-result-counts').should('be.visible')
+}
+
+describe('
', { keystrokeDelay: 0 }, () => {
+ const runs = exampleRuns()
+
+ function mountWithRun (run: CloudSpecRun) {
+ const createdAt = new Date()
+
+ createdAt.setFullYear(createdAt.getFullYear() - 1)
+ run.createdAt = createdAt.toISOString()
+ cy.mount(
)
+ }
+
+ context('passing', () => {
+ beforeEach(() => {
+ mountWithRun(runs[0])
+ })
+
+ it('should render expected content', () => {
+ // Green border
+ validateTopBorder('rgb(31, 169, 113)')
+ validateFilename('mySpecFile.spec.ts')
+ // Green text
+ validateStatus('Passed', 'rgb(0, 129, 77)')
+ validateTimeAgo('1 year ago')
+ validateDuration1('2:23')
+ validateDuration2('2:39')
+ validateResultCountsVisible()
+ })
+ })
+
+ context('failed', () => {
+ beforeEach(() => {
+ mountWithRun(runs[1])
+ })
+
+ it('should render expected content', () => {
+ // Red border
+ validateTopBorder('rgb(228, 87, 112)')
+ validateFilename('mySpecFile.spec.ts')
+ // Red text
+ validateStatus('Failed', 'rgb(198, 43, 73)')
+ validateTimeAgo('1 year ago')
+ validateDuration1('1:02:40')
+ cy.findByTestId('spec-run-duration-2').should('not.exist')
+ validateResultCountsVisible()
+ })
+ })
+
+ context('canceled', () => {
+ beforeEach(() => {
+ mountWithRun(runs[2])
+ })
+
+ it('should render expected content', () => {
+ // Gray border
+ validateTopBorder('rgb(144, 149, 173)')
+ validateFilename('mySpecFile.spec.ts')
+ // Gray text
+ validateStatus('Canceled', 'rgb(90, 95, 122)')
+ validateTimeAgo('1 year ago')
+ validateDuration1('2:23')
+ validateDuration2('2:39')
+ validateResultCountsVisible()
+ })
+ })
+
+ context('errored', () => {
+ beforeEach(() => {
+ mountWithRun(runs[3])
+ })
+
+ it('should render expected content', () => {
+ // Orange border
+ validateTopBorder('rgb(219, 121, 3)')
+ validateFilename('mySpecFile.spec.ts')
+ // Orange text
+ validateStatus('Errored', 'rgb(189, 88, 0)')
+ validateTimeAgo('1 year ago')
+ validateDuration1('1:02:40')
+ validateDuration2('10:26:40')
+ validateResultCountsVisible()
+ })
+ })
+
+ context('no tests', () => {
+ beforeEach(() => {
+ mountWithRun(runs[4])
+ })
+
+ it('should render expected content', () => {
+ // Gray border
+ validateTopBorder('rgb(144, 149, 173)')
+ validateFilename('mySpecFile.spec.ts')
+ validateStatus('No tests', 'rgb(90, 95, 122)')
+ validateTimeAgo('1 year ago')
+ validateDuration1('2:23')
+ validateDuration2('2:39')
+ validateResultCountsVisible()
+ })
+ })
+
+ context('running', () => {
+ beforeEach(() => {
+ mountWithRun(runs[6])
+ })
+
+ it('should render expected content', () => {
+ // Blue border
+ validateTopBorder('rgb(100, 112, 243)')
+ validateFilename('mySpecFile.spec.ts')
+ // Blue text
+ validateStatus('Running', 'rgb(73, 86, 227)')
+ validateTimeAgo('1 year ago')
+ validateDuration1('2:23')
+ validateDuration2('2:39')
+ validateResultCountsVisible()
+ })
+ })
+
+ context('timed out', () => {
+ beforeEach(() => {
+ mountWithRun(runs[7])
+ })
+
+ it('should render expected content', () => {
+ // Orange border
+ validateTopBorder('rgb(219, 121, 3)')
+ validateFilename('mySpecFile.spec.ts')
+ // Orange text
+ validateStatus('Timed out', 'rgb(189, 88, 0)')
+ validateTimeAgo('1 year ago')
+ validateDuration1('2:23')
+ validateDuration2('2:39')
+ validateResultCountsVisible()
+ })
+ })
+
+ context('queued', () => {
+ beforeEach(() => {
+ mountWithRun(runs[8])
+ })
+
+ it('should render expected content', () => {
+ // Gray border
+ validateTopBorder('rgb(144, 149, 173)')
+ validateFilename('mySpecFile.spec.ts')
+ // Gray text
+ validateStatus('Queued', 'rgb(90, 95, 122)')
+ validateTimeAgo('1 year ago')
+ validateDuration1('2:23')
+ validateDuration2('2:39')
+ validateResultCountsVisible()
+ })
+ })
+
+ context('unhandled status', () => {
+ beforeEach(() => {
+ mountWithRun(runs[9])
+ })
+
+ it('should render expected content', () => {
+ // Gray border
+ validateTopBorder('rgb(144, 149, 173)')
+ validateFilename('mySpecFile.spec.ts')
+
+ // Should not render any status text
+ cy.findByTestId('spec-run-status')
+ .should('not.exist')
+
+ validateTimeAgo('1 year ago')
+ validateDuration1('2:23')
+ validateDuration2('2:39')
+ validateResultCountsVisible()
+ })
+ })
+})
diff --git a/packages/app/src/specs/SpecRunSummary.vue b/packages/app/src/specs/SpecRunSummary.vue
new file mode 100644
index 000000000000..66186a71a843
--- /dev/null
+++ b/packages/app/src/specs/SpecRunSummary.vue
@@ -0,0 +1,184 @@
+
+
+
+ {{ props.specFileNoExtension }} {{ props.specFileExtension }}
+
+
+
+ {{ statusText }}
+
+
+
+ {{ getTimeAgo(props.run.createdAt) }}
+
+
+
+ {{ durationText1 }}
+
+
+ -
+
+
+ {{ durationText2 }}
+
+
+
+
+
+
+
+
+
diff --git a/packages/app/src/specs/SpecsList.cy.tsx b/packages/app/src/specs/SpecsList.cy.tsx
index 37bc249b7aec..459b7c37b069 100644
--- a/packages/app/src/specs/SpecsList.cy.tsx
+++ b/packages/app/src/specs/SpecsList.cy.tsx
@@ -2,38 +2,39 @@ import SpecsList from './SpecsList.vue'
import { Specs_SpecsListFragmentDoc, SpecsListFragment, TestingTypeEnum } from '../generated/graphql-test'
import { defaultMessages } from '@cy/i18n'
-function mountWithTestingType (testingType: TestingTypeEnum) {
- cy.mountFragment(Specs_SpecsListFragmentDoc, {
- onResult: (ctx) => {
- if (!ctx.currentProject) throw new Error('need current project')
-
- ctx.currentProject.currentTestingType = testingType
-
- return ctx
- },
- render: (gqlVal) => {
- return
- },
- })
-}
-
-let specs: Array
= []
-
describe(' ', { keystrokeDelay: 0 }, () => {
+ let specs: Array
+
+ function mountWithTestingType (testingType: TestingTypeEnum | undefined) {
+ specs = []
+ const showCreateSpecModalSpy = cy.spy().as('showCreateSpecModalSpy')
+
+ cy.mountFragment(Specs_SpecsListFragmentDoc, {
+ variableTypes: {
+ hasBranch: 'Boolean',
+ },
+ variables: {
+ hasBranch: true,
+ },
+ onResult: (ctx) => {
+ if (!ctx.currentProject) throw new Error('need current project')
+
+ specs = ctx.currentProject?.specs || []
+ if (testingType) {
+ ctx.currentProject.currentTestingType = testingType
+ }
+
+ return ctx
+ },
+ render: (gqlVal) => {
+ return
+ },
+ })
+ }
+
context('when testingType is unset', () => {
beforeEach(() => {
- const showCreateSpecModalSpy = cy.spy().as('showCreateSpecModalSpy')
-
- cy.mountFragment(Specs_SpecsListFragmentDoc, {
- onResult: (ctx) => {
- specs = ctx.currentProject?.specs || []
-
- return ctx
- },
- render: (gqlVal) => {
- return
- },
- })
+ mountWithTestingType(undefined)
})
it('should filter specs', () => {
@@ -119,6 +120,51 @@ describe(' ', { keystrokeDelay: 0 }, () => {
cy.contains(defaultMessages.createSpec.newSpec).click()
cy.get('@showCreateSpecModalSpy').should('have.been.calledOnce')
})
+
+ describe('column headers', () => {
+ // Spec name (first) column is handled by type-specific tests below
+
+ it('should display last updated column', () => {
+ cy.findByTestId('last-updated-header').as('header')
+ cy.get('@header').should('be.visible').and('have.text', 'Last updated')
+ })
+
+ context('when screen is wide', { viewportWidth: 1200 }, () => {
+ it('should display latest runs column with full text', () => {
+ cy.findByTestId('latest-runs-header').within(() => {
+ cy.findByTestId('short-header-text').should('not.be.visible')
+ cy.findByTestId('full-header-text').should('be.visible')
+ .and('have.text', 'Latest runs')
+ })
+ })
+
+ it('should display average duration column with full text', () => {
+ cy.findByTestId('average-duration-header').within(() => {
+ cy.findByTestId('short-header-text').should('not.be.visible')
+ cy.findByTestId('full-header-text').should('be.visible')
+ .and('have.text', 'Average duration')
+ })
+ })
+ })
+
+ context('when screen is narrow', { viewportWidth: 800 }, () => {
+ it('should display latest runs column with short text', () => {
+ cy.findByTestId('latest-runs-header').within(() => {
+ cy.findByTestId('full-header-text').should('not.be.visible')
+ cy.findByTestId('short-header-text').should('be.visible')
+ .and('have.text', 'Runs')
+ })
+ })
+
+ it('should display average duration column with full text', () => {
+ cy.findByTestId('average-duration-header').within(() => {
+ cy.findByTestId('full-header-text').should('not.be.visible')
+ cy.findByTestId('short-header-text').should('be.visible')
+ .and('have.text', 'Duration')
+ })
+ })
+ })
+ })
})
context('when testingType is e2e', () => {
@@ -127,7 +173,7 @@ describe(' ', { keystrokeDelay: 0 }, () => {
})
it('should display the e2e testing header', () => {
- cy.get('[data-cy="specs-testing-type-header"]').should('have.text', 'E2E specs')
+ cy.findByTestId('specs-testing-type-header').should('have.text', 'E2E specs')
})
})
@@ -137,7 +183,7 @@ describe(' ', { keystrokeDelay: 0 }, () => {
})
it('should display the component testing header', () => {
- cy.get('[data-cy="specs-testing-type-header"]').should('have.text', 'Component specs')
+ cy.findByTestId('specs-testing-type-header').should('have.text', 'Component specs')
})
})
})
diff --git a/packages/app/src/specs/SpecsList.vue b/packages/app/src/specs/SpecsList.vue
index 0a9a1b29a300..7a2024fcd3a2 100644
--- a/packages/app/src/specs/SpecsList.vue
+++ b/packages/app/src/specs/SpecsList.vue
@@ -4,17 +4,64 @@
v-if="isAlertOpen"
v-model="isAlertOpen"
status="error"
- :title="t('specPage.noSpecErrorTitle')"
+ :title="t('specPage.noSpecError.title')"
class="mb-16px"
:icon="WarningIcon"
dismissible
>
- {{ t('specPage.noSpecErrorIntro') }}
+ {{ t('specPage.noSpecError.intro') }}
{{ route.params.unrunnable }}
- {{ t('specPage.noSpecErrorExplainer') }}
+ {{ t('specPage.noSpecError.explainer') }}
+
+
+
+ {{ t('specPage.offlineWarning.explainer') }}
+
+
+
+
+ {{ t('specPage.fetchFailedWarning.explainer1') }}
+
+
+
+
+ Status Page
+
+
+
+
+ {{ t('specPage.fetchFailedWarning.refreshButton') }}
+
{{ props.gql.currentProject?.currentTestingType === 'component' ?
t('specPage.componentSpecsHeader') : t('specPage.e2eSpecsHeader') }}
-
-
{{ t('specPage.lastUpdatedHeader') }}
+
+
+
+
+
+
+
+
+
+
@@ -170,6 +175,7 @@
diff --git a/packages/frontend-shared/src/gql-components/topnav/LoginModal.cy.tsx b/packages/frontend-shared/src/gql-components/topnav/LoginModal.cy.tsx
index 7f990c668ec1..dd001c4f2b17 100644
--- a/packages/frontend-shared/src/gql-components/topnav/LoginModal.cy.tsx
+++ b/packages/frontend-shared/src/gql-components/topnav/LoginModal.cy.tsx
@@ -31,7 +31,7 @@ const mountSuccess = (viewer: TestCloudViewer = cloudViewer) => {
result.cloudViewer = viewer
result.cloudViewer.__typename = 'CloudUser'
},
- render: (gqlVal) =>
,
+ render: (gqlVal) =>
,
})
}
@@ -39,7 +39,7 @@ describe(' ', { viewportWidth: 1000, viewportHeight: 750 }, () => {
describe('progress communication', () => {
it('renders and reaches "opening browser" status', () => {
cy.mountFragment(LoginModalFragmentDoc, {
- render: (gqlVal) =>
,
+ render: (gqlVal) =>
,
})
cy.contains('h2', text.login.titleInitial).should('be.visible')
@@ -59,7 +59,7 @@ describe(' ', { viewportWidth: 1000, viewportHeight: 750 }, () => {
render: (gqlVal) => {
gqlVal.authState.browserOpened = true
- return
+ return
},
})
@@ -90,7 +90,7 @@ describe(' ', { viewportWidth: 1000, viewportHeight: 750 }, () => {
},
render: (gqlVal) =>
(
-
+
),
})
@@ -118,7 +118,7 @@ describe(' ', { viewportWidth: 1000, viewportHeight: 750 }, () => {
gqlVal.authState.message = errorText
return (
-
+
)
},
})
@@ -158,7 +158,7 @@ describe(' ', { viewportWidth: 1000, viewportHeight: 750 }, () => {
it('renders correct components if there is no internet connection', () => {
cy.mountFragment(LoginModalFragmentDoc, {
- render: (gqlVal) =>
,
+ render: (gqlVal) =>
,
})
cy.goOffline()
@@ -171,7 +171,7 @@ describe(' ', { viewportWidth: 1000, viewportHeight: 750 }, () => {
it('shows login action when the internet is back', () => {
cy.mountFragment(LoginModalFragmentDoc, {
- render: (gqlVal) =>
,
+ render: (gqlVal) =>
,
})
cy.goOffline()
diff --git a/packages/frontend-shared/src/gql-components/topnav/LoginModal.vue b/packages/frontend-shared/src/gql-components/topnav/LoginModal.vue
index 560135437b42..a7ddf8188284 100644
--- a/packages/frontend-shared/src/gql-components/topnav/LoginModal.vue
+++ b/packages/frontend-shared/src/gql-components/topnav/LoginModal.vue
@@ -79,7 +79,8 @@
@@ -107,13 +108,23 @@ import type { LoginModalFragment } from '../../generated/graphql'
const online = useOnline()
+function continueAuth (isLoggedIn: boolean) {
+ if (isLoggedIn) {
+ emit('loggedin')
+ }
+
+ emit('update:modelValue', false)
+}
+
const emit = defineEmits<{
(event: 'update:modelValue', value: boolean): void
+ (event: 'loggedin'): void
}>()
const props = defineProps<{
modelValue: boolean
gql: LoginModalFragment
+ utmMedium: string
}>()
gql`
diff --git a/packages/frontend-shared/src/graphql/urqlClient.ts b/packages/frontend-shared/src/graphql/urqlClient.ts
index 0eb0a9b1ac2e..9047dfe115e6 100644
--- a/packages/frontend-shared/src/graphql/urqlClient.ts
+++ b/packages/frontend-shared/src/graphql/urqlClient.ts
@@ -6,6 +6,7 @@ import {
errorExchange,
fetchExchange,
subscriptionExchange,
+ CombinedError,
} from '@urql/core'
import { devtoolsExchange } from '@urql/devtools'
import { useToast } from 'vue-toastification'
@@ -21,11 +22,38 @@ import { pubSubExchange } from './urqlExchangePubsub'
import { namedRouteExchange } from './urqlExchangeNamedRoute'
import type { SpecFile, AutomationElementId, Browser } from '@packages/types'
import { urqlFetchSocketAdapter } from './urqlFetchSocketAdapter'
-import type { DocumentNode } from 'graphql'
import { initializeGlobalSubscriptions } from './urqlGlobalSubscriptions'
+import type { GlobalSubscriptions_PushFragmentSubscription } from '../generated/graphql'
const toast = useToast()
+let hasError = false
+
+export function showError (error: CombinedError) {
+ const message = `
+ GraphQL Field Path: [${error.graphQLErrors?.[0]?.path?.join(', ')}]:
+
+ ${error.message ?? error.graphQLErrors?.[0]?.message}
+
+ ${error.stack ?? error.graphQLErrors?.[0]?.stack ?? ''}
+ `
+
+ if (process.env.NODE_ENV !== 'production' && !hasError) {
+ hasError = true
+ timeoutId = setTimeout(() => {
+ toast.error(message, {
+ timeout: false,
+ onClose () {
+ hasError = false
+ },
+ })
+ }, 1000)
+ }
+
+ // eslint-disable-next-line
+ console.error(error)
+}
+
export function makeCacheExchange (schema: any = urqlSchema) {
return graphcacheExchange({
...urqlCacheKeys,
@@ -33,10 +61,22 @@ export function makeCacheExchange (schema: any = urqlSchema) {
updates: {
Subscription: {
pushFragment (parent, args, cache, info) {
- const { pushFragment } = parent as { pushFragment: { id?: string, fragment: DocumentNode, data: any, typename: string }[] }
+ const { pushFragment } = parent as GlobalSubscriptions_PushFragmentSubscription
for (const toPush of pushFragment) {
- cache.writeFragment(toPush.fragment, toPush.data)
+ if (toPush.invalidateCache) {
+ cache.invalidate({ __typename: 'Query' })
+ continue
+ }
+
+ cache.writeFragment(toPush.fragment, toPush.data, toPush.variables ?? {})
+
+ if (toPush.errors?.length) {
+ // TODO: clean this up
+ showError({
+ graphQLErrors: toPush.errors,
+ } as CombinedError)
+ }
}
},
},
@@ -93,8 +133,6 @@ export function clearPendingError () {
}
export async function makeUrqlClient (config: UrqlClientConfig): Promise {
- let hasError = false
-
const exchanges: Exchange[] = [dedupExchange]
const io = getPubSubSource(config)
@@ -114,28 +152,7 @@ export async function makeUrqlClient (config: UrqlClientConfig): Promise
exchanges.push(
errorExchange({
onError (error) {
- const message = `
- GraphQL Field Path: [${error.graphQLErrors?.[0]?.path?.join(', ')}]:
-
- ${error.message}
-
- ${error.stack ?? ''}
- `
-
- if (process.env.NODE_ENV !== 'production' && !hasError) {
- hasError = true
- timeoutId = setTimeout(() => {
- toast.error(message, {
- timeout: false,
- onClose () {
- hasError = false
- },
- })
- }, 1000)
- }
-
- // eslint-disable-next-line
- console.error(error)
+ showError(error)
},
}),
// https://formidable.com/open-source/urql/docs/graphcache/errors/
diff --git a/packages/frontend-shared/src/graphql/urqlDetailedDebugExchange.ts b/packages/frontend-shared/src/graphql/urqlDetailedDebugExchange.ts
new file mode 100644
index 000000000000..7eddbb186ff7
--- /dev/null
+++ b/packages/frontend-shared/src/graphql/urqlDetailedDebugExchange.ts
@@ -0,0 +1,74 @@
+import md5 from 'md5'
+import type { Exchange } from '@urql/core'
+import { pipe, tap } from 'wonka'
+import jsonStableStringify from 'json-stable-stringify'
+import type { OperationDefinitionNode } from 'graphql'
+import { print } from 'graphql'
+
+declare global {
+ interface Window {
+ __toPrintClear: Function
+ __toPrint__: {
+ queries: Record
+ logs: any[]
+ data: Record
+ }
+ }
+}
+
+window.__toPrintClear = function () {
+ window.__toPrint__ = {
+ queries: [],
+ logs: [],
+ data: {},
+ }
+}
+
+/**
+ * detailedDebugExchange:
+ *
+ * This is not imported/included by default in the urqlClient, but can be very helpful when debugging
+ * edge-case bugs in the urqlCache exchange. To use, import & add in the exchanges array, prior to the
+ * makeCacheExchange() definition. Calling `copy(window.__toPrint__)` in the console will spit out a whole
+ * bunch of metadata logged about the URQL request/response handling. The `window.__toPrintClear` can be used
+ * to reset the state, if you need to narrow down the logs to a smaller scope of payloads.
+ */
+export const detailedDebugExchange: Exchange = ({ forward }) => {
+ return (ops$) => {
+ window.__toPrint__ ??= {
+ queries: [],
+ logs: [],
+ data: {},
+ }
+
+ return pipe(
+ ops$,
+ tap((op) => {
+ // @ts-ignore
+ window.__toPrint__.queries[(op.query.definitions[0] as OperationDefinitionNode).name?.value] = print(op.query)
+ window.__toPrint__.logs.push(JSON.parse(JSON.stringify({
+ debugType: 'incoming',
+ timestamp: new Date().valueOf(),
+ ...op,
+ query: (op.query.definitions[0] as OperationDefinitionNode).name?.value,
+ })))
+ }),
+ forward,
+ tap((result) => {
+ const hash = md5(jsonStableStringify(result.data))
+
+ window.__toPrint__.data[hash] = result.data
+ window.__toPrint__.logs.push(JSON.parse(JSON.stringify({
+ debugType: 'completed',
+ timestamp: new Date().valueOf(),
+ ...result,
+ data: hash,
+ operation: {
+ ...result.operation,
+ query: (result.operation.query.definitions[0] as OperationDefinitionNode).name?.value,
+ },
+ })))
+ }),
+ )
+ }
+}
diff --git a/packages/frontend-shared/src/graphql/urqlGlobalSubscriptions.ts b/packages/frontend-shared/src/graphql/urqlGlobalSubscriptions.ts
index a9ce37de491c..b2c08398f7c5 100644
--- a/packages/frontend-shared/src/graphql/urqlGlobalSubscriptions.ts
+++ b/packages/frontend-shared/src/graphql/urqlGlobalSubscriptions.ts
@@ -8,6 +8,9 @@ gql`
target
fragment
data
+ errors
+ variables
+ invalidateCache
}
}
`
diff --git a/packages/frontend-shared/src/locales/en-US.json b/packages/frontend-shared/src/locales/en-US.json
index b45e29dc04a8..4f5e9929b933 100644
--- a/packages/frontend-shared/src/locales/en-US.json
+++ b/packages/frontend-shared/src/locales/en-US.json
@@ -119,16 +119,62 @@
"pageTitle": "Specs",
"newSpecButton": "New Spec",
"searchPlaceholder": "Search Specs",
+ "clearSearch": "Clear search field",
"componentSpecsHeader": "Component specs",
"e2eSpecsHeader": "E2E specs",
- "lastUpdatedHeader": "Last updated",
+ "lastUpdated": {
+ "header": "Last updated",
+ "tooltip": {
+ "gitStatus": "Git status",
+ "gitInfo": "git info",
+ "gitInfoAvailable": "{0} of the spec files within this project",
+ "gitInfoUnavailable": "Cypress is unable to detect {0} for this project and has defaulted to showing file system data instead"
+ }
+ },
+ "latestRuns": {
+ "header": "Latest runs",
+ "headerShort": "Runs",
+ "tooltip": {
+ "connected": "The {0} in the Cypress Dashboard",
+ "notConnected": "Connect to the Cypress Dashboard to see the {0}",
+ "noAccess": "Request access to this project in the Cypress Dashboard to view the {0}",
+ "linkText": "status of your latest runs"
+ }
+ },
+ "averageDuration": {
+ "header": "Average duration",
+ "headerShort": "Duration",
+ "tooltip": {
+ "connected": "The {0} of your latest runs in the Cypress Dashboard",
+ "notConnected": "Connect to the Cypress Dashboard to see the {0} of your latest runs",
+ "noAccess": "Request access to this project in the Cypress Dashboard to view the {0} of your latest runs",
+ "linkText": "average spec durations"
+ }
+ },
+ "connectProjectButton": "Connect your project",
+ "dashboardLoginButton": "Log in to the Dashboard",
+ "reconnectProjectButton": "Reconnect your project",
+ "requestAccessButton": "Request access",
+ "requestSentButton": "Request sent",
"rows": {
"gitTooltipSubtext": "{shortHash} by {author}"
},
"noResultsMessage": "No specs matched your search:",
- "noSpecErrorTitle": "Spec not found",
- "noSpecErrorIntro": "There is no spec matching the following location:",
- "noSpecErrorExplainer": "It is possible that the file has been moved or deleted. Please choose from the list of specs below."
+ "noSpecError": {
+ "title": "Spec not found",
+ "intro": "There is no spec matching the following location:",
+ "explainer": "It is possible that the file has been moved or deleted. Please choose from the list of specs below."
+ },
+ "offlineWarning": {
+ "title": "No internet connection",
+ "explainer": "Please check your internet connection to resolve this issue. When your internet connection is fixed, we will automatically attempt to fetch the run metrics from the Cypress Dashboard."
+ },
+ "fetchFailedWarning": {
+ "title": "Lost connection",
+ "explainer1": "The request timed out or failed when trying to retrieve the recorded run metrics from the Cypress Dashboard. The information that you're seeing in the table below may be incomplete as a result.",
+ "explainer2": "Please refresh the page to try again and visit our {0} if this behavior continues.",
+ "refreshButton": "Try again"
+ }
},
"noResults": {
"defaultMessage": "No results matched your search:",
@@ -381,7 +427,7 @@
"errorNotFound": "Project not found",
"errorNotFoundButton": "Connect it again",
"errorNotLoggedIn": "You are not connected to the Cypress Dashboard",
- "errorNotLoggedInButton": "Log in to Cypress Dashboard"
+ "errorNotLoggedInButton": "Log in to the Cypress Dashboard"
},
"project": {
"title": "Project Settings",
diff --git a/packages/frontend-shared/src/utils/getUrlWithParams.ts b/packages/frontend-shared/src/utils/getUrlWithParams.ts
index 0e55a9dae2c9..f8c0b527ab3f 100644
--- a/packages/frontend-shared/src/utils/getUrlWithParams.ts
+++ b/packages/frontend-shared/src/utils/getUrlWithParams.ts
@@ -1,3 +1,5 @@
+import { getUtmSource } from './getUtmSource'
+
export type LinkWithParams = {
url: string
params: { [key: string]: string }
@@ -8,11 +10,7 @@ export const getUrlWithParams = (link: LinkWithParams) => {
const hasUtmParams = Object.keys(link.params).some((param) => param.startsWith('utm_'))
if (hasUtmParams) {
- // __CYPRESS_MODE__ is only set on the window in th browser app -
- // checking this allows us to know if links are clicked in the browser app or the launchpad
- const utm_source = window.__CYPRESS_MODE__ ? 'Binary: App' : 'Binary: Launchpad'
-
- link.params.utm_source = utm_source
+ link.params.utm_source = getUtmSource()
}
if (link.params) {
diff --git a/packages/frontend-shared/src/utils/getUtmSource.ts b/packages/frontend-shared/src/utils/getUtmSource.ts
new file mode 100644
index 000000000000..85e3996820a8
--- /dev/null
+++ b/packages/frontend-shared/src/utils/getUtmSource.ts
@@ -0,0 +1,7 @@
+export type LoginUtmSource = 'Binary: App' | 'Binary: Launchpad'
+
+// __CYPRESS_MODE__ is only set on the window in th browser app -
+// checking this allows us to know if links are clicked in the browser app or the launchpad
+export function getUtmSource (): LoginUtmSource {
+ return window.__CYPRESS_MODE__ ? 'Binary: App' : 'Binary: Launchpad'
+}
diff --git a/packages/frontend-shared/src/utils/time.ts b/packages/frontend-shared/src/utils/time.ts
index a4fd360e7169..738cd2c8e545 100644
--- a/packages/frontend-shared/src/utils/time.ts
+++ b/packages/frontend-shared/src/utils/time.ts
@@ -7,3 +7,26 @@ const timeAgo = new TimeAgo('en-US')
export function getTimeAgo (iso8601: string) {
return timeAgo.format(new Date(iso8601))
}
+
+export function getDurationString (totalSeconds: number): string {
+ const roundedTotalSeconds = Math.floor(totalSeconds / 1000)
+ const seconds = roundedTotalSeconds % 60
+ const roundedTotalMinutes = Math.floor(roundedTotalSeconds / 60)
+ const minutes = roundedTotalMinutes % 60
+ const roundedTotalHours = Math.floor(roundedTotalMinutes / 60)
+ const hours = roundedTotalHours % 60
+
+ if (hours) {
+ return `${hours}:${
+ minutes.toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false })
+ }:${
+ seconds.toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false })
+ }`
+ }
+
+ return `${
+ minutes
+ }:${
+ seconds.toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false })
+ }`
+}
diff --git a/packages/frontend-shared/vite.config.ts b/packages/frontend-shared/vite.config.ts
index a79e55a3f101..b35c4ba0b797 100644
--- a/packages/frontend-shared/vite.config.ts
+++ b/packages/frontend-shared/vite.config.ts
@@ -2,9 +2,9 @@ import path from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
-import WindiCSS from 'vite-plugin-windicss'
import VueI18n from '@intlify/vite-plugin-vue-i18n'
import VueSvgLoader from 'vite-svg-loader'
+import { CyCSSVitePlugin } from '@cypress-design/css'
import Components from 'unplugin-vue-components/vite'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
@@ -71,7 +71,19 @@ const makePlugins = (plugins) => {
}),
...plugins?.componentsOptions,
}),
- WindiCSS(),
+ CyCSSVitePlugin({
+ scan: {
+ // accepts globs and file paths relative to project root
+ include: [
+ 'index.html',
+ '**/*.{vue,html,tsx}',
+ path.resolve(__dirname, '../frontend-shared/**/*.{vue,html,tsx,svg}'),
+ path.resolve(__dirname, '../app/**/*.{vue,html,tsx,svg}'),
+ path.resolve(__dirname, '../launchpad/**/*.{vue,html,tsx,svg}'),
+ ],
+ exclude: ['node_modules/**/*', '.git/**/*'],
+ },
+ }),
VueSvgLoader(),
// package.json is modified and auto-updated when new cjs dependencies
diff --git a/packages/frontend-shared/windi.config.ts b/packages/frontend-shared/windi.config.ts
index b57322e1bb3e..ac065be05241 100644
--- a/packages/frontend-shared/windi.config.ts
+++ b/packages/frontend-shared/windi.config.ts
@@ -1,57 +1,14 @@
+/**
+ * This file is used for vscode plugin autocompletion of windi colors
+ */
+
+import { colors } from '@cypress-design/css'
import { defineConfig } from 'windicss/helpers'
-import InteractionVariants from '@windicss/plugin-interaction-variants'
-import { IconDuotoneColorsPlugin } from './.windicss/icon-color-plugins'
-import { safelist } from './.windicss/safelist'
-import { colors } from './.windicss/colors'
-import { shortcuts } from './.windicss/shortcuts'
-import path from 'path'
-import type { FullConfig } from 'windicss/types/interfaces'
-export const defaultConfig: FullConfig = {
- // This adds !important to all utility classes.
- // https://csswizardry.com/2016/05/the-importance-of-important/
- important: true,
+export default defineConfig({
theme: {
extend: {
- borderRadius: {
- DEFAULT: '4px',
- md: '4px' },
- fontFamily: {
- mono: '"Fira Code", monospace',
- },
colors,
- cursor: {
- 'ew-resize': 'ew-resize',
- },
- boxShadow: {
- 'dropdown': '0 1px 3px 0 rgba(0, 0, 0, 0.2)',
- },
},
},
- safelist,
- variants: {
- // What's hocus?
- // Hocus is a portmanteau of hover + focus. This is useful because
- // many of our styles are the same for both hover and focus.
- backgroundColor: ['group-focus-within', 'group-focus-visible', 'group-active', 'group-visited', 'group-disabled', 'hocus', 'group-hocus', 'can-hover', 'no-hover'],
- },
- plugins: [
- IconDuotoneColorsPlugin,
- InteractionVariants,
- require('windicss/plugin/filters'),
- ],
- shortcuts,
- extract: {
- // accepts globs and file paths relative to project root
- include: [
- 'index.html',
- '**/*.{vue,html,tsx}',
- path.resolve(__dirname, '../frontend-shared/**/*.{vue,html,tsx,svg,ts}'),
- path.resolve(__dirname, '../app/**/*.{vue,html,tsx,svg}'),
- path.resolve(__dirname, '../launchpad/**/*.{vue,html,tsx,svg}'),
- ],
- exclude: ['node_modules/**/*', '.git/**/*'],
- },
-}
-
-export default defineConfig(defaultConfig)
+})
diff --git a/packages/graphql/.eslintrc.json b/packages/graphql/.eslintrc.json
index 0eda50e708ec..b396ce9ebcf6 100644
--- a/packages/graphql/.eslintrc.json
+++ b/packages/graphql/.eslintrc.json
@@ -10,6 +10,9 @@
"plugins": [
"cypress"
],
+ "rules": {
+ "@typescript-eslint/no-unused-vars": "off"
+ },
"overrides": [
{
"files": [
@@ -19,44 +22,8 @@
"no-useless-constructor": "off",
"@typescript-eslint/explicit-function-return-type": [
"error"
- ],
- "no-restricted-imports": [
- "error",
- "assert",
- "buffer",
- "child_process",
- "cluster",
- "crypto",
- "dgram",
- "dns",
- "domain",
- "events",
- "freelist",
- "fs",
- "http",
- "https",
- "module",
- "net",
- "os",
- "path",
- "punycode",
- "querystring",
- "readline",
- "repl",
- "smalloc",
- "stream",
- "string_decoder",
- "sys",
- "timers",
- "tls",
- "tracing",
- "tty",
- "url",
- "util",
- "vm",
- "zlib"
]
}
}
]
-}
+}
\ No newline at end of file
diff --git a/packages/graphql/package.json b/packages/graphql/package.json
index 8c06f2a639f4..b6f5dc284852 100644
--- a/packages/graphql/package.json
+++ b/packages/graphql/package.json
@@ -17,11 +17,13 @@
"dependencies": {
"@graphql-tools/delegate": "8.2.1",
"@graphql-tools/wrap": "8.1.1",
+ "@urql/core": "2.4.4",
"dedent": "^0.7.0",
"express": "4.17.1",
"express-graphql": "^0.12.0",
"getenv": "1.0.0",
"graphql": "^15.5.1",
+ "graphql-resolve-batch": "1.0.3",
"graphql-scalars": "^1.10.0",
"graphql-ws": "^5.5.5",
"nexus": "^1.2.0-next.15",
@@ -33,6 +35,7 @@
"@packages/root": "0.0.0-development",
"@packages/types": "0.0.0-development",
"@types/dedent": "^0.7.0",
+ "@types/graphql-resolve-batch": "1.1.6",
"@types/micromatch": "4.0.2",
"@types/server-destroy": "^1.0.1",
"chai": "^4.2.0",
diff --git a/packages/graphql/schemas/cloud.graphql b/packages/graphql/schemas/cloud.graphql
index 768ceceb5aec..0fe0a57f4dfb 100644
--- a/packages/graphql/schemas/cloud.graphql
+++ b/packages/graphql/schemas/cloud.graphql
@@ -1,6 +1,21 @@
### This file was generated by Nexus Schema
### Do not make changes to this file directly
+"""
+Represents a pollable status for clients to know when refetching data is required.
+"""
+type CloudLatestRunUpdateSpecData {
+ """
+ DateTime of the latest update in a project.
+ """
+ mostRecentUpdate: DateTime
+
+ """
+ Recommended seconds to wait before next poll.
+ """
+ pollingInterval: Int
+}
+
"""
A CloudOrganization represents an Organization stored in the Cypress Cloud
"""
@@ -186,6 +201,85 @@ union CloudProjectResult =
| CloudProjectNotFound
| CloudProjectUnauthorized
+type CloudProjectSpec implements Node {
+ """
+ Average duration the spec takes to run
+ """
+ averageDuration(
+ """
+ The branch to measure average duration against. This will fallback to the closest branch with data.
+ """
+ fromBranch: String!
+ ): Float
+
+ """
+ Globally unique identifier representing a concrete GraphQL ObjectType
+ """
+ id: ID!
+ isConsideredFlaky(
+ """
+ The branch to measure flakiness against
+ """
+ fromBranch: String!
+ ): Boolean
+
+ """
+ Current DateTime on the server. Used in connection with CloudLatestRunUpdateSpecData.
+ """
+ retrievedAt: DateTime
+
+ """
+ Shortened spec path
+ """
+ specPath: String
+
+ """
+ Runs this spec has been involved with.
+ """
+ specRuns(
+ """
+ Returns the elements in the list that come after the specified cursor
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor
+ """
+ before: String
+
+ """
+ Returns the first n elements from the list.
+ """
+ first: Int
+
+ """
+ The branch to filter on for the specs. This will fallback to the closest branch with data.
+ """
+ fromBranch: String!
+
+ """
+ Returns the last n elements from the list.
+ """
+ last: Int
+ ): CloudSpecRunConnection
+}
+
+"""
+Unable to find cloud spec in project
+"""
+type CloudProjectSpecNotFound {
+ """
+ an error message
+ """
+ message: String!
+ retrievedAt: DateTime
+}
+
+union CloudProjectSpecResult =
+ CloudProjectSpec
+ | CloudProjectSpecNotFound
+ | CloudProjectUnauthorized
+
"""
Unauthorized access
"""
@@ -221,12 +315,14 @@ A Recorded run of the Test Runner, typically to the cloud
"""
type CloudRun implements Node {
commitInfo: CloudRunCommitInfo
+ completedAt: DateTime
createdAt: DateTime
"""
Globally unique identifier representing a concrete GraphQL ObjectType
"""
id: ID!
+ runNumber: Int
status: CloudRunStatus
tags: [CloudRunTag]
@@ -344,6 +440,114 @@ type CloudRunTag implements Node {
name: String
}
+"""
+A Recorded run of a given spec from the Test Runner, typically to the cloud
+"""
+type CloudSpecRun implements Node {
+ """
+ When the run was completed
+ """
+ completedAt: DateTime
+
+ """
+ When the run was created
+ """
+ createdAt: DateTime
+
+ """
+ Amount of groups this spec was run in
+ """
+ groupCount: Int
+
+ """
+ Globally unique identifier representing a concrete GraphQL ObjectType
+ """
+ id: ID!
+
+ """
+ Incremental run number assigned
+ """
+ runNumber: Int
+
+ """
+ Aggregate information about how long the spec took to run in the groups
+ """
+ specDuration: SpecDataAggregate
+
+ """
+ Most important status for the spec shared between all groups
+ """
+ status: CloudSpecStatus
+
+ """
+ Aggregate information about how many tests failed in the groups
+ """
+ testsFailed: SpecDataAggregate
+
+ """
+ Aggregate information about how many tests passed in the groups
+ """
+ testsPassed: SpecDataAggregate
+
+ """
+ Aggregate information about how many tests are pending in the groups
+ """
+ testsPending: SpecDataAggregate
+
+ """
+ Aggregate information about how many tests were skipped in the groups
+ """
+ testsSkipped: SpecDataAggregate
+
+ """
+ A link to the run overview page filtered by spec
+ """
+ url: String
+}
+
+type CloudSpecRunConnection {
+ """
+ https://facebook.github.io/relay/graphql/connections.htm#sec-Edge-Types
+ """
+ edges: [CloudSpecRunEdge!]!
+
+ """
+ Flattened list of CloudSpecRun type
+ """
+ nodes: [CloudSpecRun!]!
+
+ """
+ https://facebook.github.io/relay/graphql/connections.htm#sec-undefined.PageInfo
+ """
+ pageInfo: PageInfo!
+}
+
+type CloudSpecRunEdge {
+ """
+ https://facebook.github.io/relay/graphql/connections.htm#sec-Cursor
+ """
+ cursor: String!
+
+ """
+ https://facebook.github.io/relay/graphql/connections.htm#sec-Node
+ """
+ node: CloudSpecRun!
+}
+
+"""
+Possible check status of the spec within a run
+"""
+enum CloudSpecStatus {
+ CANCELLED
+ ERRORED
+ FAILED
+ NOTESTS
+ PASSED
+ RUNNING
+ TIMEDOUT
+ UNCLAIMED
+}
+
"""
A CloudUser represents an User stored in the Cypress Cloud
"""
@@ -473,6 +677,26 @@ type PageInfo {
}
type Query {
+ """
+ Polling query to determine when to refetch spec data. A null value here means no data available in the cloud.
+ """
+ cloudLatestRunUpdateSpecData(
+ """
+ Clients active branch to search for builds. This will fallback to the closest branch with data.
+ """
+ commitBranch: String!
+
+ """
+ A list of Project slugs
+ """
+ projectSlug: String!
+
+ """
+ Datetime since the fetched data
+ """
+ sinceDateTime: DateTime
+ ): CloudLatestRunUpdateSpecData
+
"""
Returns an object conforming to the Relay spec
"""
@@ -508,8 +732,38 @@ type Query {
slugs: [String!]!
): [CloudProjectResult]
+ """
+ Gets a set of specs on a given project and branch
+ """
+ cloudSpecByPath(
+ """
+ Slug of the project to which the set of specs belong
+ """
+ projectSlug: String!
+
+ """
+ The spec path to find
+ """
+ specPath: String!
+ ): CloudProjectSpecResult
+
"""
A user within the Cypress Cloud
"""
cloudViewer: CloudUser
}
+
+"""
+Aggregate data from multiple groups for a spec run
+"""
+type SpecDataAggregate {
+ """
+ Maximum value in the groups
+ """
+ max: Int
+
+ """
+ Minimum value in the groups
+ """
+ min: Int
+}
diff --git a/packages/graphql/schemas/schema.graphql b/packages/graphql/schemas/schema.graphql
index 83fffe561297..5b511d93133a 100644
--- a/packages/graphql/schemas/schema.graphql
+++ b/packages/graphql/schemas/schema.graphql
@@ -65,6 +65,17 @@ type CachedUser implements Node {
id: ID!
}
+"""
+Represents a pollable status for clients to know when refetching data is required.
+"""
+type CloudLatestRunUpdateSpecData {
+ """DateTime of the latest update in a project."""
+ mostRecentUpdate: DateTime
+
+ """Recommended seconds to wait before next poll."""
+ pollingInterval: Int
+}
+
"""
A CloudOrganization represents an Organization stored in the Cypress Cloud
"""
@@ -189,6 +200,60 @@ type CloudProjectNotFound {
union CloudProjectResult = CloudProject | CloudProjectNotFound | CloudProjectUnauthorized
+type CloudProjectSpec implements Node {
+ """Average duration the spec takes to run"""
+ averageDuration(
+ """
+ The branch to measure average duration against. This will fallback to the closest branch with data.
+ """
+ fromBranch: String!
+ ): Float
+
+ """Globally unique identifier representing a concrete GraphQL ObjectType"""
+ id: ID!
+ isConsideredFlaky(
+ """The branch to measure flakiness against"""
+ fromBranch: String!
+ ): Boolean
+
+ """
+ Current DateTime on the server. Used in connection with CloudLatestRunUpdateSpecData.
+ """
+ retrievedAt: DateTime
+
+ """Shortened spec path"""
+ specPath: String
+
+ """Runs this spec has been involved with."""
+ specRuns(
+ """Returns the elements in the list that come after the specified cursor"""
+ after: String
+
+ """Returns the elements in the list that come before the specified cursor"""
+ before: String
+
+ """Returns the first n elements from the list."""
+ first: Int
+
+ """
+ The branch to filter on for the specs. This will fallback to the closest branch with data.
+ """
+ fromBranch: String!
+
+ """Returns the last n elements from the list."""
+ last: Int
+ ): CloudSpecRunConnection
+}
+
+"""Unable to find cloud spec in project"""
+type CloudProjectSpecNotFound {
+ """an error message"""
+ message: String!
+ retrievedAt: DateTime
+}
+
+union CloudProjectSpecResult = CloudProjectSpec | CloudProjectSpecNotFound | CloudProjectUnauthorized
+
"""Unauthorized access"""
type CloudProjectUnauthorized {
"""does the user have a requested access pending"""
@@ -212,10 +277,12 @@ type CloudRecordKey implements Node {
"""A Recorded run of the Test Runner, typically to the cloud"""
type CloudRun implements Node {
commitInfo: CloudRunCommitInfo
+ completedAt: DateTime
createdAt: DateTime
"""Globally unique identifier representing a concrete GraphQL ObjectType"""
id: ID!
+ runNumber: Int
status: CloudRunStatus
tags: [CloudRunTag]
@@ -305,6 +372,84 @@ type CloudRunTag implements Node {
name: String
}
+"""
+A Recorded run of a given spec from the Test Runner, typically to the cloud
+"""
+type CloudSpecRun implements Node {
+ """When the run was completed"""
+ completedAt: DateTime
+
+ """When the run was created"""
+ createdAt: DateTime
+
+ """Amount of groups this spec was run in"""
+ groupCount: Int
+
+ """Globally unique identifier representing a concrete GraphQL ObjectType"""
+ id: ID!
+
+ """Incremental run number assigned"""
+ runNumber: Int
+
+ """
+ Aggregate information about how long the spec took to run in the groups
+ """
+ specDuration: SpecDataAggregate
+
+ """Most important status for the spec shared between all groups"""
+ status: CloudSpecStatus
+
+ """Aggregate information about how many tests failed in the groups"""
+ testsFailed: SpecDataAggregate
+
+ """Aggregate information about how many tests passed in the groups"""
+ testsPassed: SpecDataAggregate
+
+ """Aggregate information about how many tests are pending in the groups"""
+ testsPending: SpecDataAggregate
+
+ """Aggregate information about how many tests were skipped in the groups"""
+ testsSkipped: SpecDataAggregate
+
+ """A link to the run overview page filtered by spec"""
+ url: String
+}
+
+type CloudSpecRunConnection {
+ """
+ https://facebook.github.io/relay/graphql/connections.htm#sec-Edge-Types
+ """
+ edges: [CloudSpecRunEdge!]!
+
+ """Flattened list of CloudSpecRun type"""
+ nodes: [CloudSpecRun!]!
+
+ """
+ https://facebook.github.io/relay/graphql/connections.htm#sec-undefined.PageInfo
+ """
+ pageInfo: PageInfo!
+}
+
+type CloudSpecRunEdge {
+ """https://facebook.github.io/relay/graphql/connections.htm#sec-Cursor"""
+ cursor: String!
+
+ """https://facebook.github.io/relay/graphql/connections.htm#sec-Node"""
+ node: CloudSpecRun!
+}
+
+"""Possible check status of the spec within a run"""
+enum CloudSpecStatus {
+ CANCELLED
+ ERRORED
+ FAILED
+ NOTESTS
+ PASSED
+ RUNNING
+ TIMEDOUT
+ UNCLAIMED
+}
+
"""A CloudUser represents an User stored in the Cypress Cloud"""
type CloudUser implements Node {
"""Url to manage cloud organizations for this user"""
@@ -387,6 +532,15 @@ type CurrentProject implements Node & ProjectLike {
"""The remote associated project from Cypress Dashboard"""
cloudProject: CloudProjectResult
+ """
+ A refetchable remote field implementation to fetch the cloudProject,
+ this can safely be used when rendering a list of projects
+ """
+ cloudProjectRemote(
+ """A globally unique name for this field"""
+ name: String!
+ ): RemoteFetchableCloudProjectResult
+
"""List of all code generation candidates stories"""
codeGenCandidates(glob: String!): [FileParts]
@@ -773,6 +927,15 @@ enum GitInfoStatusType {
"""A project which exists on the filesystem but has not been opened"""
type GlobalProject implements Node & ProjectLike {
+ """
+ A refetchable remote field implementation to fetch the cloudProject,
+ this can safely be used when rendering a list of projects
+ """
+ cloudProjectRemote(
+ """A globally unique name for this field"""
+ name: String!
+ ): RemoteFetchableCloudProjectResult
+
"""Relay style Node ID field for the GlobalProject field"""
id: ID!
@@ -960,6 +1123,9 @@ type Mutation {
"""Used internally to update the URQL cache in the CloudDataSource"""
_cloudCacheInvalidate(args: JSON): Boolean
+ """Internal use only, clears the cloud cache"""
+ _showUrqlCache: JSON
+
"""Add project to projects array and cache it"""
addProject(
"""Whether to open the project when added"""
@@ -1013,8 +1179,14 @@ type Mutation {
id: ID!
): CurrentProject
+ """Fetches the remote data for a RemoteFetchable ID"""
+ loadRemoteFetchables(
+ """The identifier for the RemoteFetchable we are loading"""
+ ids: [ID!]!
+ ): [RemoteFetchable]!
+
"""Auth with Cypress Dashboard"""
- login: Query
+ login(utmMedium: String!, utmSource: String!): Query
"""Log out of Cypress Dashboard"""
logout: Query
@@ -1164,6 +1336,15 @@ enum PluginsState {
"""Common base fields inherited by GlobalProject / CurrentProject"""
interface ProjectLike {
+ """
+ A refetchable remote field implementation to fetch the cloudProject,
+ this can safely be used when rendering a list of projects
+ """
+ cloudProjectRemote(
+ """A globally unique name for this field"""
+ name: String!
+ ): RemoteFetchableCloudProjectResult
+
"""Used to associate project with Cypress dashboard"""
projectId: String
@@ -1179,9 +1360,19 @@ type ProjectPreferences {
}
type PushFragmentPayload {
+ """Raw data associated with the fragment to be written into the cache"""
data: JSON
+
+ """Any errors encountered when executing the operation"""
+ errors: JSON
fragment: JSON!
+
+ """If present, indicates we need to invalidate the client-side cache"""
+ invalidateCache: Boolean
target: String!
+
+ """Variables associated with the fragment"""
+ variables: JSON
}
"""The root "Query" type containing all entry fields for our querying"""
@@ -1191,6 +1382,22 @@ type Query {
baseError: ErrorWrapper
cachedUser: CachedUser
+ """
+ Polling query to determine when to refetch spec data. A null value here means no data available in the cloud.
+ """
+ cloudLatestRunUpdateSpecData(
+ """
+ Clients active branch to search for builds. This will fallback to the closest branch with data.
+ """
+ commitBranch: String!
+
+ """A list of Project slugs"""
+ projectSlug: String!
+
+ """Datetime since the fetched data"""
+ sinceDateTime: DateTime
+ ): CloudLatestRunUpdateSpecData
+
"""Returns an object conforming to the Relay spec"""
cloudNode(
"""An ID for a Node conforming to the Relay spec"""
@@ -1212,6 +1419,15 @@ type Query {
slugs: [String!]!
): [CloudProjectResult]
+ """Gets a set of specs on a given project and branch"""
+ cloudSpecByPath(
+ """Slug of the project to which the set of specs belong"""
+ projectSlug: String!
+
+ """The spec path to find"""
+ specPath: String!
+ ): CloudProjectSpecResult
+
"""A user within the Cypress Cloud"""
cloudViewer: CloudUser
@@ -1255,6 +1471,110 @@ type Query {
wizard: Wizard!
}
+"""
+Represents a container for a piece of remote data stitched into the graph
+"""
+interface RemoteFetchable implements Node {
+ """The raw data response when resolving the data"""
+ dataRaw: JSON
+
+ """JSON representation of the error response"""
+ error: JSON
+
+ """The current fetching status of the fetchable data"""
+ fetchingStatus: RemoteFetchableStatus!
+
+ """Globally unique identifier representing a concrete GraphQL ObjectType"""
+ id: ID!
+
+ """Prints the full operation sent for this query, for debugging purposes"""
+ operation: String!
+
+ """The hash of the operation, for debugging purposes"""
+ operationHash: String!
+
+ """The variables passed to the operation, for debugging purposes"""
+ operationVariables: JSON!
+}
+
+"""
+Wrapper for the resolution remote RemoteFetchableCloudProjectResult data
+"""
+type RemoteFetchableCloudProjectResult implements Node & RemoteFetchable {
+ """Data resolved for the RemoteFetchableCloudProjectResult from the cloud"""
+ data: CloudProjectResult
+
+ """The raw data response when resolving the data"""
+ dataRaw: JSON
+
+ """JSON representation of the error response"""
+ error: JSON
+
+ """The current fetching status of the fetchable data"""
+ fetchingStatus: RemoteFetchableStatus!
+
+ """
+ This ID is generated based on hashes of the queried data, and should be passed to the loadRemoteFetchables mutation to initiate loading the remote data
+ """
+ id: ID!
+
+ """Prints the full operation sent for this query, for debugging purposes"""
+ operation: String!
+
+ """The hash of the operation, for debugging purposes"""
+ operationHash: String!
+
+ """The variables passed to the operation, for debugging purposes"""
+ operationVariables: JSON!
+}
+
+"""
+Wrapper for the resolution remote RemoteFetchableCloudProjectSpecResult data
+"""
+type RemoteFetchableCloudProjectSpecResult implements Node & RemoteFetchable {
+ """
+ Data resolved for the RemoteFetchableCloudProjectSpecResult from the cloud
+ """
+ data: CloudProjectSpecResult
+
+ """The raw data response when resolving the data"""
+ dataRaw: JSON
+
+ """JSON representation of the error response"""
+ error: JSON
+
+ """The current fetching status of the fetchable data"""
+ fetchingStatus: RemoteFetchableStatus!
+
+ """
+ This ID is generated based on hashes of the queried data, and should be passed to the loadRemoteFetchables mutation to initiate loading the remote data
+ """
+ id: ID!
+
+ """Prints the full operation sent for this query, for debugging purposes"""
+ operation: String!
+
+ """The hash of the operation, for debugging purposes"""
+ operationHash: String!
+
+ """The variables passed to the operation, for debugging purposes"""
+ operationVariables: JSON!
+}
+
+enum RemoteFetchableStatus {
+ """Errored while fetching"""
+ ERRORED
+
+ """We have loaded the remote data"""
+ FETCHED
+
+ """Currently fetching"""
+ FETCHING
+
+ """Has not been fetched yet"""
+ NOT_FETCHED
+}
+
"""A file that we just added to the filesystem during project setup"""
type ScaffoldedFile {
"""Info about the file we just scaffolded"""
@@ -1277,6 +1597,12 @@ type Spec implements Node {
"""Full name of spec file (e.g. MySpec.test.tsx)"""
baseName: String!
+ """Wrapper for resolving remote data associated with this field"""
+ cloudSpec(
+ """A globally unique name for this field"""
+ name: String!
+ ): RemoteFetchableCloudProjectSpecResult
+
"""The file extension (e.g. tsx, jsx)"""
fileExtension: String!
@@ -1304,6 +1630,15 @@ type Spec implements Node {
specType: SpecType!
}
+"""Aggregate data from multiple groups for a spec run"""
+type SpecDataAggregate {
+ """Maximum value in the groups"""
+ max: Int
+
+ """Minimum value in the groups"""
+ min: Int
+}
+
enum SpecType {
component
integration
@@ -1341,10 +1676,15 @@ type Subscription {
"""
When we have resolved a section of a query, and want to update the local normalized cache, we "push" the fragment to the frontend to merge in the client side cache
"""
- pushFragment: [PushFragmentPayload]
+ pushFragment: [PushFragmentPayload!]!
"""Issued when the watched specs for the project changes"""
specsChange: CurrentProject
+
+ """
+ Initiates the polling mechanism with the Cypress Cloud to check if we should refetch specs, and mark specs as stale if we have updates
+ """
+ startPollingForSpecs(branchName: String, projectId: String): String
}
enum SupportStatusEnum {
diff --git a/packages/graphql/src/makeGraphQLServer.ts b/packages/graphql/src/makeGraphQLServer.ts
index df08478be832..84159139e3f8 100644
--- a/packages/graphql/src/makeGraphQLServer.ts
+++ b/packages/graphql/src/makeGraphQLServer.ts
@@ -151,6 +151,8 @@ export async function handleGraphQLSocketRequest (uid: string, payload: string,
const operation = JSON.parse(payload) as GraphQLSocketPayload
const context = getCtx()
const document = parse(operation.query)
+
+ DataContext.addActiveRequest()
const result = await execute({
operationName: operation.operationName,
variableValues: operation.variables,
@@ -167,6 +169,8 @@ export async function handleGraphQLSocketRequest (uid: string, payload: string,
callback(result)
} catch (e) {
callback({ data: null, errors: [e] })
+ } finally {
+ DataContext.finishActiveRequest()
}
}
@@ -230,10 +234,14 @@ export const graphQLHTTP = graphqlHTTP((req, res, params) => {
const date = new Date()
const prefix = `${args.operationName ?? '(anonymous)'}`
+ DataContext.addActiveRequest()
+
return Promise.resolve(execute(args)).then((val) => {
debug(`${prefix} completed in ${new Date().valueOf() - date.valueOf()}ms with ${val.errors?.length ?? 0} errors`)
return val
+ }).finally(() => {
+ DataContext.finishActiveRequest()
})
},
}
diff --git a/packages/graphql/src/plugins/index.ts b/packages/graphql/src/plugins/index.ts
index 6141bfbda258..ef71125558bd 100644
--- a/packages/graphql/src/plugins/index.ts
+++ b/packages/graphql/src/plugins/index.ts
@@ -5,4 +5,5 @@ export * from './nexusDebugFieldPlugin'
export * from './nexusDeferIfNotLoadedPlugin'
export * from './nexusMutationErrorPlugin'
export * from './nexusNodePlugin'
+export * from './nexusRemoteFieldPlugin'
export * from './nexusSlowGuardPlugin'
diff --git a/packages/graphql/src/plugins/nexusRemoteFieldPlugin.ts b/packages/graphql/src/plugins/nexusRemoteFieldPlugin.ts
new file mode 100644
index 000000000000..494d382b435b
--- /dev/null
+++ b/packages/graphql/src/plugins/nexusRemoteFieldPlugin.ts
@@ -0,0 +1,137 @@
+import dedent from 'dedent'
+import type { DocumentNode, GraphQLResolveInfo } from 'graphql'
+import { dynamicOutputMethod, plugin, core, objectType, mutationField, idArg, list, nonNull, stringArg } from 'nexus'
+import { createBatchResolver } from 'graphql-resolve-batch'
+
+import type { NexusGenAbstractTypeMembers } from '../gen/nxs.gen'
+import { RemoteFetchable } from '../schemaTypes'
+import type { DataContext } from '@packages/data-context'
+import type { CloudRemoteTargets, CloudQueryArgs, CloudQueryFields } from '../utils/graphqlTypeUtils'
+
+export type RemoteFieldDefinitionConfig = {
+ /**
+ * The type we expect to resolve as the "data"
+ */
+ type: CloudRemoteTargets
+ /**
+ * Args to make available to the field definition
+ */
+ args?: core.ArgsRecord
+ /**
+ * Optional description for the field
+ */
+ description?: string
+ /**
+ * Whether we should "eager-fetch" the data for the field when the field is first resolved.
+ * Either a boolean (true), or called with the fetch
+ * @default false
+ */
+ shouldEagerFetch?: boolean | ((
+ source: core.RootValueField,
+ args: core.ArgsValue,
+ ctx: DataContext,
+ info: GraphQLResolveInfo,
+ index: number // Index, when resolving in a list. Useful to eager load the first "N" items
+ ) => boolean)
+ /**
+ * The remote "query field" to delegate the query to
+ */
+ remoteQueryField: RemoteField
+ /**
+ * Given the "fieldNodes" for the type we're resolving, any arguments, and the remoteQueryField,
+ * allows us to
+ */
+ makeQueryDocument?: () => DocumentNode
+} & AdditionalRemoteFieldProps
+
+// If not every member of CloudQueryArgs is provided, then we will not issue the request
+export type AdditionalRemoteFieldProps = RemoteField extends never ? {
+ queryArgs?: RemoteQueryArgsResolver
+} : {
+ queryArgs: RemoteQueryArgsResolver
+}
+
+export type RemoteQueryArgsResolver = (
+ source: core.SourceValue,
+ args: core.ArgsValue,
+ ctx: DataContext,
+ info: GraphQLResolveInfo
+) => core.MaybePromise | false>
+
+export const remoteFieldPlugin = plugin({
+ name: 'remoteFieldPlugin',
+ description: 'Adds a container for an independently fetchable remote-resolved field',
+ fieldDefTypes: [
+ core.printedGenTypingImport({
+ module: '@packages/graphql/src/plugins/nexusRemoteFieldPlugin',
+ bindings: ['RemoteFieldDefinitionConfig'],
+ }),
+ core.printedGenTypingImport({
+ module: '@packages/graphql/src/gen/cloud-source-types.gen',
+ bindings: [['Query', 'CloudQuery']],
+ }),
+ ],
+ onInstall (b) {
+ b.addType(mutationField('loadRemoteFetchables', {
+ description: 'Fetches the remote data for a RemoteFetchable ID',
+ type: nonNull(list('RemoteFetchable')),
+ args: {
+ ids: nonNull(list(nonNull(idArg({
+ description: 'The identifier for the RemoteFetchable we are loading',
+ })))),
+ },
+ resolve: (source, args, ctx, info) => {
+ // Each ID encodes all of the information necessary to resolve a remote fetchable,
+ // we just need to unpack them and execute
+ return args.ids.map((id) => ctx.remoteRequest.loadRemoteFetchable(id, ctx))
+ },
+ }))
+
+ b.addType(dynamicOutputMethod({
+ name: 'remoteField',
+ typeDescription: dedent`
+ Adds a field which is resolved with data from from the Cloud API.
+ The "id" is refetchable via the loadRemoteFetchables APIs
+ `,
+ typeDefinition: dedent`
+ >(fieldName: FieldName, config: RemoteFieldDefinitionConfig): void
+ `,
+ factory ({ typeName: parentTypeName, typeDef: t, args: factoryArgs, stage, builder, wrapping }) {
+ const [fieldName, fieldConfig] = factoryArgs as [string, RemoteFieldDefinitionConfig]
+ const fieldType = `RemoteFetchable${fieldConfig.type}` as NexusGenAbstractTypeMembers['RemoteFetchable']
+
+ if (!builder.hasType(fieldType)) {
+ builder.addType(objectType({
+ name: fieldType,
+ description: `Wrapper for the resolution remote ${fieldType} data`,
+ definition (t) {
+ t.implements(RemoteFetchable)
+ t.nonNull.id('id', {
+ description: 'This ID is generated based on hashes of the queried data, and should be passed to the loadRemoteFetchables mutation to initiate loading the remote data',
+ resolve: (source, args, ctx) => ctx.remoteRequest.makeRefetchableId(fieldType, source.operationHash, source.operationVariables),
+ })
+
+ t.field('data', {
+ description: `Data resolved for the ${fieldType} from the cloud`,
+ type: fieldConfig.type,
+ })
+ },
+ }))
+ }
+
+ t.field(fieldName, {
+ type: fieldType as any,
+ description: fieldConfig.description ?? 'Wrapper for resolving remote data associated with this field',
+ args: {
+ ...fieldConfig.args ?? {},
+ name: nonNull(stringArg({ description: 'A globally unique name for this field' })),
+ },
+ // Wrap with a batch resolver, so we aren't doing the same info parsing for each row
+ resolve: createBatchResolver((sources, args, ctx, info) => {
+ return ctx.remoteRequest.batchResolveRemoteFields(fieldConfig, sources, args, ctx, info)
+ }),
+ })
+ },
+ }))
+ },
+})
diff --git a/packages/graphql/src/plugins/nexusSlowGuardPlugin.ts b/packages/graphql/src/plugins/nexusSlowGuardPlugin.ts
index a4552901e9b7..d87cf7cc8765 100644
--- a/packages/graphql/src/plugins/nexusSlowGuardPlugin.ts
+++ b/packages/graphql/src/plugins/nexusSlowGuardPlugin.ts
@@ -2,7 +2,7 @@ import { plugin } from 'nexus'
import { isPromiseLike, pathToArray } from 'nexus/dist/utils'
import chalk from 'chalk'
-const HANGING_RESOLVER_THRESHOLD = 15
+const HANGING_RESOLVER_THRESHOLD = 100
export const nexusSlowGuardPlugin = plugin({
name: 'NexusSlowGuard',
diff --git a/packages/graphql/src/schema.ts b/packages/graphql/src/schema.ts
index 307810e94b96..12b93763116a 100644
--- a/packages/graphql/src/schema.ts
+++ b/packages/graphql/src/schema.ts
@@ -4,7 +4,7 @@ import { makeSchema, connectionPlugin } from 'nexus'
import * as schemaTypes from './schemaTypes/'
import { nodePlugin } from './plugins/nexusNodePlugin'
import { remoteSchemaWrapped } from './stitching/remoteSchemaWrapped'
-import { mutationErrorPlugin, nexusDebugLogPlugin, nexusSlowGuardPlugin, nexusDeferIfNotLoadedPlugin, nexusDeferResolveGuard } from './plugins'
+import { mutationErrorPlugin, nexusDebugLogPlugin, nexusSlowGuardPlugin, nexusDeferIfNotLoadedPlugin, nexusDeferResolveGuard, remoteFieldPlugin } from './plugins'
const isCodegen = Boolean(process.env.CYPRESS_INTERNAL_NEXUS_CODEGEN)
@@ -30,17 +30,21 @@ export const graphqlSchema = makeSchema({
},
},
plugins: [
- nexusDeferResolveGuard,
- nexusSlowGuardPlugin,
- nexusDeferIfNotLoadedPlugin,
- nexusDebugLogPlugin,
- mutationErrorPlugin,
+ // Structural Plugins
connectionPlugin({
nonNullDefaults: {
output: true,
},
}),
nodePlugin,
+ remoteFieldPlugin,
+
+ // Runtime Resolver Plugins
+ nexusDeferResolveGuard,
+ nexusSlowGuardPlugin,
+ nexusDeferIfNotLoadedPlugin,
+ nexusDebugLogPlugin,
+ mutationErrorPlugin,
],
formatTypegen (content, type) {
if (type === 'schema') {
diff --git a/packages/graphql/src/schemaTypes/interfaceTypes/gql-Node.ts b/packages/graphql/src/schemaTypes/interfaceTypes/gql-Node.ts
new file mode 100644
index 000000000000..687a19d1761c
--- /dev/null
+++ b/packages/graphql/src/schemaTypes/interfaceTypes/gql-Node.ts
@@ -0,0 +1,22 @@
+import { interfaceType } from 'nexus'
+import assert from 'assert'
+
+export const Node = interfaceType({
+ name: 'Node',
+ description: 'Implements the Relay Node spec',
+ definition (t) {
+ t.nonNull.id('id', {
+ description: 'Globally unique identifier representing a concrete GraphQL ObjectType',
+ resolve: (source) => {
+ throw new Error('Abstract resolve, should be handled separately')
+ },
+ })
+ },
+ resolveType: (t: any) => {
+ if (!t.__typename) {
+ assert(t.__typename, `Cannot resolve Node without __typename: saw ${String(t)}`)
+ }
+
+ return t.__typename
+ },
+})
diff --git a/packages/graphql/src/schemaTypes/interfaceTypes/gql-ProjectLike.ts b/packages/graphql/src/schemaTypes/interfaceTypes/gql-ProjectLike.ts
index d9194767afc6..9d7f4b0ed050 100644
--- a/packages/graphql/src/schemaTypes/interfaceTypes/gql-ProjectLike.ts
+++ b/packages/graphql/src/schemaTypes/interfaceTypes/gql-ProjectLike.ts
@@ -1,10 +1,6 @@
+import dedent from 'dedent'
import { interfaceType } from 'nexus'
-export interface ProjectShape {
- projectId?: string | null
- projectRoot: string
-}
-
export const ProjectLike = interfaceType({
name: 'ProjectLike',
description: 'Common base fields inherited by GlobalProject / CurrentProject',
@@ -15,18 +11,36 @@ export const ProjectLike = interfaceType({
t.string('projectId', {
description: 'Used to associate project with Cypress dashboard',
- resolve: (source, args, ctx) => ctx.project.projectId(),
+ resolve: (source, args, ctx) => ctx.project.maybeGetProjectId(source),
})
t.nonNull.string('title', {
resolve: (source, args, ctx) => ctx.project.projectTitle(source.projectRoot),
})
+
+ t.remoteField('cloudProjectRemote', {
+ type: 'CloudProjectResult',
+ remoteQueryField: 'cloudProjectBySlug',
+ description: dedent`
+ A refetchable remote field implementation to fetch the cloudProject,
+ this can safely be used when rendering a list of projects
+ `,
+ queryArgs: async (source, args, ctx) => {
+ const projectId = await ctx.project.maybeGetProjectId(source)
+
+ if (projectId) {
+ return { slug: projectId }
+ }
+
+ return false
+ },
+ })
},
resolveType (root) {
return 'GlobalProject'
},
sourceType: {
- module: __dirname,
+ module: '@packages/data-context/src/data/coreDataShape',
export: 'ProjectShape',
},
})
diff --git a/packages/graphql/src/schemaTypes/interfaceTypes/gql-RemoteFetchable.ts b/packages/graphql/src/schemaTypes/interfaceTypes/gql-RemoteFetchable.ts
new file mode 100644
index 000000000000..a5ad4d33785b
--- /dev/null
+++ b/packages/graphql/src/schemaTypes/interfaceTypes/gql-RemoteFetchable.ts
@@ -0,0 +1,68 @@
+import { enumType, interfaceType } from 'nexus'
+import type { RemoteFetchableStatus, NexusGenAbstractTypeMembers } from '../../gen/nxs.gen'
+
+export interface RemoteFetchableShape {
+ __typename: NexusGenAbstractTypeMembers['RemoteFetchable']
+ id: string
+ fetchingStatus: RemoteFetchableStatus
+ operation: string
+ operationHash: string
+ operationVariables: any
+ data?: any
+ dataRaw?: any
+ error?: any
+}
+
+const FETCHABLE_MEMBERS = {
+ NOT_FETCHED: 'Has not been fetched yet',
+ FETCHING: 'Currently fetching',
+ ERRORED: 'Errored while fetching',
+ FETCHED: 'We have loaded the remote data',
+}
+
+const RemoteFetchableStatusEnum = enumType({
+ name: 'RemoteFetchableStatus',
+ members: Object.entries(FETCHABLE_MEMBERS).map(([key, val]) => {
+ return {
+ name: key,
+ description: val,
+ }
+ }),
+})
+
+export const RemoteFetchable = interfaceType({
+ name: 'RemoteFetchable',
+ description: 'Represents a container for a piece of remote data stitched into the graph',
+ definition (t) {
+ t.implements('Node')
+ t.nonNull.field('fetchingStatus', {
+ description: 'The current fetching status of the fetchable data',
+ type: RemoteFetchableStatusEnum,
+ })
+
+ t.json('error', {
+ description: 'JSON representation of the error response',
+ })
+
+ t.json('dataRaw', {
+ description: 'The raw data response when resolving the data',
+ })
+
+ t.nonNull.string('operation', {
+ description: 'Prints the full operation sent for this query, for debugging purposes',
+ })
+
+ t.nonNull.string('operationHash', {
+ description: 'The hash of the operation, for debugging purposes',
+ })
+
+ t.nonNull.json('operationVariables', {
+ description: 'The variables passed to the operation, for debugging purposes',
+ })
+ },
+ resolveType: (t) => t.__typename,
+ sourceType: {
+ module: __filename,
+ export: 'RemoteFetchableShape',
+ },
+})
diff --git a/packages/graphql/src/schemaTypes/interfaceTypes/index.ts b/packages/graphql/src/schemaTypes/interfaceTypes/index.ts
index e704b30161ed..d2e7042a3002 100644
--- a/packages/graphql/src/schemaTypes/interfaceTypes/index.ts
+++ b/packages/graphql/src/schemaTypes/interfaceTypes/index.ts
@@ -1,4 +1,6 @@
/* eslint-disable padding-line-between-statements */
// created by autobarrel, do not modify directly
+export * from './gql-Node'
export * from './gql-ProjectLike'
+export * from './gql-RemoteFetchable'
diff --git a/packages/graphql/src/schemaTypes/objectTypes/gql-Mutation.ts b/packages/graphql/src/schemaTypes/objectTypes/gql-Mutation.ts
index f2780cf6c319..0490552a34cb 100644
--- a/packages/graphql/src/schemaTypes/objectTypes/gql-Mutation.ts
+++ b/packages/graphql/src/schemaTypes/objectTypes/gql-Mutation.ts
@@ -259,8 +259,12 @@ export const mutation = mutationType({
t.field('login', {
type: Query,
description: 'Auth with Cypress Dashboard',
+ args: {
+ utmMedium: nonNull(stringArg()),
+ utmSource: nonNull(stringArg()),
+ },
resolve: async (_, args, ctx) => {
- await ctx.actions.auth.login()
+ await ctx.actions.auth.login(args.utmSource, args.utmMedium)
return {}
},
@@ -661,5 +665,14 @@ export const mutation = mutationType({
return true
},
})
+
+ t.json('_showUrqlCache', {
+ description: 'Internal use only, clears the cloud cache',
+ resolve: async (source, args, ctx) => {
+ const { data } = await ctx.cloud.getCache()
+
+ return data
+ },
+ })
},
})
diff --git a/packages/graphql/src/schemaTypes/objectTypes/gql-Spec.ts b/packages/graphql/src/schemaTypes/objectTypes/gql-Spec.ts
index ef83db8923de..ed693c03ff0a 100644
--- a/packages/graphql/src/schemaTypes/objectTypes/gql-Spec.ts
+++ b/packages/graphql/src/schemaTypes/objectTypes/gql-Spec.ts
@@ -47,5 +47,25 @@ export const Spec = objectType({
return ctx.lifecycleManager.git?.gitInfoFor(source.absolute) ?? null
},
})
+
+ t.remoteField('cloudSpec', {
+ type: 'CloudProjectSpecResult',
+ remoteQueryField: 'cloudSpecByPath',
+ shouldEagerFetch: () => false, // defaults to false to be fully lazy and rely on the UI to fetch as needed
+ queryArgs: async (source, args, ctx) => {
+ const projectId = await ctx.project.projectId()
+ const fromBranch = ctx.lifecycleManager.git?.currentBranch
+
+ if (!projectId) {
+ return false
+ }
+
+ return {
+ projectSlug: projectId,
+ specPath: source.relative,
+ fromBranch,
+ }
+ },
+ })
},
})
diff --git a/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts b/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts
index 4e4e52790295..fb21a4855a43 100644
--- a/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts
+++ b/packages/graphql/src/schemaTypes/objectTypes/gql-Subscription.ts
@@ -1,5 +1,5 @@
import type { PushFragmentData } from '@packages/data-context/src/actions'
-import { list, objectType, subscriptionType } from 'nexus'
+import { list, nonNull, objectType, stringArg, subscriptionType } from 'nexus'
import { CurrentProject, DevState, Query } from '.'
import { Spec } from './gql-Spec'
@@ -85,18 +85,44 @@ export const Subscription = subscriptionType({
resolve: (source, args, ctx) => ctx.lifecycleManager,
})
- t.field('pushFragment', {
+ t.nonNull.field('pushFragment', {
description: 'When we have resolved a section of a query, and want to update the local normalized cache, we "push" the fragment to the frontend to merge in the client side cache',
- type: list(objectType({
+ type: list(nonNull(objectType({
name: 'PushFragmentPayload',
definition (t) {
t.nonNull.string('target')
t.nonNull.json('fragment')
- t.json('data')
+ t.json('data', {
+ description: 'Raw data associated with the fragment to be written into the cache',
+ })
+
+ t.json('variables', {
+ description: 'Variables associated with the fragment',
+ })
+
+ t.json('errors', {
+ description: 'Any errors encountered when executing the operation',
+ })
+
+ t.boolean('invalidateCache', {
+ description: 'If present, indicates we need to invalidate the client-side cache',
+ })
},
- })),
+ }))),
subscribe: (source, args, ctx) => ctx.emitter.subscribeTo('pushFragment', { sendInitial: false }),
resolve: (source: PushFragmentData[], args, ctx) => source,
})
+
+ t.string('startPollingForSpecs', {
+ args: {
+ projectId: stringArg(),
+ branchName: stringArg(),
+ },
+ description: 'Initiates the polling mechanism with the Cypress Cloud to check if we should refetch specs, and mark specs as stale if we have updates',
+ subscribe: (source, args, ctx) => {
+ return ctx.remotePolling.subscribeAndPoll(args.branchName, args.projectId)
+ },
+ resolve: (o: string | null) => o,
+ })
},
})
diff --git a/packages/graphql/src/stitching/remoteSchemaWrapped.ts b/packages/graphql/src/stitching/remoteSchemaWrapped.ts
index 797f8a92d4fc..982da8927487 100644
--- a/packages/graphql/src/stitching/remoteSchemaWrapped.ts
+++ b/packages/graphql/src/stitching/remoteSchemaWrapped.ts
@@ -4,7 +4,7 @@ import type { DataContext } from '@packages/data-context'
import type { RequestPolicy } from '@urql/core'
import assert from 'assert'
import debugLib from 'debug'
-import { BREAK, OperationDefinitionNode, visit } from 'graphql'
+import { BREAK, OperationDefinitionNode, print, visit } from 'graphql'
import { remoteSchema } from './remoteSchema'
const debug = debugLib('cypress:graphql:remoteSchemaWrapped')
@@ -44,29 +44,35 @@ export const remoteSchemaWrapped = wrapSchema({
debug('executing: %j', { rootValue: obj.rootValue, operationName, requestPolicy })
- return obj.context.cloud.executeRemoteGraphQL({
+ const operationDoc = visit(obj.document, {
+ OperationDefinition (node) {
+ if (!node.name) {
+ return {
+ ...node, name: { kind: 'Name', value: operationName },
+ } as OperationDefinitionNode
+ }
+
+ return BREAK
+ },
+ })
+
+ const context = obj.context
+
+ return context.cloud.executeRemoteGraphQL({
+ fieldName: info.fieldName,
requestPolicy,
operationType: obj.operationType ?? 'query',
- document: visit(obj.document, {
- OperationDefinition (node) {
- if (!node.name) {
- return {
- ...node, name: { kind: 'Name', value: operationName },
- } as OperationDefinitionNode
- }
-
- return BREAK
- },
- }),
- variables: obj.variables,
+ operation: print(operationDoc),
+ operationDoc,
+ operationVariables: obj.variables,
// When we respond eagerly with a result, but receive an updated value
// for the query, we can "push" the data down using the pushFragment subscription
onUpdatedResult (result) {
- obj.context?.graphql.pushResult({
+ context.graphql.pushResult({
result: result?.[info.fieldName] ?? null,
source: obj.rootValue,
info,
- ctx: obj.context,
+ ctx: context,
})
},
}) as any
diff --git a/packages/graphql/src/utils/graphqlTypeUtils.ts b/packages/graphql/src/utils/graphqlTypeUtils.ts
new file mode 100644
index 000000000000..7f5d0fab532d
--- /dev/null
+++ b/packages/graphql/src/utils/graphqlTypeUtils.ts
@@ -0,0 +1,14 @@
+import type { QueryResolvers as CloudQueryResolvers, Resolver } from '../gen/cloud-source-types.gen'
+import type { NexusGenInterfaceNames, NexusGenObjectNames, NexusGenUnionNames } from '../gen/nxs.gen'
+
+export type CloudRemoteTargets = {
+ [K in NexusGenObjectNames | NexusGenUnionNames | NexusGenInterfaceNames]:
+ K extends `Cloud${infer U}` ? K extends `${infer _}${'Edge'}` ? never : K : never
+}[NexusGenObjectNames | NexusGenUnionNames | NexusGenInterfaceNames]
+
+export type CloudQueryFields = keyof CloudQueryResolvers
+
+export type CloudQueryArgs =
+ Exclude extends Resolver
+ ? keyof Args extends never ? never : Args
+ : never
diff --git a/packages/graphql/src/utils/index.ts b/packages/graphql/src/utils/index.ts
new file mode 100644
index 000000000000..bc5e2c071e78
--- /dev/null
+++ b/packages/graphql/src/utils/index.ts
@@ -0,0 +1,4 @@
+/* eslint-disable padding-line-between-statements */
+// created by autobarrel, do not modify directly
+
+export * from './graphqlTypeUtils'
diff --git a/packages/graphql/test/stubCloudTypes.ts b/packages/graphql/test/stubCloudTypes.ts
index 5300b14e8ce1..8cb907c90c53 100644
--- a/packages/graphql/test/stubCloudTypes.ts
+++ b/packages/graphql/test/stubCloudTypes.ts
@@ -168,6 +168,7 @@ export function createCloudRun (config: Partial): Required {
const cloudRunData: Required = {
...testNodeId('CloudRun'),
status: 'PASSED',
+ runNumber: 432,
totalFailed: 0,
totalSkipped: 0,
totalPending: 0,
@@ -179,6 +180,7 @@ export function createCloudRun (config: Partial): Required {
tags: [],
url: 'http://dummy.cypress.io/runs/1',
createdAt: new Date(Date.now() - 1000 * 60 * 61).toISOString(),
+ completedAt: null,
commitInfo: createCloudRunCommitInfo({
sha: `fake-sha-${getNodeIdx('CloudRun')}`,
summary: `fix: make gql work ${config.status ?? 'PASSED'}`,
diff --git a/packages/launchpad/README.md b/packages/launchpad/README.md
index 73bcb702fe91..957bd33f9dfd 100644
--- a/packages/launchpad/README.md
+++ b/packages/launchpad/README.md
@@ -36,7 +36,7 @@ yarn workspace @packages/launchpad build
## Developing
-For the best development experience, you will want to use VS Code with the [Volar](https://marketplace.visualstudio.com/items?itemName=vue.volar) extension. This will give you type completion inside `vue` files.
+For the best development experience, you will want to use VS Code with the [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) extension. This will give you type completion inside `vue` files.
```bash
diff --git a/packages/launchpad/cypress.config.ts b/packages/launchpad/cypress.config.ts
index b11799991fc5..c52816ef08fa 100644
--- a/packages/launchpad/cypress.config.ts
+++ b/packages/launchpad/cypress.config.ts
@@ -4,9 +4,10 @@ import { snapshotCypressDirectory } from './cypress/tasks/snapshotsScaffold'
import { uninstallDependenciesInScaffoldedProject } from './cypress/tasks/uninstallDependenciesInScaffoldedProject'
const CYPRESS_INTERNAL_CLOUD_ENV = getenv('CYPRESS_INTERNAL_CLOUD_ENV', process.env.CYPRESS_INTERNAL_ENV || 'development')
+const CYPRESS_INTERNAL_DEV_PROJECT_ID = getenv('CYPRESS_INTERNAL_DEV_PROJECT_ID', process.env.CYPRESS_INTERNAL_DEV_PROJECT_ID || 'sehy69')
export default defineConfig({
- projectId: CYPRESS_INTERNAL_CLOUD_ENV === 'staging' ? 'ypt4pf' : 'sehy69',
+ projectId: CYPRESS_INTERNAL_CLOUD_ENV === 'staging' ? 'ypt4pf' : CYPRESS_INTERNAL_DEV_PROJECT_ID,
viewportWidth: 800,
viewportHeight: 850,
retries: {
diff --git a/packages/launchpad/cypress/e2e/global-mode.cy.ts b/packages/launchpad/cypress/e2e/global-mode.cy.ts
index 991bb5219e15..2d0bffd0b0b5 100644
--- a/packages/launchpad/cypress/e2e/global-mode.cy.ts
+++ b/packages/launchpad/cypress/e2e/global-mode.cy.ts
@@ -152,7 +152,8 @@ describe('Launchpad: Global Mode', () => {
it('updates breadcrumb when selecting a project and navigating back', () => {
const getBreadcrumbLink = (name: string, options: { disabled: boolean } = { disabled: false }) => {
- return cy.findByRole('link', { name }).should('have.attr', 'aria-disabled', options.disabled ? 'true' : 'false')
+ // The timeout is increased to account for variability in configuration load times in CI.
+ return cy.findByRole('link', { name, timeout: 10000 }).should('have.attr', 'aria-disabled', options.disabled ? 'true' : 'false')
}
const resetSpies = () => {
diff --git a/packages/launchpad/cypress/e2e/migration.cy.ts b/packages/launchpad/cypress/e2e/migration.cy.ts
index 8734427f4092..300390f796ce 100644
--- a/packages/launchpad/cypress/e2e/migration.cy.ts
+++ b/packages/launchpad/cypress/e2e/migration.cy.ts
@@ -1075,6 +1075,22 @@ describe('Full migration flow for each project', { retries: { openMode: 0, runMo
checkOutcome()
})
+ it('completes journey for migration-e2e-plugins-implicit-index-js', () => {
+ startMigrationFor('migration-e2e-plugins-implicit-index-js')
+ // no specs, nothing to rename?
+ cy.get(renameAutoStep).should('exist')
+ // no CT
+ cy.get(renameManualStep).should('not.exist')
+ cy.get(renameSupportStep).should('exist')
+ cy.get(setupComponentStep).should('not.exist')
+ cy.get(configFileStep).should('exist')
+
+ runAutoRename()
+ renameSupport()
+ migrateAndVerifyConfig()
+ checkOutcome()
+ })
+
it('completes journey for migration-e2e-fully-custom', () => {
startMigrationFor('migration-e2e-fully-custom')
// integration folder and testFiles are custom, cannot rename anything
@@ -1530,8 +1546,8 @@ describe('Migration', { viewportWidth: 1200, retries: { openMode: 0, runMode: 2
})
describe('Migrate custom config files', () => {
- it('completes journey for migration-custom-config-file-root-level', () => {
- startMigrationFor('migration-custom-config-file-root-level', ['--config-file', 'customConfig.json'])
+ it('completes journey for migration-custom-config-file-root-level spaces', () => {
+ startMigrationFor('migration-custom-config-file-root-level spaces', ['--config-file', 'customConfig.json'])
// defaults, rename all the things
// can rename integration->e2e
@@ -1698,7 +1714,8 @@ describe('Migrate custom config files', () => {
it('shows error if plugins file do not exist', () => {
scaffoldAndVisitLaunchpad('migration', ['--config-file', 'erroredConfigFiles/incorrectPluginsFile.json'])
- cy.contains(`${getPathForPlatform('foo/bar')} file threw an error.`)
- cy.contains('Please ensure your pluginsFile is valid and relaunch the migration tool to migrate to Cypress version 10.0.0.')
+ const err = `Looked for pluginsFile at foo/bar, but it was not found.`
+
+ cy.contains(err)
})
})
diff --git a/packages/launchpad/cypress/e2e/open-mode.cy.ts b/packages/launchpad/cypress/e2e/open-mode.cy.ts
index f469ff4ec8c5..565ba42cbc53 100644
--- a/packages/launchpad/cypress/e2e/open-mode.cy.ts
+++ b/packages/launchpad/cypress/e2e/open-mode.cy.ts
@@ -176,7 +176,7 @@ describe('Launchpad: Open Mode', () => {
},
]
- ctx.coreData.app.projects = [{ projectRoot: '/some/project' }]
+ ctx.coreData.app.projects = [{ projectRoot: '/some/project', savedState: () => Promise.resolve({}) }]
})
cy.visitLaunchpad()
@@ -203,7 +203,7 @@ describe('Launchpad: Open Mode', () => {
it('opens using finder', () => {
cy.withCtx(async (ctx, o) => {
- ctx.coreData.app.projects = [{ projectRoot: '/some/project' }]
+ ctx.coreData.app.projects = [{ projectRoot: '/some/project', savedState: () => Promise.resolve({}) }]
})
cy.visitLaunchpad()
@@ -242,4 +242,11 @@ describe('Launchpad: Open Mode', () => {
cy.get('body').should('not.contain.text', 'Your project does not contain a default supportFile.')
cy.get('h1').should('contain', 'Choose a Browser')
})
+
+ it('opens project with spaces in path', () => {
+ cy.scaffoldProject('simple with spaces')
+ cy.openProject('simple with spaces', ['--e2e'])
+ cy.visitLaunchpad()
+ cy.get('h1').should('contain', 'Choose a Browser')
+ })
})
diff --git a/packages/launchpad/package.json b/packages/launchpad/package.json
index c691bcafabee..0fc348cecde4 100644
--- a/packages/launchpad/package.json
+++ b/packages/launchpad/package.json
@@ -69,7 +69,6 @@
"vue-i18n": "9.2.0-beta.7",
"vue-tsc": "^0.3.0",
"vue3-file-selector": "^1.0.1",
- "windicss": "3.1.4",
"windicss-analysis": "^0.3.4",
"wonka": "^4.0.15"
},
diff --git a/packages/launchpad/windi.config.ts b/packages/launchpad/windi.config.ts
index e68499f9350c..37cd764edfe4 100644
--- a/packages/launchpad/windi.config.ts
+++ b/packages/launchpad/windi.config.ts
@@ -1,4 +1,5 @@
-import { defaultConfig } from '@packages/frontend-shared/windi.config'
-import { defineConfig } from 'windicss/helpers'
+/**
+ * This file is used for vscode plugin autocompletion of windi colors
+ */
-export default defineConfig(defaultConfig)
+export { default } from '@packages/frontend-shared/windi.config'
diff --git a/packages/proxy/lib/http/index.ts b/packages/proxy/lib/http/index.ts
index b08442541a76..97b6add166c9 100644
--- a/packages/proxy/lib/http/index.ts
+++ b/packages/proxy/lib/http/index.ts
@@ -19,8 +19,9 @@ import type { Request, Response } from 'express'
import RequestMiddleware from './request-middleware'
import ResponseMiddleware from './response-middleware'
import { DeferredSourceMapCache } from '@packages/rewriter'
-import type { Browser } from '@packages/server/lib/browsers/types'
import type { RemoteStates } from '@packages/server/lib/remote_states'
+import type { CookieJar } from '@packages/server/lib/cookie-jar'
+import type { Automation } from '@packages/server/lib/automation/automation'
function getRandomColorFn () {
return chalk.hex(`#${Number(
@@ -51,11 +52,12 @@ type HttpMiddlewareCtx = {
stage: HttpStages
debug: Debug.Debugger
middleware: HttpMiddlewareStacks
+ getCookieJar: () => CookieJar
deferSourceMapRewrite: (opts: { js: string, url: string }) => string
- getCurrentBrowser: () => Browser | Partial & Pick | null
+ getAutomation: () => Automation
getPreRequest: (cb: GetPreRequestCb) => void
- getPreviousAUTRequestUrl: Http['getPreviousAUTRequestUrl']
- setPreviousAUTRequestUrl: Http['setPreviousAUTRequestUrl']
+ getAUTUrl: Http['getAUTUrl']
+ setAUTUrl: Http['setAUTUrl']
} & T
export const defaultMiddleware = {
@@ -67,8 +69,9 @@ export const defaultMiddleware = {
export type ServerCtx = Readonly<{
config: CyServer.Config & Cypress.Config
shouldCorrelatePreRequests?: () => boolean
- getCurrentBrowser: () => Browser | Partial & Pick | null
+ getAutomation: () => Automation
getFileServerToken: () => string
+ getCookieJar: () => CookieJar
remoteStates: RemoteStates
getRenderedHTMLOrigins: Http['getRenderedHTMLOrigins']
netStubbingState: NetStubbingState
@@ -152,6 +155,10 @@ export function _runStage (type: HttpStages, ctx: any, onError) {
const fullCtx = {
next: () => {
+ fullCtx.next = () => {
+ throw new Error('Error running proxy middleware: Cannot call this.next() more than once in the same middleware function. Doing so can cause unintended issues.')
+ }
+
copyChangedCtx()
_end(runMiddlewareStack())
@@ -206,7 +213,7 @@ export class Http {
config: CyServer.Config
shouldCorrelatePreRequests: () => boolean
deferredSourceMapCache: DeferredSourceMapCache
- getCurrentBrowser: () => Browser | Partial & Pick | null
+ getAutomation: () => Automation
getFileServerToken: () => string
remoteStates: RemoteStates
middleware: HttpMiddlewareStacks
@@ -216,7 +223,8 @@ export class Http {
socket: CyServer.Socket
serverBus: EventEmitter
renderedHTMLOrigins: {[key: string]: boolean} = {}
- previousAUTRequestUrl?: string
+ autUrl?: string
+ getCookieJar: () => CookieJar
constructor (opts: ServerCtx & { middleware?: HttpMiddlewareStacks }) {
this.buffers = new HttpBuffers()
@@ -224,7 +232,7 @@ export class Http {
this.config = opts.config
this.shouldCorrelatePreRequests = opts.shouldCorrelatePreRequests || (() => false)
- this.getCurrentBrowser = opts.getCurrentBrowser
+ this.getAutomation = opts.getAutomation
this.getFileServerToken = opts.getFileServerToken
this.remoteStates = opts.remoteStates
this.middleware = opts.middleware
@@ -232,6 +240,7 @@ export class Http {
this.socket = opts.socket
this.request = opts.request
this.serverBus = opts.serverBus
+ this.getCookieJar = opts.getCookieJar
if (typeof opts.middleware === 'undefined') {
this.middleware = defaultMiddleware
@@ -250,7 +259,7 @@ export class Http {
buffers: this.buffers,
config: this.config,
shouldCorrelatePreRequests: this.shouldCorrelatePreRequests,
- getCurrentBrowser: this.getCurrentBrowser,
+ getAutomation: this.getAutomation,
getFileServerToken: this.getFileServerToken,
remoteStates: this.remoteStates,
request: this.request,
@@ -258,6 +267,7 @@ export class Http {
netStubbingState: this.netStubbingState,
socket: this.socket,
serverBus: this.serverBus,
+ getCookieJar: this.getCookieJar,
debug: (formatter, ...args) => {
if (!debugVerbose.enabled) return
@@ -270,8 +280,8 @@ export class Http {
})
},
getRenderedHTMLOrigins: this.getRenderedHTMLOrigins,
- getPreviousAUTRequestUrl: this.getPreviousAUTRequestUrl,
- setPreviousAUTRequestUrl: this.setPreviousAUTRequestUrl,
+ getAUTUrl: this.getAUTUrl,
+ setAUTUrl: this.setAUTUrl,
getPreRequest: (cb) => {
this.preRequests.get(ctx.req, ctx.debug, cb)
},
@@ -305,12 +315,12 @@ export class Http {
return this.renderedHTMLOrigins
}
- getPreviousAUTRequestUrl = () => {
- return this.previousAUTRequestUrl
+ getAUTUrl = () => {
+ return this.autUrl
}
- setPreviousAUTRequestUrl = (url) => {
- this.previousAUTRequestUrl = url
+ setAUTUrl = (url) => {
+ this.autUrl = url
}
async handleSourceMapRequest (req: Request, res: Response) {
@@ -329,7 +339,7 @@ export class Http {
reset () {
this.buffers.reset()
- this.setPreviousAUTRequestUrl(undefined)
+ this.setAUTUrl(undefined)
}
setBuffer (buffer) {
diff --git a/packages/proxy/lib/http/request-middleware.ts b/packages/proxy/lib/http/request-middleware.ts
index 1cc778247de1..789bda85526f 100644
--- a/packages/proxy/lib/http/request-middleware.ts
+++ b/packages/proxy/lib/http/request-middleware.ts
@@ -2,6 +2,7 @@ import _ from 'lodash'
import { blocked, cors } from '@packages/network'
import { InterceptRequest } from '@packages/net-stubbing'
import type { HttpMiddleware } from './'
+import { getSameSiteContext } from './util/cookies'
// do not use a debug namespace in this file - use the per-request `this.debug` instead
// available as cypress-verbose:proxy:http
@@ -20,7 +21,7 @@ const LogRequest: RequestMiddleware = function () {
this.next()
}
-const ExtractIsAUTFrameHeader: RequestMiddleware = async function () {
+const ExtractIsAUTFrameHeader: RequestMiddleware = function () {
this.req.isAUTFrame = !!this.req.headers['x-cypress-is-aut-frame']
if (this.req.headers['x-cypress-is-aut-frame']) {
@@ -30,6 +31,33 @@ const ExtractIsAUTFrameHeader: RequestMiddleware = async function () {
this.next()
}
+const MaybeAttachCrossOriginCookies: RequestMiddleware = function () {
+ const currentAUTUrl = this.getAUTUrl()
+
+ if (!this.config.experimentalSessionAndOrigin || !currentAUTUrl) {
+ return this.next()
+ }
+
+ const sameSiteContext = getSameSiteContext(
+ currentAUTUrl,
+ this.req.proxiedUrl,
+ this.req.isAUTFrame,
+ )
+
+ const cookies = this.getCookieJar().getCookies(this.req.proxiedUrl, sameSiteContext)
+ const existingCookies = this.req.headers['cookie'] ? [this.req.headers['cookie']] : []
+ const cookiesToAdd = cookies.map((cookie) => `${cookie.key}=${cookie.value}`)
+
+ this.debug('existing cookies on request: %s', existingCookies.join('; '))
+ this.debug('add cookies to request: %s', cookiesToAdd.join('; '))
+
+ // if two or more cookies have the same key, the first one found is preferred,
+ // so we prepend the added cookies so they take preference
+ this.req.headers['cookie'] = cookiesToAdd.concat(existingCookies).join('; ')
+
+ this.next()
+}
+
const CorrelateBrowserPreRequest: RequestMiddleware = async function () {
if (!this.shouldCorrelatePreRequests()) {
return this.next()
@@ -207,6 +235,7 @@ const SendRequestOutgoing: RequestMiddleware = function () {
export default {
LogRequest,
ExtractIsAUTFrameHeader,
+ MaybeAttachCrossOriginCookies,
MaybeEndRequestWithBufferedResponse,
CorrelateBrowserPreRequest,
SendToDriver,
diff --git a/packages/proxy/lib/http/response-middleware.ts b/packages/proxy/lib/http/response-middleware.ts
index efdbe9f2ce32..b552ba2aec11 100644
--- a/packages/proxy/lib/http/response-middleware.ts
+++ b/packages/proxy/lib/http/response-middleware.ts
@@ -2,7 +2,7 @@ import _ from 'lodash'
import charset from 'charset'
import type Debug from 'debug'
import type { CookieOptions } from 'express'
-import { cors, concatStream, httpUtils, uri } from '@packages/network'
+import { cors, concatStream, httpUtils } from '@packages/network'
import type { CypressIncomingRequest, CypressOutgoingResponse } from '@packages/proxy'
import type { HttpMiddleware, HttpMiddlewareThis } from '.'
import iconv from 'iconv-lite'
@@ -12,7 +12,7 @@ import { PassThrough, Readable } from 'stream'
import * as rewriter from './util/rewriter'
import zlib from 'zlib'
import { URL } from 'url'
-import type { Browser } from '@packages/server/lib/browsers/types'
+import { CookiesHelper } from './util/cookies'
interface ResponseMiddlewareProps {
/**
@@ -393,8 +393,8 @@ const MaybePreventCaching: ResponseMiddleware = function () {
this.next()
}
-const determineIfNeedsCrossOriginHandling = (ctx: HttpMiddlewareThis) => {
- const previousAUTRequestUrl = ctx.getPreviousAUTRequestUrl()
+const checkIfNeedsCrossOriginHandling = (ctx: HttpMiddlewareThis) => {
+ const currentAUTUrl = ctx.getAUTUrl()
// A cookie needs cross origin handling if it's an AUT request and
// either the request itself is cross-origin or the origins between
@@ -402,90 +402,90 @@ const determineIfNeedsCrossOriginHandling = (ctx: HttpMiddlewareThis primary-origin, we don't
// recognize the request as cross-origin
return (
- !!ctx.req.isAUTFrame &&
- (
- (previousAUTRequestUrl && !cors.urlOriginsMatch(previousAUTRequestUrl, ctx.req.proxiedUrl))
+ ctx.config.experimentalSessionAndOrigin
+ && ctx.req.isAUTFrame
+ && (
+ (currentAUTUrl && !cors.urlOriginsMatch(currentAUTUrl, ctx.req.proxiedUrl))
|| !ctx.remoteStates.isPrimaryOrigin(ctx.req.proxiedUrl)
)
)
}
-interface EnsureSameSiteNoneProps {
- cookie: string
- browser: Browser | { family: string | null }
- isLocalhost: boolean
- url: URL
- ctxDebug: Debug.Debugger
-}
-
-const cookieSameSiteRegex = /SameSite=(\w+)/i
-const cookieSecureRegex = /(^|\W)Secure(\W|$)/i
-const cookieSecureSemicolonRegex = /;\s*Secure/i
-
-const ensureSameSiteNone = ({ cookie, browser, isLocalhost, url, ctxDebug }: EnsureSameSiteNoneProps) => {
- ctxDebug('original cookie: %s', cookie)
+const CopyCookiesFromIncomingRes: ResponseMiddleware = async function () {
+ const cookies: string | string[] | undefined = this.incomingRes.headers['set-cookie']
- if (cookieSameSiteRegex.test(cookie)) {
- ctxDebug('change cookie to SameSite=None')
- cookie = cookie.replace(cookieSameSiteRegex, 'SameSite=None')
- } else {
- ctxDebug('add SameSite=None to cookie')
- cookie += '; SameSite=None'
+ if (!cookies || !cookies.length) {
+ return this.next()
}
- const isFirefox = browser.family === 'firefox'
-
- // Secure is required for SameSite=None cookies to be set in secure contexts
- // (https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy),
- // but will not allow the cookie to be set in an insecure context.
- // Normally http://localhost is considered a secure context (see
- // https://w3c.github.io/webappsec-secure-contexts/#localhost), but Firefox
- // does not consider the Cypress-launched browser to be a secure context (see
- // https://github.com/cypress-io/cypress/issues/18217). For that reason, we
- // remove Secure from http://localhost cookies in Firefox.
- if (cookieSecureRegex.test(cookie)) {
- if (isFirefox && isLocalhost && url.protocol === 'http:') {
- ctxDebug('remove Secure from cookie')
- cookie = cookie.replace(cookieSecureSemicolonRegex, '')
+ // Cross-origin Cookie Handling
+ // ---------------------------
+ // - We capture cookies sent by responses and add them to our own server-side
+ // tough-cookie cookie jar. All request cookies are captured, since any
+ // future request could be cross-origin even if the response that sets them
+ // is not.
+ // - If we sent the cookie header, it would fail to be set by the browser
+ // (in most cases). We change the header name to 'X-Set-Cookie' to make it
+ // clear that it's one we're handling ourselves.
+ // - We also set the cookies through automation so they are available in the
+ // browser via document.cookie and via Cypress cookie APIs
+ // (e.g. cy.getCookie). This is only done for cross-origin responses, since
+ // non-cross-origin responses will be successfully set in the browser
+ // automatically.
+ // - In the request middleware, we retrieve the cookies for a given URL
+ // and attach them to the request, like the browser normally would.
+ // tough-cookie handles retrieving the correct cookies based on domain,
+ // path, etc. It also removes cookies from the cookie jar if they've expired.
+ const needsCrossOriginHandling = checkIfNeedsCrossOriginHandling(this)
+
+ const appendCookie = (cookie: string) => {
+ const headerName = needsCrossOriginHandling ? 'X-Set-Cookie' : 'Set-Cookie'
+
+ try {
+ this.res.append(headerName, cookie)
+ } catch (err) {
+ this.debug(`failed to append header ${headerName}, continuing %o`, { err, cookie })
}
- } else if (!isFirefox || url.protocol === 'https:') {
- ctxDebug('add Secure to cookie')
- cookie += '; Secure'
}
- ctxDebug('resulting cookie: %s', cookie)
+ if (!this.config.experimentalSessionAndOrigin) {
+ ([] as string[]).concat(cookies).forEach((cookie) => {
+ appendCookie(cookie)
+ })
- return cookie
-}
+ return this.next()
+ }
-const CopyCookiesFromIncomingRes: ResponseMiddleware = function () {
- const cookies: string | string[] | undefined = this.incomingRes.headers['set-cookie']
+ const cookiesHelper = new CookiesHelper({
+ cookieJar: this.getCookieJar(),
+ currentAUTUrl: this.getAUTUrl(),
+ debug: this.debug,
+ request: {
+ url: this.req.proxiedUrl,
+ isAUTFrame: this.req.isAUTFrame,
+ needsCrossOriginHandling,
+ },
+ })
- if (cookies) {
- const needsCrossOriginHandling = (
- this.config.experimentalSessionAndOrigin
- && determineIfNeedsCrossOriginHandling(this)
- )
- const browser = this.getCurrentBrowser() || { family: null }
- const url = new URL(this.req.proxiedUrl)
- const isLocalhost = uri.isLocalhost(url)
+ await cookiesHelper.capturePreviousCookies()
- this.debug('force SameSite=None?', needsCrossOriginHandling)
+ ;([] as string[]).concat(cookies).forEach((cookie) => {
+ cookiesHelper.setCookie(cookie)
- ;([] as string[]).concat(cookies).forEach((cookie) => {
- if (needsCrossOriginHandling) {
- cookie = ensureSameSiteNone({ cookie, browser, isLocalhost, url, ctxDebug: this.debug })
- }
+ appendCookie(cookie)
+ })
- try {
- this.res.append('Set-Cookie', cookie)
- } catch (err) {
- this.debug('failed to Set-Cookie, continuing %o', { err, cookie })
- }
- })
+ const addedCookies = await cookiesHelper.getAddedCookies()
+
+ if (!needsCrossOriginHandling || !addedCookies.length) {
+ return this.next()
}
- this.next()
+ this.serverBus.once('cross:origin:automation:cookies:received', () => {
+ this.next()
+ })
+
+ this.serverBus.emit('cross:origin:automation:cookies', addedCookies)
}
const REDIRECT_STATUS_CODES: any[] = [301, 302, 303, 307, 308]
@@ -602,7 +602,7 @@ const SendResponseBodyToClient: ResponseMiddleware = function () {
if (this.req.isAUTFrame) {
// track the previous AUT request URL so we know if the next requests
// is cross-origin
- this.setPreviousAUTRequestUrl(this.req.proxiedUrl)
+ this.setAUTUrl(this.req.proxiedUrl)
}
this.incomingResStream.pipe(this.res).on('error', this.onError)
diff --git a/packages/proxy/lib/http/util/cookies.ts b/packages/proxy/lib/http/util/cookies.ts
new file mode 100644
index 000000000000..21fbf78c43dc
--- /dev/null
+++ b/packages/proxy/lib/http/util/cookies.ts
@@ -0,0 +1,160 @@
+import _ from 'lodash'
+import type Debug from 'debug'
+import { URL } from 'url'
+import { cors } from '@packages/network'
+import { Cookie, CookieJar } from '@packages/server/lib/cookie-jar'
+import type { AutomationCookie } from '@packages/server/lib/automation/cookies'
+
+interface RequestDetails {
+ url: string
+ isAUTFrame: boolean
+ needsCrossOriginHandling: boolean
+}
+
+// sameSiteContext is a concept for tough-cookie's cookie jar that helps it
+// simulate what a browser would do when determining whether or not it should
+// be set from a response or a attached to a response. it shouldn't be confused
+// with a cookie's SameSite property, though that also plays a role when
+// setting/getting a cookie from the tough-cookie cookie jar. see tough-cookie's
+// own explanation of sameSiteContext for more information:
+// see https://github.com/salesforce/tough-cookie#samesite-cookies
+export const getSameSiteContext = (autUrl: string | undefined, requestUrl: string, isAUTFrameRequest: boolean) => {
+ // if there's no AUT URL, it's a request for the first URL visited, or if
+ // the request origin matches the AUT origin; both indicate that it's not
+ // a cross-origin request
+ if (!autUrl || cors.urlOriginsMatch(autUrl, requestUrl)) {
+ return 'strict'
+ }
+
+ // being an AUT frame request means it's via top-level navigation, and we've
+ // ruled out same-origin navigation, so the context is 'lax'.
+ // anything else is a non-navigation, cross-origin request
+ return isAUTFrameRequest ? 'lax' : 'none'
+}
+
+const sameSiteNoneRe = /; +samesite=(?:'none'|"none"|none)/i
+
+export const parseCookie = (cookie: string) => {
+ const toughCookie = CookieJar.parse(cookie)
+
+ if (!toughCookie) return
+
+ // fixes tough-cookie defaulting undefined/invalid SameSite to 'none'
+ // https://github.com/salesforce/tough-cookie/issues/191
+ const hasUnspecifiedSameSite = toughCookie.sameSite === 'none' && !sameSiteNoneRe.test(cookie)
+
+ // not all browsers currently default to lax, but they're heading in that
+ // direction since it's now the standard, so this is more future-proof
+ if (hasUnspecifiedSameSite) {
+ toughCookie.sameSite = 'lax'
+ }
+
+ return toughCookie
+}
+
+const comparableCookieString = (toughCookie: Cookie): string => {
+ return _(toughCookie)
+ .pick('key', 'value', 'domain', 'path')
+ .toPairs()
+ .sortBy(([key]) => key)
+ .map(([key, value]) => `${key}=${value}`)
+ .join('; ')
+}
+
+const areCookiesEqual = (cookieA: Cookie, cookieB: Cookie) => {
+ return comparableCookieString(cookieA) === comparableCookieString(cookieB)
+}
+
+const matchesPreviousCookie = (previousCookies: Cookie[], cookie: Cookie) => {
+ return !!previousCookies.find((previousCookie) => {
+ return areCookiesEqual(previousCookie, cookie)
+ })
+}
+
+const toughCookieToAutomationCookie = (toughCookie: Cookie, defaultDomain: string): AutomationCookie => {
+ const expiry = toughCookie.expiryTime()
+
+ return {
+ domain: toughCookie.domain || defaultDomain,
+ expiry: isFinite(expiry) ? expiry / 1000 : null,
+ httpOnly: toughCookie.httpOnly,
+ maxAge: toughCookie.maxAge,
+ name: toughCookie.key,
+ path: toughCookie.path,
+ sameSite: toughCookie.sameSite === 'none' ? 'no_restriction' : toughCookie.sameSite,
+ secure: toughCookie.secure,
+ value: toughCookie.value,
+ }
+}
+
+/**
+ * Utility for dealing with cross-origin cookies
+ * - Tracks which cookies were added to our server-side cookie jar during
+ * a request, so they can be added to the browser via automation
+ * - Provides utility cookie-handling methods that rely on aspects of the
+ * request (url, previous request url, etc)
+ */
+export class CookiesHelper {
+ cookieJar: CookieJar
+ currentAUTUrl: string | undefined
+ request: RequestDetails
+ debug: Debug.Debugger
+ defaultDomain: string
+ sameSiteContext: 'strict' | 'lax' | 'none'
+ previousCookies: Cookie[] = []
+
+ constructor ({ cookieJar, currentAUTUrl, request, debug }) {
+ this.cookieJar = cookieJar
+ this.currentAUTUrl = currentAUTUrl
+ this.request = request
+ this.debug = debug
+ this.sameSiteContext = getSameSiteContext(currentAUTUrl, request.url, request.isAUTFrame)
+
+ const parsedRequestUrl = new URL(request.url)
+
+ this.defaultDomain = parsedRequestUrl.hostname
+ }
+
+ capturePreviousCookies () {
+ // this plays a part in adding cross-origin cookies to the browser via
+ // automation. if the request doesn't need cross-origin handling, this
+ // is a noop
+ if (!this.request.needsCrossOriginHandling) return
+
+ this.previousCookies = this.cookieJar.getAllCookies()
+ }
+
+ getAddedCookies () {
+ // this plays a part in adding cross-origin cookies to the browser via
+ // automation. if the request doesn't need cross-origin handling, this
+ // is a noop
+ if (!this.request.needsCrossOriginHandling) return []
+
+ const afterCookies = this.cookieJar.getAllCookies()
+
+ return afterCookies.reduce((memo, afterCookie) => {
+ if (matchesPreviousCookie(this.previousCookies, afterCookie)) return memo
+
+ return memo.concat(toughCookieToAutomationCookie(afterCookie, this.defaultDomain))
+ }, [])
+ }
+
+ setCookie (cookie: string) {
+ const toughCookie = parseCookie(cookie)
+
+ // don't set the cookie in our own cookie jar if the parsed cookie is
+ // undefined (meaning it's invalid) or if the browser would not set it
+ // because Secure is required for SameSite=None. not all browsers currently
+ // currently enforce this, but they're heading in that direction since
+ // it's now the standard, so this is more future-proof
+ if (!toughCookie || (toughCookie.sameSite === 'none' && !toughCookie.secure)) {
+ return
+ }
+
+ try {
+ this.cookieJar.setCookie(toughCookie, this.request.url, this.sameSiteContext)
+ } catch (err) {
+ this.debug('adding cookie to jar failed: %s', err.message)
+ }
+ }
+}
diff --git a/packages/proxy/lib/http/util/prerequests.ts b/packages/proxy/lib/http/util/prerequests.ts
index fc595539157a..cf0443c81b8a 100644
--- a/packages/proxy/lib/http/util/prerequests.ts
+++ b/packages/proxy/lib/http/util/prerequests.ts
@@ -3,7 +3,6 @@ import type {
BrowserPreRequest,
} from '@packages/proxy'
import Debug from 'debug'
-import _ from 'lodash'
const debug = Debug('cypress:proxy:http:util:prerequests')
const debugVerbose = Debug('cypress-verbose:proxy:http:util:prerequests')
@@ -12,101 +11,103 @@ const metrics: any = {
browserPreRequestsReceived: 0,
proxyRequestsReceived: 0,
immediatelyMatchedRequests: 0,
- eventuallyReceivedPreRequest: [],
- neverReceivedPreRequest: [],
+ unmatchedRequests: 0,
+ unmatchedPreRequests: 0,
}
process.once('exit', () => {
debug('metrics: %o', metrics)
})
-function removeOne (a: Array, predicate: (v: T) => boolean): T | void {
- for (let i = a.length - 1; i >= 0; i--) {
- const v = a[i]
-
- if (predicate(v)) {
- a.splice(i, 1)
-
- return v
- }
- }
-}
+export type GetPreRequestCb = (browserPreRequest?: BrowserPreRequest) => void
-function matches (preRequest: BrowserPreRequest, req: Pick) {
- return preRequest.method === req.method && preRequest.url === req.proxiedUrl
+type PendingRequest = {
+ ctxDebug
+ callback: GetPreRequestCb
+ timeout: ReturnType
}
-export type GetPreRequestCb = (browserPreRequest?: BrowserPreRequest) => void
+// This class' purpose is to match up incoming "requests" (requests from the browser received by the http proxy)
+// with "pre-requests" (events received by our browser extension indicating that the browser is about to make a request).
+// Because these come from different sources, they can be out of sync, arriving in either order.
+// Basically, when requests come in, we want to provide additional data read from the pre-request. but if no pre-request
+// ever comes in, we don't want to block proxied requests indefinitely.
export class PreRequests {
- pendingBrowserPreRequests: Array = []
- requestsPendingPreRequestCbs: Array<{
- cb: (browserPreRequest: BrowserPreRequest) => void
- method: string
- proxiedUrl: string
- }> = []
-
- get (req: CypressIncomingRequest, ctxDebug, cb: GetPreRequestCb) {
- metrics.proxyRequestsReceived++
-
- const pendingBrowserPreRequest = removeOne(this.pendingBrowserPreRequests, (browserPreRequest) => {
- return matches(browserPreRequest, req)
- })
-
- if (pendingBrowserPreRequest) {
- metrics.immediatelyMatchedRequests++
-
- ctxDebug('matches pending pre-request %o', pendingBrowserPreRequest)
+ requestTimeout: number
+ pendingPreRequests: Record = {}
+ pendingRequests: Record = {}
+ prerequestTimestamps: Record = {}
+ sweepInterval: ReturnType
+
+ constructor (requestTimeout = 500) {
+ // If a request comes in and we don't have a matching pre-request after this timeout,
+ // we invoke the request callback to tell the server to proceed (we don't want to block
+ // user requests indefinitely).
+ this.requestTimeout = requestTimeout
+
+ // Discarding prerequests on the other hand is not urgent, so we do it on a regular interval
+ // rather than with a separate timer for each one.
+ // 2 times the requestTimeout is arbitrary, chosen to give plenty of time and
+ // make sure we don't discard any pre-requests prematurely but that we don't leak memory over time
+ // if a large number of pre-requests don't match up
+ // fixes: https://github.com/cypress-io/cypress/issues/17853
+ this.sweepInterval = setInterval(() => {
+ const now = Date.now()
+
+ Object.entries(this.prerequestTimestamps).forEach(([key, timestamp]) => {
+ if (timestamp + this.requestTimeout * 2 < now) {
+ debugVerbose('timed out unmatched pre-request %s: %o', key, this.pendingPreRequests[key])
+ metrics.unmatchedPreRequests++
+ delete this.pendingPreRequests[key]
+ delete this.prerequestTimestamps[key]
+ }
+ })
+ }, this.requestTimeout * 2)
+ }
- return cb(pendingBrowserPreRequest)
- }
+ addPending (browserPreRequest: BrowserPreRequest) {
+ metrics.browserPreRequestsReceived++
+ const key = `${browserPreRequest.method}-${browserPreRequest.url}`
- const timeout = setTimeout(() => {
- metrics.neverReceivedPreRequest.push({ url: req.proxiedUrl })
- ctxDebug('500ms passed without a pre-request, continuing request with an empty pre-request field!')
-
- remove()
- cb()
- }, 500)
-
- const startedMs = Date.now()
- const remove = _.once(() => removeOne(this.requestsPendingPreRequestCbs, (v) => v === requestPendingPreRequestCb))
-
- const requestPendingPreRequestCb = {
- cb: (browserPreRequest) => {
- const afterMs = Date.now() - startedMs
-
- metrics.eventuallyReceivedPreRequest.push({ url: browserPreRequest.url, afterMs })
- ctxDebug('received pre-request after %dms %o', afterMs, browserPreRequest)
- clearTimeout(timeout)
- remove()
- cb(browserPreRequest)
- },
- proxiedUrl: req.proxiedUrl,
- method: req.method,
+ if (this.pendingRequests[key]) {
+ debugVerbose('Incoming pre-request %s matches pending request. %o', key, browserPreRequest)
+ clearTimeout(this.pendingRequests[key].timeout)
+ this.pendingRequests[key].callback(browserPreRequest)
+ delete this.pendingRequests[key]
}
- this.requestsPendingPreRequestCbs.push(requestPendingPreRequestCb)
+ debugVerbose('Caching pre-request %s to be matched later. %o', key, browserPreRequest)
+ this.pendingPreRequests[key] = browserPreRequest
+ this.prerequestTimestamps[key] = Date.now()
}
- addPending (browserPreRequest: BrowserPreRequest) {
- if (this.pendingBrowserPreRequests.indexOf(browserPreRequest) !== -1) {
- return
- }
-
- metrics.browserPreRequestsReceived++
+ get (req: CypressIncomingRequest, ctxDebug, callback: GetPreRequestCb) {
+ metrics.proxyRequestsReceived++
+ const key = `${req.method}-${req.proxiedUrl}`
- const requestPendingPreRequestCb = removeOne(this.requestsPendingPreRequestCbs, (req) => {
- return matches(browserPreRequest, req)
- })
+ if (this.pendingPreRequests[key]) {
+ metrics.immediatelyMatchedRequests++
+ ctxDebug('Incoming request %s matches known pre-request: %o', key, this.pendingPreRequests[key])
+ callback(this.pendingPreRequests[key])
- if (requestPendingPreRequestCb) {
- debugVerbose('immediately matched pre-request %o', browserPreRequest)
+ delete this.pendingPreRequests[key]
+ delete this.prerequestTimestamps[key]
- return requestPendingPreRequestCb.cb(browserPreRequest)
+ return
}
- debugVerbose('queuing pre-request to be matched later %o %o', browserPreRequest, this.pendingBrowserPreRequests)
- this.pendingBrowserPreRequests.push(browserPreRequest)
+ const timeout = setTimeout(() => {
+ callback()
+ ctxDebug('Never received pre-request for request %s after waiting %sms. Continuing without one.', key, this.requestTimeout)
+ metrics.unmatchedRequests++
+ delete this.pendingRequests[key]
+ }, this.requestTimeout)
+
+ this.pendingRequests[key] = {
+ ctxDebug,
+ callback,
+ timeout,
+ }
}
}
diff --git a/packages/proxy/test/unit/http/request-middleware.spec.ts b/packages/proxy/test/unit/http/request-middleware.spec.ts
index cdf7c1bbe649..fffa0d0663d2 100644
--- a/packages/proxy/test/unit/http/request-middleware.spec.ts
+++ b/packages/proxy/test/unit/http/request-middleware.spec.ts
@@ -11,6 +11,7 @@ describe('http/request-middleware', () => {
expect(_.keys(RequestMiddleware)).to.have.ordered.members([
'LogRequest',
'ExtractIsAUTFrameHeader',
+ 'MaybeAttachCrossOriginCookies',
'MaybeEndRequestWithBufferedResponse',
'CorrelateBrowserPreRequest',
'SendToDriver',
@@ -57,6 +58,57 @@ describe('http/request-middleware', () => {
})
})
+ describe('MaybeAttachCrossOriginCookies', () => {
+ const { MaybeAttachCrossOriginCookies } = RequestMiddleware
+
+ it('is a noop if experimental flag is off', async () => {
+ const ctx = getContext()
+
+ ctx.config.experimentalSessionAndOrigin = false
+
+ await testMiddleware([MaybeAttachCrossOriginCookies], ctx)
+
+ expect(ctx.req.headers['cookie']).to.equal('exist=ing')
+ })
+
+ it('is a noop if no current AUT URL', async () => {
+ const ctx = getContext()
+
+ ctx.getAUTUrl = () => ''
+
+ await testMiddleware([MaybeAttachCrossOriginCookies], ctx)
+
+ expect(ctx.req.headers['cookie']).to.equal('exist=ing')
+ })
+
+ it('is prepends cookie jar cookies to request', async () => {
+ const ctx = getContext()
+
+ await testMiddleware([MaybeAttachCrossOriginCookies], ctx)
+
+ expect(ctx.req.headers['cookie']).to.equal('new=one; exist=ing')
+ })
+
+ function getContext () {
+ const cookieJar = {
+ getCookies: () => [{ key: 'new', value: 'one' }],
+ }
+
+ return {
+ getAUTUrl: () => 'http://foobar.com',
+ getCookieJar: () => cookieJar,
+ config: { experimentalSessionAndOrigin: true },
+ req: {
+ proxiedUrl: 'http://foobar.com',
+ isAUTFrame: true,
+ headers: {
+ cookie: 'exist=ing',
+ },
+ },
+ }
+ }
+ })
+
describe('MaybeEndRequestWithBufferedResponse', () => {
const { MaybeEndRequestWithBufferedResponse } = RequestMiddleware
diff --git a/packages/proxy/test/unit/http/response-middleware.spec.ts b/packages/proxy/test/unit/http/response-middleware.spec.ts
index 172f63efe7a0..bbd8d0184cd7 100644
--- a/packages/proxy/test/unit/http/response-middleware.spec.ts
+++ b/packages/proxy/test/unit/http/response-middleware.spec.ts
@@ -31,6 +31,36 @@ describe('http/response-middleware', function () {
])
})
+ it('errors if this.next() is called more than once in the same middleware', function (done) {
+ const middleware = function () {
+ this.next()
+ this.next()
+ }
+
+ testMiddleware([middleware], {
+ onError (err) {
+ expect(err.message).to.equal('Error running proxy middleware: Cannot call this.next() more than once in the same middleware function. Doing so can cause unintended issues.')
+
+ done()
+ },
+ })
+ })
+
+ it('does not error if this.next() is called more than once in different middleware', function () {
+ const middleware1 = function () {
+ this.next()
+ }
+ const middleware2 = function () {
+ this.next()
+ }
+
+ return testMiddleware([middleware1, middleware2], {
+ onError () {
+ throw new Error('onError should not be called')
+ },
+ })
+ })
+
describe('MaybeStripDocumentDomainFeaturePolicy', function () {
const { MaybeStripDocumentDomainFeaturePolicy } = ResponseMiddleware
let ctx
@@ -603,16 +633,12 @@ describe('http/response-middleware', function () {
const { CopyCookiesFromIncomingRes } = ResponseMiddleware
it('appends cookies on the response when an array', async function () {
- const appendStub = sinon.stub()
- const ctx = prepareContext({
+ const { appendStub, ctx } = prepareSameOriginContext({
incomingRes: {
headers: {
'set-cookie': ['cookie1=value1', 'cookie2=value2'],
},
},
- res: {
- append: appendStub,
- },
})
await testMiddleware([CopyCookiesFromIncomingRes], ctx)
@@ -623,17 +649,7 @@ describe('http/response-middleware', function () {
})
it('appends cookies on the response when a string', async function () {
- const appendStub = sinon.stub()
- const ctx = prepareContext({
- incomingRes: {
- headers: {
- 'set-cookie': 'cookie=value',
- },
- },
- res: {
- append: appendStub,
- },
- })
+ const { appendStub, ctx } = prepareSameOriginContext()
await testMiddleware([CopyCookiesFromIncomingRes], ctx)
@@ -654,229 +670,93 @@ describe('http/response-middleware', function () {
expect(appendStub).not.to.be.called
})
- describe('SameSite', function () {
- it('forces SameSite=None when an AUT request and does not match origin policy', async function () {
- const appendStub = sinon.stub()
- const ctx = prepareContext({
- incomingRes: {
- headers: {
- 'content-type': 'text/html',
- 'set-cookie': 'cookie=value',
- },
- },
- req: {
- isAUTFrame: true,
- },
- res: {
- append: appendStub,
+ it('uses X-Set-Cookie when experimental flag is on and request needs cross-origin handling', async () => {
+ const appendStub = sinon.stub()
+ const ctx = prepareContext({
+ req: {
+ isAUTFrame: true,
+ },
+ incomingRes: {
+ headers: {
+ 'set-cookie': 'cookie=value',
},
- })
-
- await testMiddleware([CopyCookiesFromIncomingRes], ctx)
-
- expect(appendStub).to.be.calledOnce
- expect(appendStub).to.be.calledWith('Set-Cookie', 'cookie=value; SameSite=None; Secure')
+ },
+ res: {
+ append: appendStub,
+ },
})
- it('forces SameSite=None when an AUT request and last AUT request was a different origin', async function () {
- const appendStub = sinon.stub()
- const ctx = prepareContext({
- incomingRes: {
- headers: {
- 'content-type': 'text/html',
- 'set-cookie': 'cookie=value',
- },
- },
- req: {
- isAUTFrame: true,
- proxiedUrl: 'https://site2.com',
- },
- res: {
- append: appendStub,
- },
- getPreviousAUTRequestUrl () {
- return 'https://different.site'
- },
- })
+ await testMiddleware([CopyCookiesFromIncomingRes], ctx)
- await testMiddleware([CopyCookiesFromIncomingRes], ctx)
+ expect(appendStub).to.be.calledOnce
+ expect(appendStub).to.be.calledWith('X-Set-Cookie', 'cookie=value')
+ })
- expect(appendStub).to.be.calledOnce
- expect(appendStub).to.be.calledWith('Set-Cookie', 'cookie=value; SameSite=None; Secure')
- })
+ it('uses Set-Cookie when experimental flag is on but request does not need cross-origin handling', async () => {
+ const { appendStub, ctx } = prepareSameOriginContext()
- it('does not force SameSite=None if not an AUT request', async function () {
- const appendStub = sinon.stub()
- const ctx = prepareContext({
- incomingRes: {
- headers: {
- 'content-type': 'text/html',
- 'set-cookie': 'cookie=value',
- },
- },
- res: {
- append: appendStub,
- },
- })
+ await testMiddleware([CopyCookiesFromIncomingRes], ctx)
- await testMiddleware([CopyCookiesFromIncomingRes], ctx)
+ expect(appendStub).to.be.calledOnce
+ expect(appendStub).to.be.calledWith('Set-Cookie', 'cookie=value')
+ })
- expect(appendStub).to.be.calledWith('Set-Cookie', 'cookie=value')
- })
+ it('does not send cross:origin:automation:cookies if request does not need cross-origin handling', async () => {
+ const { ctx } = prepareSameOriginContext()
- it('does not force SameSite=None if the first AUT request', async function () {
- const appendStub = sinon.stub()
- const ctx = prepareContext({
- incomingRes: {
- headers: {
- 'content-type': 'text/html',
- 'set-cookie': 'cookie=value',
- },
- },
- req: {
- isAUTFrame: true,
- proxiedUrl: 'http://www.foobar.com/primary-origin.html',
- },
- res: {
- append: appendStub,
- },
- })
+ await testMiddleware([CopyCookiesFromIncomingRes], ctx)
- await testMiddleware([CopyCookiesFromIncomingRes], ctx)
+ expect(ctx.serverBus.emit).not.to.be.called
+ })
- expect(appendStub).to.be.calledWith('Set-Cookie', 'cookie=value')
- })
+ it('does not send cross:origin:automation:cookies if there are no added cookies', async () => {
+ const cookieJar = {
+ getAllCookies: () => [{ key: 'cookie', value: 'value' }],
+ }
- it('does not force SameSite=None if an AUT request but not cross-origin', async function () {
- const appendStub = sinon.stub()
- const ctx = prepareContext({
- incomingRes: {
- headers: {
- 'content-type': 'text/html',
- 'set-cookie': 'cookie=value',
- },
- },
- req: {
- isAUTFrame: true,
- proxiedUrl: 'http://www.foobar.com/primary-origin.html',
- },
- res: {
- append: appendStub,
+ const ctx = prepareContext({
+ cookieJar,
+ incomingRes: {
+ headers: {
+ 'set-cookie': 'cookie=value',
},
- })
-
- ctx.getPreviousAUTRequestUrl = () => ctx.req.proxiedUrl
-
- await testMiddleware([CopyCookiesFromIncomingRes], ctx)
-
- expect(appendStub).to.be.calledWith('Set-Cookie', 'cookie=value')
+ },
})
- it('does not force SameSite=None if experimental flag is off', async function () {
- const appendStub = sinon.stub()
- const ctx = prepareContext({
- incomingRes: {
- headers: {
- 'content-type': 'text/html',
- 'set-cookie': 'cookie=value',
- },
- },
- req: {
- isAUTFrame: true,
- },
- res: {
- append: appendStub,
- },
- config: {
- experimentalSessionAndOrigin: false,
- },
- })
-
- await testMiddleware([CopyCookiesFromIncomingRes], ctx)
-
- expect(appendStub).to.be.calledWith('Set-Cookie', 'cookie=value')
- })
-
- describe('cookie modification scenarios', function () {
- const makeScenarios = (output, flippedOutput?) => {
- return [
- ['SameSite=Strict; Secure', output],
- ['SameSite=Strict', output],
- ['SameSite=Lax; Secure', output],
- ['SameSite=Lax', output],
- ['SameSite=Invalid; Secure', output],
- ['SameSite=Invalid', output],
- ['SameSite=None', output],
- ['', output],
- // When Secure is first or there's no SameSite, it ends up as
- // "Secure; SameSite=None" instead of "Secure" being second
- ['Secure', flippedOutput || output],
- ['Secure; SameSite=None', flippedOutput || output],
- ]
- }
-
- const withFirefox = {
- getCurrentBrowser: () => ({ family: 'firefox' }),
- }
-
- describe('not Firefox', function () {
- makeScenarios('SameSite=None; Secure', 'Secure; SameSite=None').forEach(([input, output]) => {
- it(`${input} -> ${output}`, async function () {
- const { appendStub, ctx } = prepareContextWithCookie(`insecure=true; cookie=value${input ? '; ' : ''}${input}`)
-
- await testMiddleware([CopyCookiesFromIncomingRes], ctx)
-
- expect(appendStub).to.be.calledOnce
- expect(appendStub).to.be.calledWith('Set-Cookie', `insecure=true; cookie=value; ${output}`)
- })
- })
- })
+ await testMiddleware([CopyCookiesFromIncomingRes], ctx)
- describe('Firefox + non-localhost', function () {
- makeScenarios('SameSite=None; Secure', 'Secure; SameSite=None').forEach(([input, output]) => {
- it(`${input} -> ${output}`, async function () {
- const { appendStub, ctx } = prepareContextWithCookie(`insecure=true; cookie=value${input ? '; ' : ''}${input}`, {
- req: { proxiedUrl: 'https://foobar.com' },
- ...withFirefox,
- })
+ expect(ctx.serverBus.emit).not.to.be.called
+ })
- await testMiddleware([CopyCookiesFromIncomingRes], ctx)
+ it('sends cross:origin:automation:cookies if there are added cookies and resolves on cross:origin:automation:cookies:received', async () => {
+ const cookieJar = {
+ getAllCookies: sinon.stub(),
+ }
- expect(appendStub).to.be.calledOnce
- expect(appendStub).to.be.calledWith('Set-Cookie', `insecure=true; cookie=value; ${output}`)
- })
- })
- })
+ cookieJar.getAllCookies.onCall(0).returns([])
+ cookieJar.getAllCookies.onCall(1).returns([cookieStub({ key: 'cookie', value: 'value' })])
- describe('Firefox + https://localhost', function () {
- makeScenarios('SameSite=None; Secure', 'Secure; SameSite=None').forEach(([input, output]) => {
- it(`${input} -> ${output}`, async function () {
- const { appendStub, ctx } = prepareContextWithCookie(`insecure=true; cookie=value${input ? '; ' : ''}${input}`, {
- req: { proxiedUrl: 'https://localhost:3500' },
- ...withFirefox,
- })
+ const ctx = prepareContext({
+ cookieJar,
+ incomingRes: {
+ headers: {
+ 'set-cookie': 'cookie=value',
+ },
+ },
+ })
- await testMiddleware([CopyCookiesFromIncomingRes], ctx)
+ // test will hang if this.next() is not called, so this also tests
+ // that we move on once receiving this event
+ ctx.serverBus.once.withArgs('cross:origin:automation:cookies:received').yields()
- expect(appendStub).to.be.calledOnce
- expect(appendStub).to.be.calledWith('Set-Cookie', `insecure=true; cookie=value; ${output}`)
- })
- })
- })
+ await testMiddleware([CopyCookiesFromIncomingRes], ctx)
- describe('Firefox + http://localhost', function () {
- makeScenarios('SameSite=None').forEach(([input, output]) => {
- it(`${input} -> ${output}`, async function () {
- const { appendStub, ctx } = prepareContextWithCookie(`insecure=true; cookie=value${input ? '; ' : ''}${input}`, withFirefox)
+ expect(ctx.serverBus.emit).to.be.calledWith('cross:origin:automation:cookies')
- await testMiddleware([CopyCookiesFromIncomingRes], ctx)
+ const cookies = ctx.serverBus.emit.withArgs('cross:origin:automation:cookies').args[0][1]
- expect(appendStub).to.be.calledOnce
- expect(appendStub).to.be.calledWith('Set-Cookie', `insecure=true; cookie=value; ${output}`)
- })
- })
- })
- })
+ expect(cookies[0].name).to.equal('cookie')
+ expect(cookies[0].value).to.equal('value')
})
function prepareContext (props) {
@@ -892,6 +772,12 @@ describe('http/response-middleware', function () {
eventEmitter.emit('cross:origin:bridge:ready', { originPolicy })
})
+ remoteStates.isPrimaryOrigin = () => false
+
+ const cookieJar = props.cookieJar || {
+ getAllCookies: () => [],
+ }
+
return {
incomingRes: {
headers: {},
@@ -903,8 +789,9 @@ describe('http/response-middleware', function () {
...props.res,
},
req: {
- proxiedUrl: 'http://127.0.0.1:3501/primary-origin.html',
+ proxiedUrl: 'http://www.foobar.com/login',
headers: {},
+ isAUTFrame: true,
...props.req,
},
incomingResStream: {
@@ -915,39 +802,51 @@ describe('http/response-middleware', function () {
config: {
experimentalSessionAndOrigin: true,
},
- getCurrentBrowser () {
- return { family: 'chromium' }
- },
- getPreviousAUTRequestUrl () {},
+ getCookieJar: () => cookieJar,
+ getAUTUrl: () => 'http://www.foobar.com/primary-origin.html',
remoteStates,
debug () {},
onError (error) {
throw error
},
+ serverBus: {
+ emit: sinon.stub(),
+ once: sinon.stub(),
+ },
..._.omit(props, 'incomingRes', 'res', 'req'),
}
}
- function prepareContextWithCookie (cookie, props: any = {}) {
+ function prepareSameOriginContext (props = {}) {
const appendStub = sinon.stub()
+
const ctx = prepareContext({
- incomingRes: {
- headers: {
- 'content-type': 'text/html',
- 'set-cookie': cookie,
- },
- },
req: {
isAUTFrame: true,
...props.req,
},
+ incomingRes: {
+ headers: {
+ 'set-cookie': 'cookie=value',
+ },
+ ...props.incomingRes,
+ },
res: {
append: appendStub,
+ ...props.res,
},
- ..._.omit(props, 'incomingRes', 'res', 'req'),
})
+ ctx.remoteStates.isPrimaryOrigin = () => true
+
return { appendStub, ctx }
}
+
+ function cookieStub (props) {
+ return {
+ expiryTime: () => 0,
+ ...props,
+ }
+ }
})
})
diff --git a/packages/proxy/test/unit/http/util/prerequests.spec.ts b/packages/proxy/test/unit/http/util/prerequests.spec.ts
index 971c3ccc8520..c69f921aee7e 100644
--- a/packages/proxy/test/unit/http/util/prerequests.spec.ts
+++ b/packages/proxy/test/unit/http/util/prerequests.spec.ts
@@ -7,7 +7,11 @@ describe('http/util/prerequests', () => {
let preRequests: PreRequests
beforeEach(() => {
- preRequests = new PreRequests()
+ preRequests = new PreRequests(10)
+ })
+
+ afterEach(() => {
+ clearInterval(preRequests.sweepInterval)
})
it('synchronously matches a pre-request that existed at the time of the request', () => {
@@ -33,4 +37,30 @@ describe('http/util/prerequests', () => {
preRequests.get({ proxiedUrl: 'foo', method: 'GET' } as CypressIncomingRequest, () => {}, cb)
preRequests.addPending({ requestId: '1234', url: 'foo', method: 'GET' } as BrowserPreRequest)
})
+
+ it('invokes a request callback after a timeout if no pre-request occurs', (done) => {
+ const cb = (preRequest) => {
+ expect(preRequest).to.be.undefined
+ done()
+ }
+
+ preRequests.get({ proxiedUrl: 'foo', method: 'GET' } as CypressIncomingRequest, () => {}, cb)
+ })
+
+ // https://github.com/cypress-io/cypress/issues/17853
+ it('eventually discards pre-requests that don\'t match requests', (done) => {
+ preRequests.addPending({ requestId: '1234', url: 'foo', method: 'GET' } as BrowserPreRequest)
+
+ // preRequests garbage collects pre-requests that never matched up with an incoming request after around
+ // 2 * requestTimeout. We verify that it's gone (and therefore not leaking memory) by sending in a request
+ // and assuring that the pre-request wasn't there to be matched anymore.
+ setTimeout(() => {
+ const cb = (preRequest) => {
+ expect(preRequest).to.be.undefined
+ done()
+ }
+
+ preRequests.get({ proxiedUrl: 'foo', method: 'GET' } as CypressIncomingRequest, () => {}, cb)
+ }, 50)
+ })
})
diff --git a/packages/server/lib/automation/automation.ts b/packages/server/lib/automation/automation.ts
index aa3579df63d3..ac7317348e8e 100644
--- a/packages/server/lib/automation/automation.ts
+++ b/packages/server/lib/automation/automation.ts
@@ -4,6 +4,7 @@ import { Cookies } from './cookies'
import { Screenshot } from './screenshot'
import type { BrowserPreRequest } from '@packages/proxy'
import type { AutomationMiddleware, OnRequestEvent } from '@packages/types'
+import { cookieJar } from '../cookie-jar'
export type OnBrowserPreRequest = (browserPreRequest: BrowserPreRequest) => void
@@ -109,10 +110,20 @@ export class Automation {
return this.cookies.setCookie(data, automate)
case 'set:cookies':
return this.cookies.setCookies(data, automate)
+ case 'add:cookies':
+ return this.cookies.addCookies(data, automate)
case 'clear:cookies':
- return this.cookies.clearCookies(data, automate)
+ return Bluebird.all([
+ this.cookies.clearCookies(data, automate),
+ cookieJar.removeAllCookies(),
+ ])
+ .spread((automationResult) => automationResult)
case 'clear:cookie':
- return this.cookies.clearCookie(data, automate)
+ return Bluebird.all([
+ this.cookies.clearCookie(data, automate),
+ cookieJar.removeCookie(data),
+ ])
+ .spread((automationResult) => automationResult)
case 'change:cookie':
return this.cookies.changeCookie(data)
case 'create:download':
diff --git a/packages/server/lib/automation/cookies.ts b/packages/server/lib/automation/cookies.ts
index 5c9b2750e491..ee45dcc89704 100644
--- a/packages/server/lib/automation/cookies.ts
+++ b/packages/server/lib/automation/cookies.ts
@@ -3,6 +3,19 @@ import Debug from 'debug'
import extension from '@packages/extension'
import { isHostOnlyCookie } from '../browsers/cdp_automation'
+export interface AutomationCookie {
+ domain: string
+ expiry: number | null
+ httpOnly: boolean
+ maxAge: 'Infinity' | '-Infinity' | number | null
+ name: string
+ path: string | null
+ sameSite: string
+ secure: boolean
+ url?: string
+ value: string
+}
+
// match the w3c webdriver spec on return cookies
// https://w3c.github.io/webdriver/webdriver-spec.html#cookies
const COOKIE_PROPERTIES = 'name value path domain secure httpOnly expiry hostOnly sameSite'.split(' ')
@@ -56,6 +69,10 @@ export const normalizeGetCookieProps = (props) => {
return normalizeCookieProps(props)
}
+/**
+ * Utility for getting/setting/clearing cookies via automation
+ * Normalizes the API for different automation mechanisms (CDP, extension, etc)
+ */
export class Cookies {
static normalizeCookies = normalizeCookies
static normalizeCookieProps = normalizeCookieProps
@@ -130,7 +147,11 @@ export class Cookies {
})
}
- setCookies (cookies, automate) {
+ setCookies (
+ cookies: AutomationCookie[],
+ automate: (eventName: string, cookies: AutomationCookie[]) => Bluebird.Promise,
+ eventName: 'set:cookies' | 'add:cookies' = 'set:cookies',
+ ) {
cookies = cookies.map((data) => {
this.throwIfNamespaced(data)
const cookie = normalizeCookieProps(data)
@@ -142,13 +163,22 @@ export class Cookies {
return cookie
})
- debug('set:cookies %o', cookies)
+ debug(`${eventName} %o`, cookies)
- return automate('set:cookies', cookies)
- // .tap(console.log)
+ return automate(eventName, cookies)
.return(cookies)
}
+ // set:cookies will clear cookies first in browsers that use CDP. this is the
+ // same as set:cookies in Firefox, but will only add cookies and not clear
+ // them in Chrome, etc.
+ addCookies (
+ cookies: AutomationCookie[],
+ automate: (eventName: string, cookies: AutomationCookie[]) => Bluebird.Promise,
+ ) {
+ return this.setCookies(cookies, automate, 'add:cookies')
+ }
+
clearCookie (data, automate) {
this.throwIfNamespaced(data)
debug('clear:cookie %o', data)
diff --git a/packages/server/lib/browsers/cdp_automation.ts b/packages/server/lib/browsers/cdp_automation.ts
index a649583c586a..7d96704741db 100644
--- a/packages/server/lib/browsers/cdp_automation.ts
+++ b/packages/server/lib/browsers/cdp_automation.ts
@@ -202,6 +202,15 @@ export class CdpAutomation {
// in Firefox, the hash is incorrectly included in the URL: https://bugzilla.mozilla.org/show_bug.cgi?id=1715366
if (url.includes('#')) url = url.slice(0, url.indexOf('#'))
+ // Filter out "data:" urls from being cached - fixes: https://github.com/cypress-io/cypress/issues/17853
+ // Chrome sends `Network.requestWillBeSent` events with data urls which won't actually be fetched
+ // Example data url: "data:font/woff;base64,"
+ if (url.startsWith('data:')) {
+ debugVerbose('skipping `data:` url %s', url)
+
+ return
+ }
+
// Firefox: https://searchfox.org/mozilla-central/rev/98a9257ca2847fad9a19631ac76199474516b31e/remote/cdp/domains/parent/Network.jsm#397
// Firefox lacks support for urlFragment and initiator, two nice-to-haves
const browserPreRequest: BrowserPreRequest = {
@@ -300,6 +309,11 @@ export class CdpAutomation {
return this.getCookie(data)
})
+ case 'add:cookies':
+ setCookie = data.map((cookie) => normalizeSetCookieProps(cookie)) as Protocol.Network.SetCookieRequest[]
+
+ return this.sendDebuggerCommandFn('Network.setCookies', { cookies: setCookie })
+
case 'set:cookies':
setCookie = data.map((cookie) => normalizeSetCookieProps(cookie))
diff --git a/packages/server/lib/browsers/utils.ts b/packages/server/lib/browsers/utils.ts
index d84850cd9edd..41369fc14c04 100644
--- a/packages/server/lib/browsers/utils.ts
+++ b/packages/server/lib/browsers/utils.ts
@@ -3,8 +3,7 @@ import Bluebird from 'bluebird'
import _ from 'lodash'
import type { FoundBrowser } from '@packages/types'
import * as errors from '../errors'
-// @ts-ignore
-import plugins from '../plugins'
+import * as plugins from '../plugins'
import { getError } from '@packages/errors'
const path = require('path')
diff --git a/packages/server/lib/cache.js b/packages/server/lib/cache.js
index f714c591a2e3..c1dbe1f79098 100644
--- a/packages/server/lib/cache.js
+++ b/packages/server/lib/cache.js
@@ -84,6 +84,9 @@ module.exports = {
return tx.set({ PROJECTS: projects })
},
+ /**
+ * @return {Promise}
+ */
getProjectRoots () {
return fileUtil.transaction((tx) => {
return this._getProjects(tx).then((projects) => {
diff --git a/packages/server/lib/cookie-jar.ts b/packages/server/lib/cookie-jar.ts
new file mode 100644
index 000000000000..70631035135a
--- /dev/null
+++ b/packages/server/lib/cookie-jar.ts
@@ -0,0 +1,67 @@
+import { Cookie, CookieJar as ToughCookieJar } from 'tough-cookie'
+
+export { Cookie }
+
+interface CookieData {
+ name: string
+ domain: string
+ path?: string
+}
+
+/**
+ * An adapter for tough-cookie's CookieJar
+ * Holds onto cookies captured via the proxy, so they can be applied to
+ * requests as needed for the sake of cross-origin testing
+ */
+export class CookieJar {
+ _cookieJar: ToughCookieJar
+
+ static parse (cookie) {
+ return Cookie.parse(cookie)
+ }
+
+ constructor () {
+ this._cookieJar = new ToughCookieJar(undefined, { allowSpecialUseDomain: true })
+ }
+
+ getCookies (url, sameSiteContext) {
+ // @ts-ignore
+ return this._cookieJar.getCookiesSync(url, { sameSiteContext })
+ }
+
+ getAllCookies () {
+ let cookies: Cookie[] = []
+
+ // have to use the internal memstore. looks like an async api, but
+ // it's actually synchronous
+ // @ts-ignore
+ this._cookieJar.store.getAllCookies((_err, _cookies: Cookie[]) => {
+ cookies = _cookies
+ })
+
+ return cookies
+ }
+
+ setCookie (cookie: string | Cookie, url: string, sameSiteContext: 'strict' | 'lax' | 'none') {
+ // @ts-ignore
+ this._cookieJar.setCookieSync(cookie, url, { sameSiteContext })
+ }
+
+ removeCookie (cookieData: CookieData) {
+ // have to use the internal memstore. looks like an async api, but
+ // it's actually synchronous
+ // @ts-ignore
+ this._cookieJar.store.removeCookie(
+ cookieData.domain,
+ cookieData.path || '/',
+ cookieData.name,
+ () => {},
+ )
+ }
+
+ removeAllCookies () {
+ this._cookieJar.removeAllCookiesSync()
+ }
+}
+
+export const cookieJar = new CookieJar()
diff --git a/packages/server/lib/gui/auth.ts b/packages/server/lib/gui/auth.ts
index fc0c890ef1ba..bdd2b3d90bac 100644
--- a/packages/server/lib/gui/auth.ts
+++ b/packages/server/lib/gui/auth.ts
@@ -24,7 +24,7 @@ const buildLoginRedirectUrl = (server) => {
return `http://127.0.0.1:${port}/redirect-to-auth`
}
-const buildFullLoginUrl = (baseLoginUrl, server, utmCode) => {
+const buildFullLoginUrl = (baseLoginUrl, server, utmSource, utmMedium) => {
const { port } = server.address()
if (!authState) {
@@ -43,10 +43,10 @@ const buildFullLoginUrl = (baseLoginUrl, server, utmCode) => {
platform: os.platform(),
}
- if (utmCode) {
+ if (utmMedium) {
authUrl.query = {
- utm_source: 'Test Runner',
- utm_medium: utmCode,
+ utm_source: utmSource,
+ utm_medium: utmMedium,
utm_campaign: 'Log In',
...authUrl.query,
}
@@ -65,7 +65,7 @@ const getOriginFromUrl = (originalUrl) => {
/**
* @returns the currently running auth server instance, launches one if there is not one
*/
-const launchServer = (baseLoginUrl, sendMessage, utmCode) => {
+const launchServer = (baseLoginUrl, sendMessage, utmSource, utmMedium) => {
if (!server) {
// launch an express server to listen for the auth callback from dashboard
const origin = getOriginFromUrl(baseLoginUrl)
@@ -76,7 +76,7 @@ const launchServer = (baseLoginUrl, sendMessage, utmCode) => {
app.get('/redirect-to-auth', (req, res) => {
authRedirectReached = true
- buildFullLoginUrl(baseLoginUrl, server, utmCode)
+ buildFullLoginUrl(baseLoginUrl, server, utmSource, utmMedium)
.then((fullLoginUrl) => {
debug('Received GET to /redirect-to-auth, redirecting: %o', { fullLoginUrl })
@@ -187,7 +187,7 @@ const _internal = {
/**
* @returns a promise that is resolved with a user when auth is complete or rejected when it fails
*/
-const start = (onMessage, utmCode) => {
+const start = (onMessage, utmSource, utmMedium) => {
function sendMessage (name, message) {
onMessage({
name,
@@ -199,7 +199,7 @@ const start = (onMessage, utmCode) => {
return user.getBaseLoginUrl()
.then((baseLoginUrl) => {
- return _internal.launchServer(baseLoginUrl, sendMessage, utmCode)
+ return _internal.launchServer(baseLoginUrl, sendMessage, utmSource, utmMedium)
})
.then(() => {
return _internal.buildLoginRedirectUrl(server)
diff --git a/packages/server/lib/makeDataContext.ts b/packages/server/lib/makeDataContext.ts
index cd076808f163..ec663552ea1e 100644
--- a/packages/server/lib/makeDataContext.ts
+++ b/packages/server/lib/makeDataContext.ts
@@ -2,6 +2,7 @@ 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'
@@ -73,8 +74,8 @@ export function makeDataContext (options: MakeDataContextOptions): DataContext {
getUser () {
return user.get()
},
- logIn (onMessage, utmCode) {
- return auth.start(onMessage, utmCode)
+ logIn (onMessage, utmSource, utmMedium) {
+ return auth.start(onMessage, utmSource, utmMedium)
},
logOut () {
return user.logOut()
@@ -93,8 +94,15 @@ export function makeDataContext (options: MakeDataContextOptions): DataContext {
insertProjectToCache (projectRoot: string) {
return cache.insertProject(projectRoot)
},
- getProjectRootsFromCache () {
- return cache.getProjectRoots()
+ async getProjectRootsFromCache () {
+ return cache.getProjectRoots().then((roots) => {
+ return Promise.all(roots.map(async (projectRoot: string) => {
+ return {
+ projectRoot,
+ savedState: () => savedState.create(projectRoot).then((s) => s.get()),
+ }
+ }))
+ })
},
clearLatestProjectsCache () {
return cache.removeLatestProjects()
@@ -146,6 +154,9 @@ export function makeDataContext (options: MakeDataContextOptions): DataContext {
},
})
},
+ makeProjectSavedState (projectRoot: string) {
+ return () => savedState.create(projectRoot).then((s) => s.get())
+ },
getDevServer () {
return devServer
},
diff --git a/packages/server/lib/open_project.ts b/packages/server/lib/open_project.ts
index 0a856c1dc953..1cd7bf3c564a 100644
--- a/packages/server/lib/open_project.ts
+++ b/packages/server/lib/open_project.ts
@@ -10,6 +10,7 @@ import * as errors from './errors'
import preprocessor from './plugins/preprocessor'
import runEvents from './plugins/run_events'
import * as session from './session'
+import { cookieJar } from './cookie-jar'
import { getSpecUrl } from './project_utils'
import type { LaunchOpts, OpenProjectLaunchOptions, InitializeProjectOptions } from '@packages/types'
import { DataContext, getCtx } from '@packages/data-context'
@@ -165,7 +166,8 @@ export class OpenProject {
return runEvents.execute('before:spec', cfg, spec)
}
- // clear all session data before each spec
+ // clear cookies and all session data before each spec
+ cookieJar.removeAllCookies()
session.clearSessions()
})
.then(() => {
diff --git a/packages/server/lib/plugins/index.js b/packages/server/lib/plugins/index.js
deleted file mode 100644
index f0fc85b06ad2..000000000000
--- a/packages/server/lib/plugins/index.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const { getCtx, registerServerPluginHandler, getServerPluginHandlers: getPluginHandlers } = require('@packages/data-context')
-
-const registerEvent = (event, callback) => {
- getCtx().lifecycleManager.registerEvent(event, callback)
-}
-
-const getPluginPid = () => {
- return getCtx().lifecycleManager.eventProcessPid
-}
-
-const registerHandler = (handler) => {
- registerServerPluginHandler(handler)
-}
-
-const getServerPluginHandlers = () => {
- return getPluginHandlers()
-}
-
-const has = (event) => {
- return getCtx().lifecycleManager.hasNodeEvent(event)
-}
-
-const execute = (event, ...args) => {
- return getCtx().lifecycleManager.executeNodeEvent(event, args)
-}
-
-const _reset = () => {
- return getCtx().lifecycleManager.reinitializeCypress()
-}
-
-module.exports = {
- getPluginPid,
- execute,
- has,
- registerEvent,
- registerHandler,
- getServerPluginHandlers,
-
- // for testing purposes
- _reset,
-}
diff --git a/packages/server/lib/plugins/index.ts b/packages/server/lib/plugins/index.ts
new file mode 100644
index 000000000000..007ea9d79357
--- /dev/null
+++ b/packages/server/lib/plugins/index.ts
@@ -0,0 +1,28 @@
+import {
+ getCtx, registerServerPluginHandler,
+} from '@packages/data-context'
+
+export const registerEvent = (event, callback) => {
+ getCtx().lifecycleManager.registerEvent(event, callback)
+}
+
+export const getPluginPid = () => {
+ return getCtx().lifecycleManager.eventProcessPid
+}
+
+export const registerHandler = (handler) => {
+ registerServerPluginHandler(handler)
+}
+
+export const has = (event) => {
+ return getCtx().lifecycleManager.hasNodeEvent(event)
+}
+
+export const execute = (event, ...args) => {
+ return getCtx().lifecycleManager.executeNodeEvent(event, args)
+}
+
+// for testing purposes
+export const _reset = () => {
+ return getCtx().lifecycleManager.reinitializeCypress()
+}
diff --git a/packages/server/lib/project-base.ts b/packages/server/lib/project-base.ts
index bef0facde13e..e8df3ca4bb36 100644
--- a/packages/server/lib/project-base.ts
+++ b/packages/server/lib/project-base.ts
@@ -25,6 +25,7 @@ import { DataContext, getCtx } from '@packages/data-context'
import { createHmac } from 'crypto'
export interface Cfg extends ReceivedCypressOptions {
+ projectId?: string
projectRoot: string
proxyServer?: Cypress.RuntimeConfigOptions['proxyUrl']
testingType: TestingType
@@ -160,6 +161,7 @@ export class ProjectBase extends EE {
const [port, warning] = await this._server.open(cfg, {
getCurrentBrowser: () => this.browser,
+ getAutomation: () => this.automation,
getSpec: () => this.spec,
exit: this.options.args?.exit,
onError: this.options.onError,
@@ -197,8 +199,10 @@ export class ProjectBase extends EE {
// save the last time they opened the project
// along with the first time they opened it
const now = Date.now()
+
const stateToSave = {
lastOpened: now,
+ lastProjectId: cfg.projectId ?? null,
} as any
if (!cfg.state || !cfg.state.firstOpened) {
diff --git a/packages/server/lib/saved_state.ts b/packages/server/lib/saved_state.ts
index b10cb049ed94..3ee675e2c46b 100644
--- a/packages/server/lib/saved_state.ts
+++ b/packages/server/lib/saved_state.ts
@@ -7,6 +7,7 @@ import cwd from './cwd'
import FileUtil from './util/file'
import { fs } from './util/fs'
import { AllowedState, allowedKeys } from '@packages/types'
+import { globalPubSub } from '@packages/data-context'
const debug = Debug('cypress:server:saved_state')
@@ -83,7 +84,7 @@ const normalizeAndAllowSet = (set, key, value) => {
if (invalidKeys.length) {
// eslint-disable-next-line no-console
- console.error(`WARNING: attempted to save state for non-allowed key(s): ${invalidKeys.join(', ')}. All keys must be allowed in server/lib/saved_state.js`)
+ console.error(`WARNING: attempted to save state for non-allowed key(s): ${invalidKeys.join(', ')}. All keys must be allowed in server/lib/saved_state.ts`)
}
return set(_.pick(valueObject, allowedKeys))
@@ -115,6 +116,10 @@ export const create = (projectRoot?: string, isTextTerminal: boolean = false): B
path: fullStatePath,
})
+ globalPubSub.on('test:cleanup', () => {
+ stateFile.__resetForTest()
+ })
+
stateFile.set = _.wrap(stateFile.set.bind(stateFile), normalizeAndAllowSet)
stateFiles[fullStatePath] = stateFile
diff --git a/packages/server/lib/server-base.ts b/packages/server/lib/server-base.ts
index 779a3a450bfc..4c2fa9ec49e4 100644
--- a/packages/server/lib/server-base.ts
+++ b/packages/server/lib/server-base.ts
@@ -32,6 +32,9 @@ import { createRoutesCT } from './routes-ct'
import type { FoundSpec } from '@packages/types'
import type { Server as WebSocketServer } from 'ws'
import { RemoteStates } from './remote_states'
+import { cookieJar } from './cookie-jar'
+import type { Automation } from './automation/automation'
+import type { AutomationCookie } from './automation/cookies'
const debug = Debug('cypress:server:server-base')
@@ -99,6 +102,7 @@ export interface OpenServerOptions {
onWarning: any
exit?: boolean
getCurrentBrowser: () => Browser
+ getAutomation: () => Automation
getSpec: () => FoundSpec | null
shouldCorrelatePreRequests: () => boolean
}
@@ -176,6 +180,14 @@ export abstract class ServerBase {
this.socket.toDriver('cross:origin:delaying:html', request)
})
+
+ this._eventBus.on('cross:origin:automation:cookies', (cookies: AutomationCookie[]) => {
+ this.socket.localBus.once('cross:origin:automation:cookies:received', () => {
+ this._eventBus.emit('cross:origin:automation:cookies:received')
+ })
+
+ this.socket.toDriver('cross:origin:automation:cookies', cookies)
+ })
}
abstract createServer (
@@ -186,6 +198,7 @@ export abstract class ServerBase {
open (config: Cfg, {
getSpec,
+ getAutomation,
getCurrentBrowser,
onError,
onWarning,
@@ -212,7 +225,7 @@ export abstract class ServerBase {
clientCertificates.loadClientCertificateConfig(config)
- this.createNetworkProxy({ config, getCurrentBrowser, remoteStates: this._remoteStates, shouldCorrelatePreRequests })
+ this.createNetworkProxy({ config, getAutomation, remoteStates: this._remoteStates, shouldCorrelatePreRequests })
if (config.experimentalSourceRewriting) {
createInitialWorkers()
@@ -305,7 +318,7 @@ export abstract class ServerBase {
return e
}
- createNetworkProxy ({ config, getCurrentBrowser, remoteStates, shouldCorrelatePreRequests }) {
+ createNetworkProxy ({ config, getAutomation, remoteStates, shouldCorrelatePreRequests }) {
const getFileServerToken = () => {
return this._fileServer.token
}
@@ -315,9 +328,10 @@ export abstract class ServerBase {
this._networkProxy = new NetworkProxy({
config,
shouldCorrelatePreRequests,
- getCurrentBrowser,
+ getAutomation,
remoteStates,
getFileServerToken,
+ getCookieJar: () => cookieJar,
socket: this.socket,
netStubbingState: this.netStubbingState,
request: this.request,
diff --git a/packages/server/lib/socket-base.ts b/packages/server/lib/socket-base.ts
index 596b8417003c..259d8b579df0 100644
--- a/packages/server/lib/socket-base.ts
+++ b/packages/server/lib/socket-base.ts
@@ -16,6 +16,7 @@ import { openFile, OpenFileDetails } from './util/file-opener'
import open from './util/open'
import type { DestroyableHttpServer } from './util/server_destroy'
import * as session from './session'
+import { cookieJar } from './cookie-jar'
// eslint-disable-next-line no-duplicate-imports
import type { Socket } from '@packages/socket'
import path from 'path'
@@ -457,6 +458,7 @@ export class SocketBase {
case 'get:session':
return session.getSession(args[0])
case 'reset:session:state':
+ cookieJar.removeAllCookies()
session.clearSessions()
resetRenderedHTMLOrigins()
@@ -474,6 +476,8 @@ export class SocketBase {
return this.localBus.emit('cross:origin:release:html')
case 'cross:origin:finished':
return this.localBus.emit('cross:origin:finished', args[0])
+ case 'cross:origin:automation:cookies:received':
+ return this.localBus.emit('cross:origin:automation:cookies:received')
default:
throw new Error(
`You requested a backend event we cannot handle: ${eventName}`,
diff --git a/packages/server/lib/util/process_profiler.ts b/packages/server/lib/util/process_profiler.ts
index 505825f21b58..01563aeb28e5 100644
--- a/packages/server/lib/util/process_profiler.ts
+++ b/packages/server/lib/util/process_profiler.ts
@@ -64,16 +64,16 @@ export const _groupCyProcesses = ({ list }: si.Systeminformation.ProcessesData)
// is this the renderer for the launchpad?
const isDesktopGuiProcess = (proc: Process): boolean => {
- return proc.params.includes('--type=renderer')
+ return proc.params?.includes('--type=renderer')
&& !isBrowserProcess(proc)
}
- // these processes may be shared between the AUT and launchpad
+ // these processes may be shared between the AUT and launchpad.
// rather than treat them as part of the `browser` in `run` mode and have
// their usage in `open` mode be ambiguous, just put them in their own group
const isElectronSharedProcess = (proc: Process): boolean => {
const isType = (type) => {
- return proc.params.includes(`--type=${type}`)
+ return proc.params?.includes(`--type=${type}`)
}
return isType('broker')
@@ -208,7 +208,7 @@ export const _aggregateGroups = (processes: Process[]) => {
export const _printGroupedProcesses = (groupTotals) => {
const consoleBuffer = concatStream((buf) => {
// get rid of trailing newline
- debugVerbose(String(buf).trim())
+ debug(String(buf).trim())
})
// eslint-disable-next-line no-console
diff --git a/packages/server/test/integration/cli_spec.js b/packages/server/test/integration/cli_spec.js
index 44a2fb739075..49386a80f7bd 100644
--- a/packages/server/test/integration/cli_spec.js
+++ b/packages/server/test/integration/cli_spec.js
@@ -44,8 +44,8 @@ describe('CLI Interface', () => {
})
})
- // TODO:(tgriesser) originally skipped this, not sure why
- it.skip('writes out package.json and exits', (done) => {
+ // This fails on MacOS due to an apparent limit on the buffer size of stdout
+ it('writes out package.json and exits', (done) => {
return cp.exec('npm run dev -- --return-pkg', { env }, (err, stdout, stderr) => {
if (err) {
done(err)
@@ -96,8 +96,17 @@ describe('CLI Interface', () => {
describe('through NPM script', () => {
let npmVersion = null
- const isNpmSlurpingCode = () => {
- return semver.lt(npmVersion, '4.0.0')
+ /**
+ * In certain versions of npm, code with an exit code of 10 (Internal Runtime Javascript Failure)
+ * is ultimately displayed as an exit code of 1 (Uncaught Runtime Exception).
+ * This seems to occur before Node 7 / NPM 4 and after Node 14/ NPM 7.
+ * Please see https://github.com/arzzen/all-exit-error-codes/blob/master/programming-languages/javascript/nodejs.md
+ * for more details.
+ *
+ * @returns {boolean}
+ */
+ const doesNpmObscureInternalExitCode = () => {
+ return semver.lt(npmVersion, '4.0.0') || semver.gt(npmVersion, '6.0.0')
}
beforeEach(() => {
@@ -111,7 +120,7 @@ describe('CLI Interface', () => {
})
it('npm slurps up or not exit value on failure', (done) => {
- const expectedCode = isNpmSlurpingCode() ? 1 : 10
+ const expectedCode = doesNpmObscureInternalExitCode() ? 1 : 10
const s = cp.exec('npm run dev -- --exit-with-code=10')
return s.on('close', (code) => {
diff --git a/packages/server/test/integration/cypress_spec.js b/packages/server/test/integration/cypress_spec.js
index cd91c0b27b19..c879bcaddc0b 100644
--- a/packages/server/test/integration/cypress_spec.js
+++ b/packages/server/test/integration/cypress_spec.js
@@ -473,33 +473,6 @@ describe('lib/cypress', () => {
})
})
- // NOTE: Removal of fixtures is not supported in new flow
- it.skip('removes fixtures when they exist and fixturesFolder is false', function (done) {
- ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.idsPath)
-
- ctx.lifecycleManager.getFullInitialConfig()
- .then((cfg) => {
- this.cfg = cfg
-
- return fs.statAsync(this.cfg.fixturesFolder)
- }).then(() => {
- return settings.read(this.idsPath)
- }).then((json) => {
- json.fixturesFolder = false
-
- return settings.writeForTesting(this.idsPath, json)
- }).then(() => {
- return cypress.start([`--run-project=${this.idsPath}`])
- }).then(() => {
- return fs.statAsync(this.cfg.fixturesFolder)
- .then(() => {
- throw new Error('fixturesFolder should not exist!')
- }).catch(() => {
- return done()
- })
- })
- })
-
it('runs project headlessly and displays gui', function () {
return cypress.start([`--run-project=${this.todosPath}`, '--headed'])
.then(() => {
@@ -727,13 +700,12 @@ describe('lib/cypress', () => {
})
})
- // TODO: test this
- it.skip('logs error and exits when project has cypress.config.js syntax error', function () {
+ it('logs error and exits when project has cypress.config.js syntax error', function () {
return fs.writeFileAsync(`${this.todosPath}/cypress.config.js`, `module.exports = {`)
.then(() => {
return cypress.start([`--run-project=${this.todosPath}`])
}).then(() => {
- this.expectExitWithErr('ERROR_READING_FILE', this.todosPath)
+ this.expectExitWithErr('CONFIG_FILE_REQUIRE_ERROR', this.todosPath)
})
})
@@ -1143,8 +1115,7 @@ describe('lib/cypress', () => {
})
describe('--config-file', () => {
- // TODO: fix
- it.skip(`with a custom config file fails when it doesn't exist`, function () {
+ it(`with a custom config file fails when it doesn't exist`, function () {
this.filename = 'abcdefgh.test.js'
return fs.statAsync(path.join(this.todosPath, this.filename))
@@ -1729,61 +1700,6 @@ describe('lib/cypress', () => {
})
})
})
-
- // NOTE: skipped because we want to ensure this is captured in v10
- it.skip('sends warning when baseUrl cannot be verified', function () {
- const bus = new EE()
- const event = { sender: { send: sinon.stub() } }
- const warning = { message: 'Blah blah baseUrl blah blah' }
-
- sinon.stub(ServerE2E.prototype, 'open').resolves([2121, warning])
-
- return cypress.start(['--port=2121', '--config', 'pageLoadTimeout=1000', '--foo=bar', '--env=baz=baz'])
- .then(() => {
- const options = Events.start.firstCall.args[0]
-
- Events.handleEvent(options, bus, event, 123, 'on:project:warning')
-
- return Events.handleEvent(options, bus, event, 123, 'open:project', this.todosPath)
- }).then(() => {
- expect(event.sender.send.withArgs('response').firstCall.args[1].data).to.eql(warning)
- })
- })
-
- describe('--config-file', () => {
- beforeEach(function () {
- this.filename = 'foo.bar.baz.asdf.quux.json'
- this.open = sinon.stub(ServerE2E.prototype, 'open').resolves([])
- })
-
- // TODO: (tgriesser) needs a system test, the mocking here no longer is correct
- it.skip('reads config from a custom config file', function () {
- const bus = new EE()
-
- return fs.writeJson(path.join(this.pristinePath, this.filename), {
- env: { foo: 'bar' },
- port: 2020,
- }).then(() => {
- return cypress.start([
- `--config-file=${this.filename}`,
- ])
- .then(() => {
- const options = Events.start.firstCall.args[0]
-
- return Events.handleEvent(options, bus, {}, 123, 'open:project', this.pristinePath)
- })
- .then(() => {
- expect(this.open).to.be.called
-
- const cfg = this.open.getCall(0).args[0]
-
- expect(cfg.env.foo).to.equal('bar')
-
- expect(cfg.port).to.equal(2020)
- })
- })
- })
- })
})
context('--cwd', () => {
diff --git a/packages/server/test/unit/browsers/cdp_automation_spec.ts b/packages/server/test/unit/browsers/cdp_automation_spec.ts
index b5bbf18511ee..608726185f68 100644
--- a/packages/server/test/unit/browsers/cdp_automation_spec.ts
+++ b/packages/server/test/unit/browsers/cdp_automation_spec.ts
@@ -71,15 +71,103 @@ context('lib/browsers/cdp_automation', () => {
this.sendDebuggerCommand = sinon.stub()
this.onFn = sinon.stub()
this.sendCloseTargetCommand = sinon.stub()
+ this.automation = {
+ onBrowserPreRequest: sinon.stub(),
+ onRequestEvent: sinon.stub(),
+ }
- this.automation = await CdpAutomation.create(this.sendDebuggerCommand, this.onFn, this.sendCloseTargetCommand, null, false)
+ this.cdpAutomation = await CdpAutomation.create(this.sendDebuggerCommand, this.onFn, this.sendCloseTargetCommand, this.automation, false)
this.sendDebuggerCommand
.throws(new Error('not stubbed'))
.withArgs('Browser.getVersion')
.resolves()
- this.onRequest = this.automation.onRequest
+ this.onRequest = this.cdpAutomation.onRequest
+ })
+
+ describe('.onNetworkRequestWillBeSent', function () {
+ it('triggers onBrowserPreRequest', function () {
+ const browserPreRequest = {
+ requestId: '0',
+ type: 'other',
+ request: {
+ method: 'GET',
+ url: 'https://www.google.com',
+ headers: {},
+ },
+ }
+
+ this.onFn
+ .withArgs('Network.requestWillBeSent')
+ .yield(browserPreRequest)
+
+ expect(this.automation.onBrowserPreRequest).to.have.been.calledWith({
+ requestId: browserPreRequest.requestId,
+ method: browserPreRequest.request.method,
+ url: browserPreRequest.request.url,
+ headers: browserPreRequest.request.headers,
+ resourceType: browserPreRequest.type,
+ originalResourceType: browserPreRequest.type,
+ })
+ })
+
+ it('removes # from a url', function () {
+ const browserPreRequest = {
+ requestId: '0',
+ type: 'other',
+ request: {
+ method: 'GET',
+ url: 'https://www.google.com/foo#',
+ headers: {},
+ },
+ }
+
+ this.onFn
+ .withArgs('Network.requestWillBeSent')
+ .yield(browserPreRequest)
+
+ expect(this.automation.onBrowserPreRequest).to.have.been.calledWith({
+ requestId: browserPreRequest.requestId,
+ method: browserPreRequest.request.method,
+ url: 'https://www.google.com/foo', // we only care about the url
+ headers: browserPreRequest.request.headers,
+ resourceType: browserPreRequest.type,
+ originalResourceType: browserPreRequest.type,
+ })
+ })
+
+ it('ignore events with data urls', function () {
+ this.onFn
+ .withArgs('Network.requestWillBeSent')
+ .yield({ request: { url: 'data:font;base64' } })
+
+ expect(this.automation.onBrowserPreRequest).to.not.be.called
+ })
+ })
+
+ describe('.onResponseReceived', function () {
+ it('triggers onRequestEvent', function () {
+ const browserResponseReceived = {
+ requestId: '0',
+ response: {
+ status: 200,
+ headers: {},
+ },
+ }
+
+ this.onFn
+ .withArgs('Network.responseReceived')
+ .yield(browserResponseReceived)
+
+ expect(this.automation.onRequestEvent).to.have.been.calledWith(
+ 'response:received', {
+ requestId: browserResponseReceived.requestId,
+ status: browserResponseReceived.response.status,
+ headers: browserResponseReceived.response.headers,
+ },
+ )
+ })
})
describe('get:cookies', () => {
diff --git a/packages/server/test/unit/browsers/firefox_spec.ts b/packages/server/test/unit/browsers/firefox_spec.ts
index c07ba6d67cea..c6ebb7e151a1 100644
--- a/packages/server/test/unit/browsers/firefox_spec.ts
+++ b/packages/server/test/unit/browsers/firefox_spec.ts
@@ -279,13 +279,6 @@ describe('lib/browsers/firefox', () => {
})
})
- // TODO: pick open port for debugger
- it.skip('finds remote port for firefox debugger', function () {
- return firefox.open(this.browser, 'http://', this.options, this.automation).then(() => {
- // expect(firefoxUtil.findRemotePort).to.be.called
- })
- })
-
it('sets proxy-related preferences if specified', function () {
this.options.proxyServer = 'http://proxy-server:1234'
diff --git a/packages/server/test/unit/config_spec.js b/packages/server/test/unit/config_spec.js
index 13e9e66c480a..3b1873a019c7 100644
--- a/packages/server/test/unit/config_spec.js
+++ b/packages/server/test/unit/config_spec.js
@@ -11,6 +11,8 @@ 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
@@ -157,18 +159,10 @@ describe('lib/config', () => {
return this.expectValidationPasses()
})
- // NOTE: Validated in real use
- it.skip('validates cypress.config.js', function () {
+ it('validates cypress.config.js', function () {
this.setup({ reporter: 5 })
- return this.expectValidationFails('cypress.config.{js,ts,mjs,cjs}')
- })
-
- // NOTE: Validated in real use
- it.skip('validates cypress.env.json', function () {
- this.setup({}, { reporter: 5 })
-
- return this.expectValidationFails('cypress.env.json')
+ return this.expectValidationFails('Expected reporter to be a string')
})
it('only validates known values', function () {
@@ -577,28 +571,27 @@ describe('lib/config', () => {
})
})
- // TODO:(lachlan): after mega PR
- context.skip('specPattern', () => {
+ context('specPattern', () => {
it('passes if a string', function () {
- this.setup({ e2e: { specPattern: '**/*.coffee' } })
+ this.setup({ e2e: { supportFile: false, specPattern: '**/*.coffee' } })
return this.expectValidationPasses()
})
it('passes if an array of strings', function () {
- this.setup({ e2e: { specPattern: ['**/*.coffee'] } })
+ this.setup({ e2e: { supportFile: false, specPattern: ['**/*.coffee'] } })
return this.expectValidationPasses()
})
it('fails if not a string or array', function () {
- this.setup({ e2e: { specPattern: 42 } })
+ this.setup({ e2e: { supportFile: false, specPattern: 42 } })
return this.expectValidationFails('be a string or an array of strings')
})
it('fails if not an array of strings', function () {
- this.setup({ e2e: { specPattern: [5] } })
+ this.setup({ e2e: { supportFile: false, specPattern: [5] } })
return this.expectValidationFails('be a string or an array of strings')
.then(() => {
@@ -1466,8 +1459,7 @@ describe('lib/config', () => {
expect(warning).to.be.calledWith('FIREFOX_GC_INTERVAL_REMOVED')
})
- // TODO:(lachlan) after mega PR
- describe.skip('.resolved', () => {
+ describe('.resolved', () => {
it('sets reporter and port to cli', () => {
const obj = {
projectRoot: '/foo/bar',
@@ -1483,22 +1475,20 @@ describe('lib/config', () => {
.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' },
- component: { from: 'default', value: {} },
defaultCommandTimeout: { value: 4000, from: 'default' },
downloadsFolder: { value: 'cypress/downloads', from: 'default' },
- e2e: { from: 'default', value: {} },
env: {},
execTimeout: { value: 60000, from: 'default' },
experimentalFetchPolyfill: { value: false, from: 'default' },
experimentalInteractiveRunEvents: { value: false, from: 'default' },
experimentalSessionAndOrigin: { value: false, from: 'default' },
experimentalSourceRewriting: { value: false, from: 'default' },
- experimentalStudio: { value: false, from: 'default' },
fileServerFolder: { value: '', from: 'default' },
fixturesFolder: { value: 'cypress/fixtures', from: 'default' },
hosts: { value: null, from: 'default' },
@@ -1509,6 +1499,7 @@ describe('lib/config', () => {
modifyObstructiveCode: { value: true, 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' },
@@ -1525,7 +1516,6 @@ describe('lib/config', () => {
supportFile: { value: false, from: 'config' },
supportFolder: { value: false, from: 'default' },
taskTimeout: { value: 60000, from: 'default' },
- specPattern: { value: '**/*.*', from: 'default' },
trashAssetsBeforeRuns: { value: true, from: 'default' },
userAgent: { value: null, from: 'default' },
video: { value: true, from: 'default' },
@@ -1570,22 +1560,20 @@ describe('lib/config', () => {
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' },
- component: { from: 'default', value: {} },
clientCertificates: { value: [], from: 'default' },
defaultCommandTimeout: { value: 4000, from: 'default' },
downloadsFolder: { value: 'cypress/downloads', from: 'default' },
- e2e: { from: 'default', value: {} },
execTimeout: { value: 60000, from: 'default' },
experimentalFetchPolyfill: { value: false, from: 'default' },
experimentalInteractiveRunEvents: { value: false, from: 'default' },
experimentalSessionAndOrigin: { value: false, from: 'default' },
experimentalSourceRewriting: { value: false, from: 'default' },
- experimentalStudio: { value: false, from: 'default' },
env: {
foo: {
value: 'foo',
@@ -1618,6 +1606,7 @@ describe('lib/config', () => {
modifyObstructiveCode: { value: true, 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' },
@@ -1634,7 +1623,6 @@ describe('lib/config', () => {
supportFile: { value: false, from: 'config' },
supportFolder: { value: false, from: 'default' },
taskTimeout: { value: 60000, from: 'default' },
- specPattern: { value: '**/*.*', from: 'default' },
trashAssetsBeforeRuns: { value: true, from: 'default' },
userAgent: { value: null, from: 'default' },
video: { value: true, from: 'default' },
@@ -1861,9 +1849,7 @@ describe('lib/config', () => {
})
})
- // TODO: Figure out the behavior on updateWithPluginValues, should we check
- // the config from cfg, or get it from the data-context?
- it.skip('catches browsers=null returned from plugins', () => {
+ it('catches browsers=null returned from plugins', () => {
const browser = {
name: 'fake browser name',
family: 'chromium',
diff --git a/packages/server/test/unit/gui/auth_spec.js b/packages/server/test/unit/gui/auth_spec.js
index e89e80538124..fc1a00deee16 100644
--- a/packages/server/test/unit/gui/auth_spec.js
+++ b/packages/server/test/unit/gui/auth_spec.js
@@ -15,7 +15,7 @@ const RANDOM_STRING = 'a'.repeat(32)
const PORT = 9001
const REDIRECT_URL = `http://127.0.0.1:${PORT}/redirect-to-auth`
const FULL_LOGIN_URL = `https://foo.invalid/login.html?port=${PORT}&state=${RANDOM_STRING}&machineId=abc123&cypressVersion=${pkg.version}&platform=linux`
-const FULL_LOGIN_URL_UTM = `https://foo.invalid/login.html?utm_source=Test%20Runner&utm_medium=GUI%20Tab&utm_campaign=Log%20In&port=${PORT}&state=${RANDOM_STRING}&machineId=abc123&cypressVersion=${pkg.version}&platform=linux`
+const FULL_LOGIN_URL_UTM = `https://foo.invalid/login.html?utm_source=UTM%20Source&utm_medium=UTM%20Medium&utm_campaign=Log%20In&port=${PORT}&state=${RANDOM_STRING}&machineId=abc123&cypressVersion=${pkg.version}&platform=linux`
describe('lib/gui/auth', function () {
beforeEach(() => {
@@ -71,7 +71,7 @@ describe('lib/gui/auth', function () {
})
it('uses utm code to form a trackable URL', function () {
- return auth._internal.buildFullLoginUrl(BASE_URL, this.server, 'GUI Tab')
+ return auth._internal.buildFullLoginUrl(BASE_URL, this.server, 'UTM Source', 'UTM Medium')
.then((url) => {
expect(url).to.eq(FULL_LOGIN_URL_UTM)
})
diff --git a/packages/server/test/unit/gui/events_spec.js b/packages/server/test/unit/gui/events_spec.js
deleted file mode 100644
index feda29ddd36f..000000000000
--- a/packages/server/test/unit/gui/events_spec.js
+++ /dev/null
@@ -1,191 +0,0 @@
-require('../../spec_helper')
-
-const EE = require('events')
-const extension = require('@packages/extension')
-const electron = require('electron')
-const Promise = require('bluebird')
-const chromePolicyCheck = require(`../../../lib/util/chrome_policy_check`)
-const ProjectBase = require(`../../../lib/project-base`).ProjectBase
-const errors = require(`../../../lib/errors`)
-const browsers = require(`../../../lib/browsers`)
-const { openProject } = require('../../../lib/open_project')
-const events = require(`../../../lib/gui/events`)
-
-describe('lib/gui/events', () => {
- beforeEach(function () {
- this.send = sinon.stub()
- this.options = {}
- this.cookies = sinon.stub({
- get () {},
- set () {},
- remove () {},
- })
-
- this.event = {
- sender: {
- send: this.send,
- session: {
- cookies: this.cookies,
- },
- },
- }
-
- this.bus = new EE()
-
- sinon.stub(electron.ipcMain, 'on')
- sinon.stub(electron.ipcMain, 'removeAllListeners')
-
- this.handleEvent = (type, arg, bus = this.bus) => {
- const id = `${type}-${Math.random()}`
-
- return Promise
- .try(() => {
- return events.handleEvent(this.options, bus, this.event, id, type, arg)
- }).return({
- sendCalledWith: (data) => {
- expect(this.send).to.be.calledWith('response', { id, data })
- },
- sendErrCalledWith: (err) => {
- expect(this.send).to.be.calledWith('response', { id, __error: errors.cloneErr(err, { html: true }) })
- },
- })
- }
- })
-
- context('.stop', () => {
- it('calls ipc#removeAllListeners', () => {
- events.stop()
-
- expect(electron.ipcMain.removeAllListeners).to.be.calledOnce
- })
- })
-
- // TODO:(tgriesser) originally skipped this, not sure why
- context.skip('.start', () => {
- it('ipc attaches callback on request', () => {
- sinon.stub(events, 'handleEvent')
-
- events.start({ foo: 'bar' }, {})
-
- expect(electron.ipcMain.on).to.be.calledWith('request')
- })
-
- it('partials in options in request callback', () => {
- electron.ipcMain.on.yields('arg1', 'arg2')
- const handleEvent = sinon.stub(events, 'handleEvent')
-
- events.start({ foo: 'bar' }, {})
-
- expect(handleEvent).to.be.calledWith({ foo: 'bar' }, {}, 'arg1', 'arg2')
- })
- })
-
- context('no ipc event', () => {
- it('throws', function () {
- return this.handleEvent('no:such:event').catch((err) => {
- expect(err.message).to.include('No ipc event registered for: \'no:such:event\'')
- })
- })
- })
-
- context('project events', () => {
- // NOTE: Skipped because we want to take a look and make sure we have the same functionality in v10
- describe.skip('open:project', () => {
- beforeEach(function () {
- sinon.stub(extension, 'setHostAndPath').resolves()
- sinon.stub(browsers, 'getAllBrowsersWith')
- browsers.getAllBrowsersWith.resolves([])
- browsers.getAllBrowsersWith.withArgs('/usr/bin/baz-browser').resolves([{ foo: 'bar' }])
- this.initializeConfig = sinon.stub(ProjectBase.prototype, 'initializeConfig').resolves()
- this.open = sinon.stub(ProjectBase.prototype, 'open').resolves()
- sinon.stub(ProjectBase.prototype, 'close').resolves()
-
- return sinon.stub(ProjectBase.prototype, 'getConfig').resolves({ some: 'config' })
- })
-
- afterEach(() => {
- return openProject.close()
- })
-
- it('open project + returns config', function () {
- return this.handleEvent('open:project', '/_test-output/path/to/project-e2e')
- .then((assert) => {
- expect(this.send.firstCall.args[0]).to.eq('response') // [1].id).to.match(/setup:dashboard:project-/)
- expect(this.send.firstCall.args[1].id).to.match(/open:project-/)
- expect(this.send.firstCall.args[1].data).to.eql({ some: 'config' })
- })
- })
-
- it('catches errors', function () {
- const err = new Error('foo')
-
- this.open.rejects(err)
-
- return this.handleEvent('open:project', '/_test-output/path/to/project-e2e')
- .then((assert) => {
- return assert.sendErrCalledWith(err)
- })
- })
-
- it('calls browsers.getAllBrowsersWith with no args when no browser specified', function () {
- return this.handleEvent('open:project', '/_test-output/path/to/project-e2e').then(() => {
- expect(browsers.getAllBrowsersWith).to.be.calledWith()
- })
- })
-
- it('calls browsers.getAllBrowsersWith with browser when browser specified', function () {
- sinon.stub(openProject, 'create').resolves()
- this.options.browser = '/usr/bin/baz-browser'
-
- return this.handleEvent('open:project', '/_test-output/path/to/project-e2e').then(() => {
- expect(browsers.getAllBrowsersWith).to.be.calledWith(this.options.browser)
-
- expect(openProject.create).to.be.calledWithMatch(
- '/_test-output/path/to/project',
- {
- browser: '/usr/bin/baz-browser',
- config: {
- browsers: [
- {
- foo: 'bar',
- },
- ],
- },
- },
- )
- })
- })
-
- it('attaches warning to Chrome browsers when Chrome policy check fails', function () {
- sinon.stub(openProject, 'create').resolves()
- this.options.browser = '/foo'
-
- browsers.getAllBrowsersWith.withArgs('/foo').resolves([{ family: 'chromium' }, { family: 'some other' }])
-
- sinon.stub(chromePolicyCheck, 'run').callsArgWith(0, new Error)
-
- return this.handleEvent('open:project', '/_test-output/path/to/project-e2e').then(() => {
- expect(browsers.getAllBrowsersWith).to.be.calledWith(this.options.browser)
-
- expect(openProject.create).to.be.calledWithMatch(
- '/_test-output/path/to/project',
- {
- browser: '/foo',
- config: {
- browsers: [
- {
- family: 'chromium',
- warning: 'Cypress detected policy settings on your computer that may cause issues with using this browser. For more information, see https://on.cypress.io/bad-browser-policy',
- },
- {
- family: 'some other',
- },
- ],
- },
- },
- )
- })
- })
- })
- })
-})
diff --git a/packages/server/test/unit/modes/interactive_spec.js b/packages/server/test/unit/modes/interactive_spec.js
index 5aa36d4bbb14..8ba0d32301aa 100644
--- a/packages/server/test/unit/modes/interactive_spec.js
+++ b/packages/server/test/unit/modes/interactive_spec.js
@@ -136,8 +136,7 @@ describe('gui/interactive', () => {
sinon.stub(state, 'get').resolves(this.state)
})
- // TODO: skip
- it.skip('calls Events.start with options, adding env, onFocusTests, and os', () => {
+ it('calls Events.start with options, adding env, onFocusTests, and os', () => {
sinon.stub(os, 'platform').returns('someOs')
const opts = {}
diff --git a/packages/server/test/unit/open_project_spec.js b/packages/server/test/unit/open_project_spec.js
index ad286f237b84..931d3d6c3a35 100644
--- a/packages/server/test/unit/open_project_spec.js
+++ b/packages/server/test/unit/open_project_spec.js
@@ -66,8 +66,7 @@ describe('lib/open_project', () => {
this.browser = { name: 'chrome' }
})
- // NOTE: todo come back to this
- it.skip('tells preprocessor to remove file on browser close', function () {
+ it('tells preprocessor to remove file on browser close', function () {
return openProject.launch(this.browser, this.spec)
.then(() => {
browsers.open.lastCall.args[1].onBrowserClose()
@@ -76,8 +75,7 @@ describe('lib/open_project', () => {
})
})
- // NOTE: todo come back to this
- it.skip('does not tell preprocessor to remove file if no spec', function () {
+ it('does not tell preprocessor to remove file if no spec', function () {
return openProject.launch(this.browser, {})
.then(() => {
browsers.open.lastCall.args[1].onBrowserClose()
diff --git a/packages/server/test/unit/saved_state_spec.js b/packages/server/test/unit/saved_state_spec.js
index efae9fa28b30..808190448785 100644
--- a/packages/server/test/unit/saved_state_spec.js
+++ b/packages/server/test/unit/saved_state_spec.js
@@ -89,7 +89,7 @@ describe('lib/saved_state', () => {
.then((state) => {
return state.set({ foo: 'bar', baz: 'qux' })
}).then(() => {
- expect(console.error).to.be.calledWith('WARNING: attempted to save state for non-allowed key(s): foo, baz. All keys must be allowed in server/lib/saved_state.js')
+ expect(console.error).to.be.calledWith('WARNING: attempted to save state for non-allowed key(s): foo, baz. All keys must be allowed in server/lib/saved_state.ts')
})
})
})
diff --git a/packages/types/src/preferences.ts b/packages/types/src/preferences.ts
index 6278cee0ad8c..8e1db207b335 100644
--- a/packages/types/src/preferences.ts
+++ b/packages/types/src/preferences.ts
@@ -30,6 +30,7 @@ export const allowedKeys: Readonly> = [
'ctSpecListWidth',
'firstOpened',
'lastOpened',
+ 'lastProjectId',
'promptsShown',
'preferredEditorBinary',
'isSideNavigationOpen',
@@ -60,6 +61,7 @@ export type AllowedState = Partial<{
ctReporterWidth: Maybe
ctIsSpecsListOpen: Maybe
ctSpecListWidth: Maybe
+ lastProjectId: Maybe
firstOpened: Maybe
lastOpened: Maybe
promptsShown: Maybe
diff --git a/scripts/gulp/gulpfile.ts b/scripts/gulp/gulpfile.ts
index a15bf7069680..c34855ccb0c2 100644
--- a/scripts/gulp/gulpfile.ts
+++ b/scripts/gulp/gulpfile.ts
@@ -17,7 +17,7 @@ import { makePathMap } from './utils/makePathMap'
import { makePackage } from './tasks/gulpMakePackage'
import { exitAfterAll } from './tasks/gulpRegistry'
import { execSync } from 'child_process'
-import { webpackRunner, webpackRunnerCT } from './tasks/gulpWebpack'
+import { webpackReporter, webpackRunner, webpackRunnerCT } from './tasks/gulpWebpack'
import { e2eTestScaffold, e2eTestScaffoldWatch } from './tasks/gulpE2ETestScaffold'
import dedent from 'dedent'
@@ -58,6 +58,7 @@ gulp.task(
gulp.task(
'dev:watch',
gulp.parallel(
+ webpackReporter,
webpackRunner,
webpackRunnerCT,
gulp.series(
@@ -129,7 +130,6 @@ gulp.task('buildProd',
viteBuildApp,
viteBuildLaunchpad,
),
-
))
gulp.task(
diff --git a/scripts/gulp/tasks/gulpE2ETestScaffold.ts b/scripts/gulp/tasks/gulpE2ETestScaffold.ts
index 35e9ea3913b2..73d9cfa444e2 100644
--- a/scripts/gulp/tasks/gulpE2ETestScaffold.ts
+++ b/scripts/gulp/tasks/gulpE2ETestScaffold.ts
@@ -37,7 +37,7 @@ export async function _e2eTestScaffold (cleanupEmpty = true) {
await fs.writeFile(
OUTPUT_PATH,
`/* eslint-disable */
-// Auto-generated by ${path.basename(__filename)}
+// Auto-generated by ${path.basename(__filename)} (run yarn gulp e2eTestScaffold)
export const fixtureDirs = [
${allDirs
.map((dir) => ` '${path.basename(dir)}'`).join(',\n')}
diff --git a/scripts/gulp/tasks/gulpWebpack.ts b/scripts/gulp/tasks/gulpWebpack.ts
index 9a687d1727f7..6f4a0abb7a27 100644
--- a/scripts/gulp/tasks/gulpWebpack.ts
+++ b/scripts/gulp/tasks/gulpWebpack.ts
@@ -7,6 +7,14 @@ import semver from 'semver'
type Env = typeof process.env
+export function webpackReporter () {
+ return runWebpack({
+ cwd: monorepoPaths.pkgReporter,
+ prefix: 'webpack:reporter',
+ args: ['-w'],
+ })
+}
+
export function webpackRunnerCT () {
return runWebpack({
cwd: monorepoPaths.pkgRunnerCt,
diff --git a/scripts/run-webpack.js b/scripts/run-webpack.js
index 150aca60edd7..1d179c4525e8 100644
--- a/scripts/run-webpack.js
+++ b/scripts/run-webpack.js
@@ -20,4 +20,13 @@ if (process.versions && semver.satisfies(process.versions.node, '>=17.0.0') && s
NODE_OPTIONS = `${NODE_OPTIONS} --openssl-legacy-provider`
}
-cp.execSync(`node ${webpackCli} ${process.argv.slice(2).join(' ')}`, { stdio: 'inherit', env: { ...process.env, NODE_OPTIONS } })
+function buildCommand () {
+ const file = process.argv.slice(2).join(' ') ?? ''
+ let program = `node "${webpackCli}"`
+
+ return file ? `${program } "${file}"` : program
+}
+
+const program = buildCommand()
+
+cp.execSync(program, { stdio: 'inherit', env: { ...process.env, NODE_OPTIONS } })
diff --git a/system-tests/__snapshots__/config_spec.js b/system-tests/__snapshots__/config_spec.js
index d12efa93e073..3b6d8b1393fc 100644
--- a/system-tests/__snapshots__/config_spec.js
+++ b/system-tests/__snapshots__/config_spec.js
@@ -482,3 +482,12 @@ exports['e2e config finds supportFiles in projects containing glob syntax 1'] =
`
+
+exports['e2e config throws an error if cypress.env.json specifies invalid property 1'] = `
+Your configFile at /foo/bar/.projects/invalid-env-file/cypress.env.json set an invalid value:
+
+Expected reporter to be a string.
+
+Instead the value was: 5
+
+`
diff --git a/system-tests/projects/cypress-in-cypress/cypress/e2e/z001.spec.js b/system-tests/projects/cypress-in-cypress/cypress/e2e/z001.spec.js
new file mode 100644
index 000000000000..2fe654da72ca
--- /dev/null
+++ b/system-tests/projects/cypress-in-cypress/cypress/e2e/z001.spec.js
@@ -0,0 +1,9 @@
+describe('Blank Contents', () => {
+ it('renders the blank page', () => {
+ cy.contains('cy.visit()')
+ })
+
+ it('renders the visit failure page', () => {
+ cy.visit('http://localhost:999')
+ })
+})
diff --git a/system-tests/projects/cypress-in-cypress/cypress/e2e/z002.spec.js b/system-tests/projects/cypress-in-cypress/cypress/e2e/z002.spec.js
new file mode 100644
index 000000000000..2fe654da72ca
--- /dev/null
+++ b/system-tests/projects/cypress-in-cypress/cypress/e2e/z002.spec.js
@@ -0,0 +1,9 @@
+describe('Blank Contents', () => {
+ it('renders the blank page', () => {
+ cy.contains('cy.visit()')
+ })
+
+ it('renders the visit failure page', () => {
+ cy.visit('http://localhost:999')
+ })
+})
diff --git a/system-tests/projects/cypress-in-cypress/cypress/e2e/z003.spec.js b/system-tests/projects/cypress-in-cypress/cypress/e2e/z003.spec.js
new file mode 100644
index 000000000000..2fe654da72ca
--- /dev/null
+++ b/system-tests/projects/cypress-in-cypress/cypress/e2e/z003.spec.js
@@ -0,0 +1,9 @@
+describe('Blank Contents', () => {
+ it('renders the blank page', () => {
+ cy.contains('cy.visit()')
+ })
+
+ it('renders the visit failure page', () => {
+ cy.visit('http://localhost:999')
+ })
+})
diff --git a/system-tests/projects/cypress-in-cypress/cypress/e2e/z004.spec.js b/system-tests/projects/cypress-in-cypress/cypress/e2e/z004.spec.js
new file mode 100644
index 000000000000..2fe654da72ca
--- /dev/null
+++ b/system-tests/projects/cypress-in-cypress/cypress/e2e/z004.spec.js
@@ -0,0 +1,9 @@
+describe('Blank Contents', () => {
+ it('renders the blank page', () => {
+ cy.contains('cy.visit()')
+ })
+
+ it('renders the visit failure page', () => {
+ cy.visit('http://localhost:999')
+ })
+})
diff --git a/system-tests/projects/cypress-in-cypress/cypress/e2e/z005.spec.js b/system-tests/projects/cypress-in-cypress/cypress/e2e/z005.spec.js
new file mode 100644
index 000000000000..2fe654da72ca
--- /dev/null
+++ b/system-tests/projects/cypress-in-cypress/cypress/e2e/z005.spec.js
@@ -0,0 +1,9 @@
+describe('Blank Contents', () => {
+ it('renders the blank page', () => {
+ cy.contains('cy.visit()')
+ })
+
+ it('renders the visit failure page', () => {
+ cy.visit('http://localhost:999')
+ })
+})
diff --git a/system-tests/projects/cypress-in-cypress/cypress/e2e/z006.spec.js b/system-tests/projects/cypress-in-cypress/cypress/e2e/z006.spec.js
new file mode 100644
index 000000000000..2fe654da72ca
--- /dev/null
+++ b/system-tests/projects/cypress-in-cypress/cypress/e2e/z006.spec.js
@@ -0,0 +1,9 @@
+describe('Blank Contents', () => {
+ it('renders the blank page', () => {
+ cy.contains('cy.visit()')
+ })
+
+ it('renders the visit failure page', () => {
+ cy.visit('http://localhost:999')
+ })
+})
diff --git a/system-tests/projects/cypress-in-cypress/cypress/e2e/z007.spec.js b/system-tests/projects/cypress-in-cypress/cypress/e2e/z007.spec.js
new file mode 100644
index 000000000000..2fe654da72ca
--- /dev/null
+++ b/system-tests/projects/cypress-in-cypress/cypress/e2e/z007.spec.js
@@ -0,0 +1,9 @@
+describe('Blank Contents', () => {
+ it('renders the blank page', () => {
+ cy.contains('cy.visit()')
+ })
+
+ it('renders the visit failure page', () => {
+ cy.visit('http://localhost:999')
+ })
+})
diff --git a/system-tests/projects/cypress-in-cypress/cypress/e2e/z008.spec.js b/system-tests/projects/cypress-in-cypress/cypress/e2e/z008.spec.js
new file mode 100644
index 000000000000..2fe654da72ca
--- /dev/null
+++ b/system-tests/projects/cypress-in-cypress/cypress/e2e/z008.spec.js
@@ -0,0 +1,9 @@
+describe('Blank Contents', () => {
+ it('renders the blank page', () => {
+ cy.contains('cy.visit()')
+ })
+
+ it('renders the visit failure page', () => {
+ cy.visit('http://localhost:999')
+ })
+})
diff --git a/system-tests/projects/cypress-in-cypress/cypress/e2e/z009.spec.js b/system-tests/projects/cypress-in-cypress/cypress/e2e/z009.spec.js
new file mode 100644
index 000000000000..2fe654da72ca
--- /dev/null
+++ b/system-tests/projects/cypress-in-cypress/cypress/e2e/z009.spec.js
@@ -0,0 +1,9 @@
+describe('Blank Contents', () => {
+ it('renders the blank page', () => {
+ cy.contains('cy.visit()')
+ })
+
+ it('renders the visit failure page', () => {
+ cy.visit('http://localhost:999')
+ })
+})
diff --git a/system-tests/projects/invalid-env-file/cypress.config.js b/system-tests/projects/invalid-env-file/cypress.config.js
new file mode 100644
index 000000000000..54497f5a245b
--- /dev/null
+++ b/system-tests/projects/invalid-env-file/cypress.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ e2e: {},
+}
diff --git a/system-tests/projects/invalid-env-file/cypress.env.json b/system-tests/projects/invalid-env-file/cypress.env.json
new file mode 100644
index 000000000000..7efb8c65fb7d
--- /dev/null
+++ b/system-tests/projects/invalid-env-file/cypress.env.json
@@ -0,0 +1,3 @@
+{
+ "reporter": 5
+}
\ No newline at end of file
diff --git a/system-tests/projects/migration-custom-config-file-root-level/README.md b/system-tests/projects/migration-custom-config-file-root-level spaces/README.md
similarity index 100%
rename from system-tests/projects/migration-custom-config-file-root-level/README.md
rename to system-tests/projects/migration-custom-config-file-root-level spaces/README.md
diff --git a/system-tests/projects/migration-custom-config-file-root-level/customConfig.json b/system-tests/projects/migration-custom-config-file-root-level spaces/customConfig.json
similarity index 100%
rename from system-tests/projects/migration-custom-config-file-root-level/customConfig.json
rename to system-tests/projects/migration-custom-config-file-root-level spaces/customConfig.json
diff --git a/system-tests/projects/migration-custom-config-file-root-level/cypress/integration/foo.spec.js b/system-tests/projects/migration-custom-config-file-root-level spaces/cypress/integration/foo.spec.js
similarity index 100%
rename from system-tests/projects/migration-custom-config-file-root-level/cypress/integration/foo.spec.js
rename to system-tests/projects/migration-custom-config-file-root-level spaces/cypress/integration/foo.spec.js
diff --git a/system-tests/projects/migration-custom-config-file-root-level/cypress/plugins/index.js b/system-tests/projects/migration-custom-config-file-root-level spaces/cypress/plugins/index.js
similarity index 100%
rename from system-tests/projects/migration-custom-config-file-root-level/cypress/plugins/index.js
rename to system-tests/projects/migration-custom-config-file-root-level spaces/cypress/plugins/index.js
diff --git a/system-tests/projects/migration-custom-config-file-root-level/cypress/support/index.ts b/system-tests/projects/migration-custom-config-file-root-level spaces/cypress/support/index.ts
similarity index 100%
rename from system-tests/projects/migration-custom-config-file-root-level/cypress/support/index.ts
rename to system-tests/projects/migration-custom-config-file-root-level spaces/cypress/support/index.ts
diff --git a/system-tests/projects/migration-custom-config-file-root-level/expected-cypress.config.js b/system-tests/projects/migration-custom-config-file-root-level spaces/expected-cypress.config.js
similarity index 100%
rename from system-tests/projects/migration-custom-config-file-root-level/expected-cypress.config.js
rename to system-tests/projects/migration-custom-config-file-root-level spaces/expected-cypress.config.js
diff --git a/system-tests/projects/migration-e2e-plugins-implicit-index-js/README.md b/system-tests/projects/migration-e2e-plugins-implicit-index-js/README.md
new file mode 100644
index 000000000000..0013da82ef8d
--- /dev/null
+++ b/system-tests/projects/migration-e2e-plugins-implicit-index-js/README.md
@@ -0,0 +1,35 @@
+## Migration E2E Plugins Implicit index.js
+
+An e2e project with 1 spec file. The purpose of this project is to cover the case where `cypress.json` has `pluginsFile` configured to specify a folder (containing an `index.js`) instead of a file. Technically, `pluginsFile` should point to a file, but Cypress 9 also supported a folder containing an `index.js` file, too.
+
+Reference issue: https://github.com/cypress-io/cypress/issues/22461
+
+The following migration steps will be used during this migration:
+
+- [x] automatic file rename
+- [ ] manual file rename
+- [x] rename support
+- [x] update config file
+- [ ] setup component testing
+
+## Automatic Migration
+
+| Before | After|
+|---|---|
+| `cypress/integration/foo.spec.js` | `cypress/e2e/foo.cy.js` |
+
+## Manual Files
+
+This step is not used.
+
+## Rename supportFile
+
+The project has a default support file, `cypress/support/index.js`. We can rename it for them to `cypress/support/e2e.js`.
+
+| Before | After|
+|---|---|
+| `cypress/support/index.js` | `cypress/support/e2e.js` |
+
+## Update Config
+
+The expected output is in [`expected-cypress.config.js`](./expected-cypress.config.js).
diff --git a/system-tests/projects/migration-e2e-plugins-implicit-index-js/cypress.json b/system-tests/projects/migration-e2e-plugins-implicit-index-js/cypress.json
new file mode 100644
index 000000000000..8546b92fb9a7
--- /dev/null
+++ b/system-tests/projects/migration-e2e-plugins-implicit-index-js/cypress.json
@@ -0,0 +1,3 @@
+{
+ "pluginsFile": "cypress/plugins"
+}
diff --git a/system-tests/projects/migration-e2e-plugins-implicit-index-js/cypress/integration/foo.spec.js b/system-tests/projects/migration-e2e-plugins-implicit-index-js/cypress/integration/foo.spec.js
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/system-tests/projects/migration-e2e-plugins-implicit-index-js/cypress/plugins/index.js b/system-tests/projects/migration-e2e-plugins-implicit-index-js/cypress/plugins/index.js
new file mode 100644
index 000000000000..2437227e15f9
--- /dev/null
+++ b/system-tests/projects/migration-e2e-plugins-implicit-index-js/cypress/plugins/index.js
@@ -0,0 +1 @@
+module.exports = (on, config) => config
diff --git a/system-tests/projects/migration-e2e-plugins-implicit-index-js/cypress/support/index.js b/system-tests/projects/migration-e2e-plugins-implicit-index-js/cypress/support/index.js
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/system-tests/projects/migration-e2e-plugins-implicit-index-js/expected-cypress.config.js b/system-tests/projects/migration-e2e-plugins-implicit-index-js/expected-cypress.config.js
new file mode 100644
index 000000000000..a7ffe7b0a968
--- /dev/null
+++ b/system-tests/projects/migration-e2e-plugins-implicit-index-js/expected-cypress.config.js
@@ -0,0 +1,11 @@
+const { defineConfig } = require('cypress')
+
+module.exports = defineConfig({
+ e2e: {
+ // We've imported your old cypress plugins here.
+ // You may want to clean this up later by importing these.
+ setupNodeEvents (on, config) {
+ return require('./cypress/plugins')(on, config)
+ },
+ },
+})
diff --git a/system-tests/projects/simple with spaces/cypress.config.js b/system-tests/projects/simple with spaces/cypress.config.js
new file mode 100644
index 000000000000..93b46ace1929
--- /dev/null
+++ b/system-tests/projects/simple with spaces/cypress.config.js
@@ -0,0 +1,8 @@
+module.exports = {
+ e2e: {
+ supportFile: false,
+ setupNodeEvents (on, config) {
+ // implement node event listeners here
+ },
+ },
+}
diff --git a/system-tests/projects/simple with spaces/package.json b/system-tests/projects/simple with spaces/package.json
new file mode 100644
index 000000000000..8a5a20589141
--- /dev/null
+++ b/system-tests/projects/simple with spaces/package.json
@@ -0,0 +1,3 @@
+{
+ "projectFixtureDirectory": "simple_passing"
+}
\ No newline at end of file
diff --git a/system-tests/projects/todos/cypress/support/component-index.html b/system-tests/projects/todos/cypress/support/component-index.html
new file mode 100644
index 000000000000..ac6e79fd83df
--- /dev/null
+++ b/system-tests/projects/todos/cypress/support/component-index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ Components App
+
+
+
+
+
\ No newline at end of file
diff --git a/system-tests/projects/vue3-vite-ts-configured/.vscode/extensions.json b/system-tests/projects/vue3-vite-ts-configured/.vscode/extensions.json
index b338073e1464..a7cea0b06781 100644
--- a/system-tests/projects/vue3-vite-ts-configured/.vscode/extensions.json
+++ b/system-tests/projects/vue3-vite-ts-configured/.vscode/extensions.json
@@ -1,3 +1,3 @@
{
- "recommendations": ["vue.volar"]
+ "recommendations": ["Vue.volar"]
}
diff --git a/system-tests/test/config_spec.js b/system-tests/test/config_spec.js
index 89c2a0380081..9f966a36bd22 100644
--- a/system-tests/test/config_spec.js
+++ b/system-tests/test/config_spec.js
@@ -125,6 +125,16 @@ describe('e2e config', () => {
})
})
+ it('throws an error if cypress.env.json specifies invalid property', async function () {
+ await Fixtures.scaffoldProject('invalid-env-file')
+
+ return systemTests.exec(this, {
+ project: 'invalid-env-file',
+ expectedExitCode: 1,
+ snapshot: true,
+ })
+ })
+
it('throws an error if specPattern is set on the root level', async function () {
await Fixtures.scaffoldProject('invalid-root-level-config')
diff --git a/yarn.lock b/yarn.lock
index 769fa2b0b3d8..0f0a55333435 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -400,10 +400,10 @@
dependencies:
"@types/throttle-debounce" "^2.1.0"
-"@antfu/utils@^0.5.0":
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.5.0.tgz#b3169429997cb87850e543cb74660f9e2fed7efd"
- integrity sha512-MrAQ/MrPSxbh1bBrmwJjORfJymw4IqSHFBXqvxaga3ZdDM+/zokYF8DjyJpSjY2QmpmgQrajDUBJOWrYeARfzA==
+"@antfu/utils@^0.5.0", "@antfu/utils@^0.5.1":
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.5.1.tgz#7eb6764878adb715daff20019e5a15fd63d93342"
+ integrity sha512-8Afo0+xvYe1K8Wm4xHTymfTkpzy36aaqDvhXIayUwl+mecMG9Xzl3XjXa6swG6Bk8FBeQ646RyvmsYt6+2Be9g==
"@ardatan/aggregate-error@0.0.6":
version "0.0.6"
@@ -2840,6 +2840,11 @@
exec-sh "^0.3.2"
minimist "^1.2.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==
+
"@coolaj86/urequest@^1.3.6":
version "1.3.7"
resolved "https://registry.yarnpkg.com/@coolaj86/urequest/-/urequest-1.3.7.tgz#66a1d66378dd6534e9c8e68948bf09acf32bab77"
@@ -2867,6 +2872,16 @@
resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-9.0.1.tgz#c27b391d8457d1e893f1eddeaf5e5412d12ffbb5"
integrity sha512-6It2EVfGskxZCQhuykrfnALg7oVeiI6KclWSmGDqB0AiInVrTGB9Jp9i4/Ad21u9Jde/voVQz6eFX/eSg/UsPA==
+"@cypress-design/css@0.4.1":
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/@cypress-design/css/-/css-0.4.1.tgz#40c73462a1b8a04a2d045cef43d5e2480c3bbf2f"
+ integrity sha512-ycyrNcqm9Cy0+IrhVa7Ef9dSv+B/p69T0Sw6zhLDxHwq4S0YxtFgE4zf8R7O4SbR8vlU/YpV5GSQhaXCFLsQXg==
+ dependencies:
+ "@windicss/plugin-interaction-variants" "^1.0.0"
+ vite-plugin-windicss "^1.8.4"
+ windicss "^3.5.1"
+ windicss-webpack-plugin "^1.6.10"
+
"@cypress/browserify-preprocessor@3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@cypress/browserify-preprocessor/-/browserify-preprocessor-3.0.0.tgz#2d1fa6a96ed7130a1b172c540448a5955cbc1264"
@@ -3465,7 +3480,7 @@
dependencies:
prop-types "^15.8.1"
-"@gar/promisify@^1.0.1":
+"@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==
@@ -3589,6 +3604,18 @@
auto-bind "~4.0.0"
tslib "~2.3.0"
+"@graphql-codegen/typescript-resolvers@^2.6.4":
+ version "2.6.4"
+ resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-resolvers/-/typescript-resolvers-2.6.4.tgz#857e24279603f4e8f7293385a90a1f2498eb672e"
+ integrity sha512-BTV5q9d7V+4mVyYRnE8N7HyArmvDbUEY5JwyV94jhlN0AOq2zKQBrs8MRvx8v1VenjTGV+PlnDpF3aEtQu8o+g==
+ dependencies:
+ "@graphql-codegen/plugin-helpers" "^2.4.0"
+ "@graphql-codegen/typescript" "^2.4.11"
+ "@graphql-codegen/visitor-plugin-common" "2.8.0"
+ "@graphql-tools/utils" "^8.1.1"
+ auto-bind "~4.0.0"
+ tslib "~2.4.0"
+
"@graphql-codegen/typescript-urql-graphcache@2.2.3":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript-urql-graphcache/-/typescript-urql-graphcache-2.2.3.tgz#ec481d29857d764becb9b3c3c4eb4cd061ca8568"
@@ -3600,7 +3627,7 @@
change-case-all "1.0.14"
tslib "~2.3.0"
-"@graphql-codegen/typescript@2.4.2", "@graphql-codegen/typescript@^2.4.2":
+"@graphql-codegen/typescript@2.4.2":
version "2.4.2"
resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-2.4.2.tgz#a239d5fd8f11140d5d4c81cfae7ff02054b724dc"
integrity sha512-8ajWidiFqF1KNAywtb/692SjwTyjzrDHo1sf2Q7Z+rh9qDEIrh83VHB8naT/1CefOvxj3MS6GbcsvJMizaE/AQ==
@@ -3611,6 +3638,17 @@
auto-bind "~4.0.0"
tslib "~2.3.0"
+"@graphql-codegen/typescript@^2.4.11", "@graphql-codegen/typescript@^2.4.2":
+ version "2.4.11"
+ resolved "https://registry.yarnpkg.com/@graphql-codegen/typescript/-/typescript-2.4.11.tgz#b9d8bddaeb79ff4a85e1d0f9c774afba7423177c"
+ integrity sha512-K3oDLPJRH9Wgpg9TOvb7L+xrJZ8HxkIzV2umqGn54c+8DQjvnRFBIYRO0THgUBMnEauE2sEy6RZkGHGfgQUruA==
+ dependencies:
+ "@graphql-codegen/plugin-helpers" "^2.4.0"
+ "@graphql-codegen/schema-ast" "^2.4.1"
+ "@graphql-codegen/visitor-plugin-common" "2.8.0"
+ auto-bind "~4.0.0"
+ tslib "~2.4.0"
+
"@graphql-codegen/visitor-plugin-common@2.5.2":
version "2.5.2"
resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.5.2.tgz#90aa4add41e17bca83f1c7c8ad674f2a06065efd"
@@ -3643,6 +3681,22 @@
parse-filepath "^1.0.2"
tslib "~2.3.0"
+"@graphql-codegen/visitor-plugin-common@2.8.0":
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.8.0.tgz#f1de3bd5ee123e6f72c06423912a3a83a6044938"
+ integrity sha512-29MOaxBog7qaEhmeCzJn2mONSbcA+slCTzHN4nJ3aZl4KrC9V32rXlQpG5x0qHbFQ1LaG1f5gPO83xbiAeMBIw==
+ dependencies:
+ "@graphql-codegen/plugin-helpers" "^2.4.0"
+ "@graphql-tools/optimize" "^1.0.1"
+ "@graphql-tools/relay-operation-optimizer" "^6.3.7"
+ "@graphql-tools/utils" "^8.3.0"
+ auto-bind "~4.0.0"
+ change-case-all "1.0.14"
+ dependency-graph "^0.11.0"
+ graphql-tag "^2.11.0"
+ parse-filepath "^1.0.2"
+ tslib "~2.4.0"
+
"@graphql-tools/apollo-engine-loader@^7.0.5":
version "7.1.0"
resolved "https://registry.yarnpkg.com/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-7.1.0.tgz#12d58a459da976b496c7632bd41b76f3aceed48e"
@@ -4077,15 +4131,6 @@
resolved "https://registry.yarnpkg.com/@headlessui/vue/-/vue-1.4.0.tgz#a4a3f392d6e72923f101e307fcfa6c80c00ea446"
integrity sha512-BBLDciyKiGK03whaSVkUacDY2Cd5AR05JCUPWQLvQ9HtjQc9tv5RyPpcdmoXJa+XWI10e3U1JxL+8FY7kJMcEQ==
-"@iarna/cli@^1.2.0":
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/@iarna/cli/-/cli-1.2.0.tgz#0f7af5e851afe895104583c4ca07377a8094d641"
- integrity sha512-ukITQAqVs2n9HGmn3car/Ir7d3ta650iXhrG7pjr3EWdFmJuuOVWgYsu7ftsSe5VifEFFhjxVuX9+8F7L8hwcA==
- dependencies:
- signal-exit "^3.0.2"
- update-notifier "^2.2.0"
- yargs "^8.0.2"
-
"@iarna/toml@^2.2.5":
version "2.2.5"
resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c"
@@ -4287,6 +4332,11 @@
"@intlify/core-base" "9.2.0-beta.7"
"@intlify/shared" "9.2.0-beta.7"
+"@isaacs/string-locale-compare@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b"
+ integrity sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==
+
"@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"
@@ -5890,10 +5940,76 @@
"@nodelib/fs.scandir" "2.1.4"
fastq "^1.6.0"
+"@npmcli/arborist@^5.0.0", "@npmcli/arborist@^5.0.4":
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/@npmcli/arborist/-/arborist-5.2.1.tgz#4f38187cb694946f551a825df17e6efd565b8946"
+ integrity sha512-DNyTHov3lU7PtCGHABzrPqQOUiBdiYzZ5dLv3D0RD5I9KbmhTLcZI/rv3ddZY0K9vpDE/R+R48b+cU/dUkL0Tw==
+ dependencies:
+ "@isaacs/string-locale-compare" "^1.1.0"
+ "@npmcli/installed-package-contents" "^1.0.7"
+ "@npmcli/map-workspaces" "^2.0.3"
+ "@npmcli/metavuln-calculator" "^3.0.1"
+ "@npmcli/move-file" "^2.0.0"
+ "@npmcli/name-from-folder" "^1.0.1"
+ "@npmcli/node-gyp" "^2.0.0"
+ "@npmcli/package-json" "^2.0.0"
+ "@npmcli/run-script" "^3.0.0"
+ bin-links "^3.0.0"
+ cacache "^16.0.6"
+ common-ancestor-path "^1.0.1"
+ json-parse-even-better-errors "^2.3.1"
+ json-stringify-nice "^1.1.4"
+ mkdirp "^1.0.4"
+ mkdirp-infer-owner "^2.0.0"
+ nopt "^5.0.0"
+ npm-install-checks "^5.0.0"
+ npm-package-arg "^9.0.0"
+ npm-pick-manifest "^7.0.0"
+ npm-registry-fetch "^13.0.0"
+ npmlog "^6.0.2"
+ pacote "^13.0.5"
+ parse-conflict-json "^2.0.1"
+ proc-log "^2.0.0"
+ promise-all-reject-late "^1.0.0"
+ promise-call-limit "^1.0.1"
+ read-package-json-fast "^2.0.2"
+ readdir-scoped-modules "^1.1.0"
+ rimraf "^3.0.2"
+ semver "^7.3.7"
+ ssri "^9.0.0"
+ treeverse "^2.0.0"
+ walk-up-path "^1.0.0"
+
"@npmcli/ci-detect@^1.0.0":
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz#6c1d2c625fb6ef1b9dea85ad0a5afcbef85ef22a"
- integrity sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q==
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.4.0.tgz#18478bbaa900c37bfbd8a2006a6262c62e8b0fe1"
+ integrity sha512-3BGrt6FLjqM6br5AhWRKTr3u5GIVkjRYeAFrMp3HjnfICrg4xOrVRwFavKT6tsp++bq5dluL5t8ME/Nha/6c1Q==
+
+"@npmcli/ci-detect@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-2.0.0.tgz#e63c91bcd4185ac1e85720a34fc48e164ece5b89"
+ integrity sha512-8yQtQ9ArHh/TzdUDKQwEvwCgpDuhSWTDAbiKMl3854PcT+Dk4UmWaiawuFTLy9n5twzXOBXVflWe+90/ffXQrA==
+
+"@npmcli/config@^4.1.0":
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/config/-/config-4.1.0.tgz#5c92e5ded2a44baf76b94926646329c3b39e79b8"
+ integrity sha512-cPQmIQ2Q0vuOfrenrA3isikdMFMAHgzlXV+EmvZ8f2JeJsU5xTU2bG7ipXECiMvPF9nM+QDnMLuIg8QLw9H4xg==
+ dependencies:
+ "@npmcli/map-workspaces" "^2.0.2"
+ ini "^3.0.0"
+ mkdirp-infer-owner "^2.0.0"
+ nopt "^5.0.0"
+ proc-log "^2.0.0"
+ read-package-json-fast "^2.0.3"
+ semver "^7.3.5"
+ walk-up-path "^1.0.0"
+
+"@npmcli/disparity-colors@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/disparity-colors/-/disparity-colors-2.0.0.tgz#cb518166ee21573b96241a3613fef70acb2a60ba"
+ integrity sha512-FFXGrIjhvd2qSZ8iS0yDvbI7nbjdyT2VNO7wotosjYZM2p2r8PN3B7Om3M5NO9KqW/OVzfzLB3L0V5Vo5QXC7A==
+ dependencies:
+ ansi-styles "^4.3.0"
"@npmcli/fs@^1.0.0":
version "1.0.0"
@@ -5903,6 +6019,14 @@
"@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@^2.0.1", "@npmcli/git@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.1.0.tgz#2fbd77e147530247d37f325930d457b3ebe894f6"
@@ -5917,7 +6041,22 @@
semver "^7.3.5"
which "^2.0.2"
-"@npmcli/installed-package-contents@^1.0.5", "@npmcli/installed-package-contents@^1.0.6":
+"@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.5", "@npmcli/installed-package-contents@^1.0.6", "@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==
@@ -5925,6 +6064,26 @@
npm-bundled "^1.1.1"
npm-normalize-package-bin "^1.0.1"
+"@npmcli/map-workspaces@^2.0.2", "@npmcli/map-workspaces@^2.0.3":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-2.0.3.tgz#2d3c75119ee53246e9aa75bc469a55281cd5f08f"
+ integrity sha512-X6suAun5QyupNM8iHkNPh0AHdRC2rb1W+MTdMvvA/2ixgmqZwlq5cGUBgmKHUHT2LgrkKJMAXbfAoTxOigpK8Q==
+ dependencies:
+ "@npmcli/name-from-folder" "^1.0.1"
+ glob "^8.0.1"
+ minimatch "^5.0.1"
+ read-package-json-fast "^2.0.3"
+
+"@npmcli/metavuln-calculator@^3.0.1":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/metavuln-calculator/-/metavuln-calculator-3.1.0.tgz#b1c2f0991c4f2d992b1615a54d4358c05efc3702"
+ integrity sha512-Q5fbQqGDlYqk7kWrbg6E2j/mtqQjZop0ZE6735wYA1tYNHguIDjAuWs+kFb5rJCkLIlXllfapvsyotYKiZOTBA==
+ dependencies:
+ cacache "^16.0.0"
+ json-parse-even-better-errors "^2.3.1"
+ pacote "^13.0.3"
+ semver "^7.3.5"
+
"@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"
@@ -5933,10 +6092,35 @@
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/name-from-folder@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@npmcli/name-from-folder/-/name-from-folder-1.0.1.tgz#77ecd0a4fcb772ba6fe927e2e2e155fbec2e6b1a"
+ integrity sha512-qq3oEfcLFwNfEYOQ8HLimRGKlD8WSeGEdtUa7hmzpR8Sa7haL1KVQrvgO6wqMjhWFFVjgtrh1gIxDz+P8sjUaA==
+
"@npmcli/node-gyp@^1.0.2":
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.2.tgz#3cdc1f30e9736dbc417373ed803b42b1a0a29ede"
- integrity sha512-yrJUe6reVMpktcvagumoqD9r08fH1iRo01gn1u0zoCApa9lnZGEigVKUd2hzsCId4gdtkZZIVscLhNxMECKgRg==
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz#a912e637418ffc5f2db375e93b85837691a43a33"
+ integrity sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA==
+
+"@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/package-json@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-2.0.0.tgz#3bbcf4677e21055adbe673d9f08c9f9cde942e4a"
+ integrity sha512-42jnZ6yl16GzjWSH7vtrmWyJDGVa/LXPdpN2rcUWolFjc9ON2N3uz0qdBbQACfmhuJZ2lbKYtmK5qx68ZPLHMA==
+ dependencies:
+ json-parse-even-better-errors "^2.3.1"
"@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.2":
version "1.3.2"
@@ -5945,6 +6129,13 @@
dependencies:
infer-owner "^1.0.4"
+"@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@^1.3.0":
version "1.8.6"
resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-1.8.6.tgz#18314802a6660b0d4baa4c3afe7f1ad39d8c28b7"
@@ -5965,6 +6156,16 @@
node-gyp "^8.2.0"
read-package-json-fast "^2.0.1"
+"@npmcli/run-script@^3.0.0", "@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"
+
"@octokit/auth-app@3.6.1":
version "3.6.1"
resolved "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-3.6.1.tgz#aa5b02cc211175cbc28ce6c03c73373c1206d632"
@@ -6496,16 +6697,16 @@
fs-extra "^9.0.0"
lodash "^4.17.4"
-"@semantic-release/commit-analyzer@^8.0.0":
- version "8.0.1"
- resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-8.0.1.tgz#5d2a37cd5a3312da0e3ac05b1ca348bf60b90bca"
- integrity sha512-5bJma/oB7B4MtwUkZC2Bf7O1MHfi4gWe4mA+MIQ3lsEV0b422Bvl1z5HRpplDnMLHH3EXMoRdEng6Ds5wUqA3A==
+"@semantic-release/commit-analyzer@^9.0.2":
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-9.0.2.tgz#a78e54f9834193b55f1073fa6258eecc9a545e03"
+ integrity sha512-E+dr6L+xIHZkX4zNMe6Rnwg4YQrWNXK+rNsvwOPpdFppvZO1olE2fIgWhv89TkQErygevbjsZFSIxp+u6w2e5g==
dependencies:
conventional-changelog-angular "^5.0.0"
conventional-commits-filter "^2.0.0"
- conventional-commits-parser "^3.0.7"
+ conventional-commits-parser "^3.2.3"
debug "^4.0.0"
- import-from "^3.0.0"
+ import-from "^4.0.0"
lodash "^4.17.4"
micromatch "^4.0.2"
@@ -6514,6 +6715,11 @@
resolved "https://registry.yarnpkg.com/@semantic-release/error/-/error-2.2.0.tgz#ee9d5a09c9969eade1ec864776aeda5c5cddbbf0"
integrity sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==
+"@semantic-release/error@^3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@semantic-release/error/-/error-3.0.0.tgz#30a3b97bbb5844d695eb22f9d3aa40f6a92770c2"
+ integrity sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==
+
"@semantic-release/git@9.0.0":
version "9.0.0"
resolved "https://registry.yarnpkg.com/@semantic-release/git/-/git-9.0.0.tgz#304c4883c87d095b1faaae93300f1f1e0466e9a5"
@@ -6528,10 +6734,10 @@
micromatch "^4.0.0"
p-reduce "^2.0.0"
-"@semantic-release/github@^7.0.0":
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/@semantic-release/github/-/github-7.2.0.tgz#925f3efd91adabfc4bbe0de24b79fe1a8a38b4e2"
- integrity sha512-tMRnWiiWb43whRHvbDGXq4DGEbKRi56glDpXDJZit4PIiwDPX7Kx3QzmwRtDOcG+8lcpGjpdPabYZ9NBxoI2mw==
+"@semantic-release/github@^8.0.0":
+ version "8.0.4"
+ resolved "https://registry.yarnpkg.com/@semantic-release/github/-/github-8.0.4.tgz#4ea242f6ad10a0474b0fbb09462e10c43518002a"
+ integrity sha512-But4e8oqqP3anZI5tjzZssZc2J6eoUdeeE0s7LVKKwyiAXJiQDWNNvtPOpgG2DsIz4+Exuse7cEQgjGMxwtLmg==
dependencies:
"@octokit/rest" "^18.0.0"
"@semantic-release/error" "^2.2.0"
@@ -6539,49 +6745,49 @@
bottleneck "^2.18.1"
debug "^4.0.0"
dir-glob "^3.0.0"
- fs-extra "^9.0.0"
+ fs-extra "^10.0.0"
globby "^11.0.0"
- http-proxy-agent "^4.0.0"
+ http-proxy-agent "^5.0.0"
https-proxy-agent "^5.0.0"
issue-parser "^6.0.0"
lodash "^4.17.4"
- mime "^2.4.3"
+ mime "^3.0.0"
p-filter "^2.0.0"
p-retry "^4.0.0"
url-join "^4.0.0"
-"@semantic-release/npm@^7.0.0":
- version "7.0.10"
- resolved "https://registry.yarnpkg.com/@semantic-release/npm/-/npm-7.0.10.tgz#85e5b201e71896ecc3f45d7a496f5485f97df0b8"
- integrity sha512-DXFEhgSt5u22imTWbw8wfcVGB90nFJNcjUBtJI3zswJojzZ7yXpY4i2Va5RBRQRTtj00BfG0stbilAtKrKp35g==
+"@semantic-release/npm@^9.0.0":
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/@semantic-release/npm/-/npm-9.0.1.tgz#d81828eb1fb771e2767b3a8ee989915e1af27075"
+ integrity sha512-I5nVZklxBzfMFwemhRNbSrkiN/dsH3c7K9+KSk6jUnq0rdLFUuJt7EBsysq4Ir3moajQgFkfEryEHPqiKJj20g==
dependencies:
- "@semantic-release/error" "^2.2.0"
+ "@semantic-release/error" "^3.0.0"
aggregate-error "^3.0.0"
execa "^5.0.0"
- fs-extra "^9.0.0"
+ fs-extra "^10.0.0"
lodash "^4.17.15"
nerf-dart "^1.0.0"
- normalize-url "^5.0.0"
- npm "^6.14.9"
+ normalize-url "^6.0.0"
+ npm "^8.3.0"
rc "^1.2.8"
read-pkg "^5.0.0"
registry-auth-token "^4.0.0"
semver "^7.1.2"
tempy "^1.0.0"
-"@semantic-release/release-notes-generator@^9.0.0":
- version "9.0.1"
- resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-9.0.1.tgz#732d285d103064f2a64f08a32031551ebb4f918b"
- integrity sha512-bOoTiH6SiiR0x2uywSNR7uZcRDl22IpZhj+Q5Bn0v+98MFtOMhCxFhbrKQjhbYoZw7vps1mvMRmFkp/g6R9cvQ==
+"@semantic-release/release-notes-generator@^10.0.0":
+ version "10.0.3"
+ resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-10.0.3.tgz#85f7ca78bfa6b01fb5fda0ac48112855d69171dc"
+ integrity sha512-k4x4VhIKneOWoBGHkx0qZogNjCldLPRiAjnIpMnlUh6PtaWXp/T+C9U7/TaNDDtgDa5HMbHl4WlREdxHio6/3w==
dependencies:
conventional-changelog-angular "^5.0.0"
- conventional-changelog-writer "^4.0.0"
+ conventional-changelog-writer "^5.0.0"
conventional-commits-filter "^2.0.0"
- conventional-commits-parser "^3.0.0"
+ conventional-commits-parser "^3.2.3"
debug "^4.0.0"
- get-stream "^5.0.0"
- import-from "^3.0.0"
- into-stream "^5.0.0"
+ get-stream "^6.0.0"
+ import-from "^4.0.0"
+ into-stream "^6.0.0"
lodash "^4.17.4"
read-pkg-up "^7.0.0"
@@ -6856,6 +7062,11 @@
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==
+
"@toycode/markdown-it-class@1.2.3":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@toycode/markdown-it-class/-/markdown-it-class-1.2.3.tgz#272082b46d1242d2607a3aca281aae9d208fc182"
@@ -7287,6 +7498,13 @@
"@types/minimatch" "*"
"@types/node" "*"
+"@types/graphql-resolve-batch@1.1.6":
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/@types/graphql-resolve-batch/-/graphql-resolve-batch-1.1.6.tgz#b53099b57a8b1c02bbb39f3cf7c8f89a6c076d33"
+ integrity sha512-5wnYqk1zkutWyj16Llm8l95Gr2tVsu8PmFwMKmzh3OPm0/Nd02CKYXiZtoLX2Zv4tdkzAsIPOpev8Jk9N9am5Q==
+ dependencies:
+ graphql ">=14"
+
"@types/gulp@^4.0.9":
version "4.0.9"
resolved "https://registry.yarnpkg.com/@types/gulp/-/gulp-4.0.9.tgz#a2f9667bcc26bc72b4899dd16216d6584a12346c"
@@ -8940,16 +9158,16 @@
jiti "^1.10.1"
windicss "^3.1.4"
-"@windicss/config@1.8.2":
- version "1.8.2"
- resolved "https://registry.yarnpkg.com/@windicss/config/-/config-1.8.2.tgz#52f8720a7987184a79d610a151f12a6325c3677e"
- integrity sha512-dGXkzcH1Bnm9716/pE63YSewLQIZXGWerHEotUKf2EMlz/JqsI9Z3yBy/lXVL9HsEoTNpyvMPLk75oquH0vXGg==
+"@windicss/config@1.8.4":
+ version "1.8.4"
+ resolved "https://registry.yarnpkg.com/@windicss/config/-/config-1.8.4.tgz#090c7f48cb86b6cba1bd97742a2f012852026d3c"
+ integrity sha512-i4fFGFfZoRess6WMkauykHC3PFd9xKYVx7lSuLfMK7sgo6x3+l4dY42GbsWMHyLqH1sTMfyt1LgfXSIKYJozSA==
dependencies:
- debug "^4.3.3"
+ debug "^4.3.4"
jiti "^1.13.0"
windicss "^3.5.1"
-"@windicss/plugin-interaction-variants@1.0.0":
+"@windicss/plugin-interaction-variants@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@windicss/plugin-interaction-variants/-/plugin-interaction-variants-1.0.0.tgz#11e412c6fd653899f6cced4e4f7b402eb5456981"
integrity sha512-jk0kvJEwphPlzjgCASxi0yCrLIrMPBHKTjPB1vF2LZsmWVaIPhKQRfpJW6+G093ipDos1E2BkevDrh/R2Ln8gg==
@@ -8967,17 +9185,17 @@
micromatch "^4.0.4"
windicss "^3.1.4"
-"@windicss/plugin-utils@1.8.2", "@windicss/plugin-utils@^1.1.1":
- version "1.8.2"
- resolved "https://registry.yarnpkg.com/@windicss/plugin-utils/-/plugin-utils-1.8.2.tgz#f7c982b01d0ea96cf86585115743c770c6b2cd2e"
- integrity sha512-UlinWxojyGxWV18AyQ1ISeGvtpbw4ITQpcRe0v4PyuJZHwnrrHmxp8o/pg10oEcDKnsTIbjGeZfW5DC+mkjYYQ==
+"@windicss/plugin-utils@1.8.4", "@windicss/plugin-utils@^1.1.1", "@windicss/plugin-utils@^1.8.4":
+ version "1.8.4"
+ resolved "https://registry.yarnpkg.com/@windicss/plugin-utils/-/plugin-utils-1.8.4.tgz#fba74b6eb29276e24b9d09931bc22808fd7230d7"
+ integrity sha512-DqJVwAfzlgd8nYSNlmhXOey32pI8UwH7QiOWdFS/AR2O/q9oLDGHDn97Its/kZdfoyhi8ylwZNP2Pk0H7cihhQ==
dependencies:
- "@antfu/utils" "^0.5.0"
- "@windicss/config" "1.8.2"
- debug "^4.3.3"
+ "@antfu/utils" "^0.5.1"
+ "@windicss/config" "1.8.4"
+ debug "^4.3.4"
fast-glob "^3.2.11"
- magic-string "^0.25.7"
- micromatch "^4.0.4"
+ magic-string "^0.26.1"
+ micromatch "^4.0.5"
windicss "^3.5.1"
"@xtuc/ieee754@^1.2.0":
@@ -9009,7 +9227,7 @@
mkdirp-promise "^5.0.1"
mz "^2.5.0"
-JSONStream@^1.0.3, JSONStream@^1.0.4, JSONStream@^1.3.4, JSONStream@^1.3.5:
+JSONStream@^1.0.3, JSONStream@^1.0.4, JSONStream@^1.3.4:
version "1.3.5"
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==
@@ -9178,7 +9396,7 @@ agentkeepalive@^3.4.1:
dependencies:
humanize-ms "^1.2.1"
-agentkeepalive@^4.1.3:
+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==
@@ -9421,6 +9639,13 @@ ansi-escapes@^4.1.0, ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, ansi-escapes@^4.3
dependencies:
type-fest "^0.21.3"
+ansi-escapes@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-5.0.0.tgz#b6a0caf0eef0c41af190e9a749e0c00ec04bb2a6"
+ integrity sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==
+ dependencies:
+ type-fest "^1.0.2"
+
ansi-gray@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251"
@@ -9489,7 +9714,7 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
-ansi-styles@^4.0.0, ansi-styles@^4.1.0, ansi-styles@^4.2.1:
+ansi-styles@^4.0.0, ansi-styles@^4.1.0, ansi-styles@^4.2.1, ansi-styles@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
@@ -9528,11 +9753,6 @@ ansicolors@~0.3.2:
resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979"
integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=
-ansistyles@~0.1.3:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539"
- integrity sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk=
-
any-base@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe"
@@ -9630,12 +9850,12 @@ append-transform@^2.0.0:
dependencies:
default-require-extensions "^3.0.0"
-aproba@^1.0.3, aproba@^1.1.1, aproba@^1.1.2:
+aproba@^1.0.3, aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
-"aproba@^1.0.3 || ^2.0.0", "aproba@^1.1.2 || 2", aproba@^2.0.0:
+"aproba@^1.0.3 || ^2.0.0", aproba@^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==
@@ -11491,24 +11711,24 @@ bignumber.js@^2.1.0:
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8"
integrity sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg=
-bin-links@^1.1.2, bin-links@^1.1.8:
- version "1.1.8"
- resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.8.tgz#bd39aadab5dc4bdac222a07df5baf1af745b2228"
- integrity sha512-KgmVfx+QqggqP9dA3iIc5pA4T1qEEEL+hOhOhNPaUm77OTrJoOXE/C05SJLNJe6m/2wUK7F1tDSou7n5TfCDzQ==
+bin-links@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-3.0.1.tgz#cc70ffb481988b22c527d3e6e454787876987a49"
+ integrity sha512-9vx+ypzVhASvHTS6K+YSGf7nwQdANoz7v6MTC0aCtYnOEZ87YvMf81aY737EZnGZdpbRM3sfWjO9oWkKmuIvyQ==
dependencies:
- bluebird "^3.5.3"
- cmd-shim "^3.0.0"
- gentle-fs "^2.3.0"
- graceful-fs "^4.1.15"
+ cmd-shim "^5.0.0"
+ mkdirp-infer-owner "^2.0.0"
npm-normalize-package-bin "^1.0.0"
- write-file-atomic "^2.3.0"
+ read-cmd-shim "^3.0.0"
+ rimraf "^3.0.0"
+ write-file-atomic "^4.0.0"
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==
-binary-extensions@^2.0.0:
+binary-extensions@^2.0.0, binary-extensions@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
@@ -11731,7 +11951,7 @@ bowser@^2.11.0:
resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f"
integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==
-boxen@1.3.0, boxen@^1.2.1:
+boxen@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==
@@ -11766,6 +11986,13 @@ brace-expansion@^1.0.0, brace-expansion@^1.1.7:
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@^1.8.2:
version "1.8.5"
resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
@@ -11791,7 +12018,7 @@ braces@^2.3.1, braces@^2.3.2:
split-string "^3.0.2"
to-regex "^3.0.1"
-braces@^3.0.1, braces@~3.0.2:
+braces@^3.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==
@@ -12140,6 +12367,13 @@ builtins@^4.0.0:
dependencies:
semver "^7.0.0"
+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"
+
bundle-require@3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/bundle-require/-/bundle-require-3.0.4.tgz#2b52ba77d99c0a586b5854cd21d36954e63cc110"
@@ -12276,6 +12510,30 @@ cacache@^15.0.5, cacache@^15.2.0:
tar "^6.0.2"
unique-filename "^1.1.1"
+cacache@^16.0.0, cacache@^16.0.6, 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"
+
cache-base@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
@@ -12371,11 +12629,6 @@ call-bind@^1.0.0, call-bind@^1.0.2:
function-bind "^1.1.1"
get-intrinsic "^1.0.2"
-call-limit@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4"
- integrity sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ==
-
call-me-maybe@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
@@ -12523,11 +12776,6 @@ capture-exit@^2.0.0:
dependencies:
rsvp "^4.8.4"
-capture-stack-trace@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d"
- integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==
-
cardinal@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-2.1.1.tgz#7cc1055d822d212954d07b085dea251cc7bc5505"
@@ -12642,13 +12890,10 @@ chai@^4.2.0, chai@^4.3.6:
pathval "^1.1.1"
type-detect "^4.0.5"
-chalk@*, chalk@^4.0.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"
+chalk@*, chalk@^5.0.0:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6"
+ integrity sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==
chalk@1.x.x, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
@@ -12703,6 +12948,14 @@ chalk@4.1.1:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
+chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2:
+ 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"
+
chalk@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
@@ -12929,7 +13182,7 @@ chokidar@^2.0.0, chokidar@^2.0.4, chokidar@^2.1.1, chokidar@^2.1.8:
optionalDependencies:
fsevents "^1.2.7"
-chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.4:
+chownr@^1.1.1, chownr@^1.1.2:
version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
@@ -12976,11 +13229,6 @@ chromium-pickle-js@^0.2.0:
resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205"
integrity sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=
-ci-info@^1.5.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
- integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==
-
ci-info@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
@@ -12991,12 +13239,12 @@ ci-info@^3.2.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2"
integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==
-cidr-regex@^2.0.10:
- version "2.0.10"
- resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-2.0.10.tgz#af13878bd4ad704de77d6dc800799358b3afa70d"
- integrity sha512-sB3ogMQXWvreNPbJUZMRApxuRYd+KoIo4RGQ81VatjmMW6WJPo+IJZ2846FGItr9VzKo5w7DXzijPLGtSd0N3Q==
+cidr-regex@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-3.1.1.tgz#ba1972c57c66f61875f18fd7dd487469770b571d"
+ integrity sha512-RBqYd32aDwbCMFJRL6wHOlDNYJsPNTt8vC82ErHF5vKt8QQzxm1FrkW8s/R5pVrXMf17sba09Uoy91PKiddAsw==
dependencies:
- ip-regex "^2.1.0"
+ ip-regex "^4.1.0"
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
@@ -13075,13 +13323,13 @@ cli-boxes@^2.2.1:
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
-cli-columns@^3.1.2:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-3.1.2.tgz#6732d972979efc2ae444a1f08e08fa139c96a18e"
- integrity sha1-ZzLZcpee/CrkRKHwjgj6E5yWoY4=
+cli-columns@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/cli-columns/-/cli-columns-4.0.0.tgz#9fe4d65975238d55218c41bd2ed296a7fa555646"
+ integrity sha512-XW2Vg+w+L9on9wtwKpyzluIPCWXjaBahI7mTcYjx+BVIYD9c3yqcv/yKC7CmdCZat4rq2yiE1UMSJC5ivKfMtQ==
dependencies:
- string-width "^2.0.0"
- strip-ansi "^3.0.1"
+ string-width "^4.2.3"
+ strip-ansi "^6.0.1"
cli-cursor@^2.0.0, cli-cursor@^2.1.0:
version "2.1.0"
@@ -13114,7 +13362,7 @@ cli-spinners@^2.5.0:
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939"
integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==
-cli-table3@0.5.1, cli-table3@^0.5.0, cli-table3@^0.5.1:
+cli-table3@0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202"
integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==
@@ -13124,21 +13372,14 @@ cli-table3@0.5.1, cli-table3@^0.5.0, cli-table3@^0.5.1:
optionalDependencies:
colors "^1.1.2"
-cli-table3@~0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.1.tgz#36ce9b7af4847f288d3cdd081fbd09bf7bd237b8"
- integrity sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==
+cli-table3@^0.6.1, cli-table3@^0.6.2, 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 "1.4.0"
-
-cli-table@^0.3.1:
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23"
- integrity sha1-9TsFJmqLGguTSz0IIebi3FkUriM=
- dependencies:
- colors "1.0.3"
+ "@colors/colors" "1.5.0"
cli-truncate@^0.2.1:
version "0.2.1"
@@ -13311,13 +13552,12 @@ cloneable-readable@^1.0.0:
process-nextick-args "^2.0.0"
readable-stream "^2.3.5"
-cmd-shim@^3.0.0, cmd-shim@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-3.0.3.tgz#2c35238d3df37d98ecdd7d5f6b8dc6b21cadc7cb"
- integrity sha512-DtGg+0xiFhQIntSBRzL2fRQBnmtAVwXIDo4Qq46HPpObYquxMaZS4sb82U9nH91qJrlosC1wa9gwr0QyL/HypA==
+cmd-shim@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-5.0.0.tgz#8d0aaa1a6b0708630694c4dbde070ed94c707724"
+ integrity sha512-qkCtZ59BidfEwHltnJwkyVZn+XQojdAySM1D1gSeh11Z4pW1Kpolkyo53L5noc0nrxmIvyFwTmJRo4xs7FFLPw==
dependencies:
- graceful-fs "^4.1.2"
- mkdirp "~0.5.0"
+ mkdirp-infer-owner "^2.0.0"
co@^4.6.0:
version "4.6.0"
@@ -13491,17 +13731,17 @@ colors@1.0.3:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
-colors@1.4.0, colors@^1.1.2, colors@^1.4.0:
+colors@^1.1.2, colors@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
-columnify@^1.5.4, columnify@~1.5.4:
- version "1.5.4"
- resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb"
- integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=
+columnify@^1.5.4, columnify@^1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3"
+ integrity sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==
dependencies:
- strip-ansi "^3.0.0"
+ strip-ansi "^6.0.1"
wcwidth "^1.0.0"
combine-properties@0.1.0:
@@ -13598,6 +13838,11 @@ commander@~2.19.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
+common-ancestor-path@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7"
+ integrity sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==
+
common-path-prefix@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0"
@@ -13780,18 +14025,6 @@ config-chain@^1.1.11, config-chain@^1.1.12:
ini "^1.3.4"
proto-list "~1.2.1"
-configstore@^3.0.0:
- version "3.1.5"
- resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.5.tgz#e9af331fadc14dabd544d3e7e76dc446a09a530f"
- integrity sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==
- dependencies:
- dot-prop "^4.2.1"
- graceful-fs "^4.1.2"
- make-dir "^1.0.0"
- unique-string "^1.0.0"
- write-file-atomic "^2.0.0"
- xdg-basedir "^3.0.0"
-
configstore@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96"
@@ -13930,7 +14163,7 @@ conventional-changelog-preset-loader@^2.1.1, conventional-changelog-preset-loade
resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz#14a855abbffd59027fd602581f1f34d9862ea44c"
integrity sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==
-conventional-changelog-writer@^4.0.0, conventional-changelog-writer@^4.0.6:
+conventional-changelog-writer@^4.0.6:
version "4.1.0"
resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.1.0.tgz#1ca7880b75aa28695ad33312a1f2366f4b12659f"
integrity sha512-WwKcUp7WyXYGQmkLsX4QmU42AZ1lqlvRW9mqoyiQzdD+rJWbTepdWoKJuwXTS+yq79XKnQNa93/roViPQrAQgw==
@@ -13946,6 +14179,21 @@ conventional-changelog-writer@^4.0.0, conventional-changelog-writer@^4.0.6:
split "^1.0.0"
through2 "^4.0.0"
+conventional-changelog-writer@^5.0.0:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz#e0757072f045fe03d91da6343c843029e702f359"
+ integrity sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==
+ dependencies:
+ conventional-commits-filter "^2.0.7"
+ dateformat "^3.0.0"
+ handlebars "^4.7.7"
+ json-stringify-safe "^5.0.1"
+ lodash "^4.17.15"
+ meow "^8.0.0"
+ semver "^6.0.0"
+ split "^1.0.0"
+ through2 "^4.0.0"
+
conventional-commits-filter@^2.0.0, conventional-commits-filter@^2.0.2, conventional-commits-filter@^2.0.7:
version "2.0.7"
resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz#f8d9b4f182fce00c9af7139da49365b136c8a0b3"
@@ -13954,10 +14202,10 @@ conventional-commits-filter@^2.0.0, conventional-commits-filter@^2.0.2, conventi
lodash.ismatch "^4.4.0"
modify-values "^1.0.0"
-conventional-commits-parser@^3.0.0, conventional-commits-parser@^3.0.3, conventional-commits-parser@^3.0.7, conventional-commits-parser@^3.2.0:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.1.tgz#ba44f0b3b6588da2ee9fd8da508ebff50d116ce2"
- integrity sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA==
+conventional-commits-parser@^3.0.3, conventional-commits-parser@^3.2.0, conventional-commits-parser@^3.2.3:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz#a7d3b77758a202a9b2293d2112a8d8052c740972"
+ integrity sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==
dependencies:
JSONStream "^1.0.4"
is-text-path "^1.0.1"
@@ -13965,7 +14213,6 @@ conventional-commits-parser@^3.0.0, conventional-commits-parser@^3.0.3, conventi
meow "^8.0.0"
split2 "^3.0.0"
through2 "^4.0.0"
- trim-off-newlines "^1.0.0"
conventional-recommended-bump@6.1.0:
version "6.1.0"
@@ -14309,13 +14556,6 @@ create-ecdh@^4.0.0:
bn.js "^4.1.0"
elliptic "^6.5.3"
-create-error-class@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
- integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=
- dependencies:
- capture-stack-trace "^1.0.0"
-
create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196"
@@ -14467,11 +14707,6 @@ crypto-browserify@^3.0.0, crypto-browserify@^3.11.0:
randombytes "^2.0.0"
randomfill "^1.0.3"
-crypto-random-string@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
- integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=
-
crypto-random-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
@@ -15057,10 +15292,10 @@ debounce@^1.2.0:
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==
-debug@*, debug@4, debug@4.3.3, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@~4.3.1:
- version "4.3.3"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
- integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
+debug@*, debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@~4.3.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"
@@ -15120,6 +15355,13 @@ debug@4.3.2:
dependencies:
ms "2.1.2"
+debug@4.3.3:
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
+ integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
+ dependencies:
+ ms "2.1.2"
+
debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6, debug@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
@@ -15542,7 +15784,7 @@ detect-indent@^4.0.0:
dependencies:
repeating "^2.0.0"
-detect-indent@^5.0.0, detect-indent@~5.0.0:
+detect-indent@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=
@@ -15625,7 +15867,7 @@ devtools-protocol@0.0.927104:
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.927104.tgz#3bba0fca644bcdce1bcebb10ae392ab13428a7a0"
integrity sha512-5jfffjSuTOv0Lz53wTNNTcCUV8rv7d82AhYcapj28bC2B5tDxEZzVb7k51cNxZP2KHw24QE+sW7ZuSeD9NfMpA==
-dezalgo@^1.0.0, dezalgo@~1.0.3:
+dezalgo@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456"
integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=
@@ -15961,7 +16203,7 @@ dot-case@^3.0.4:
no-case "^3.0.4"
tslib "^2.0.3"
-dot-prop@^4.2.0, dot-prop@^4.2.1:
+dot-prop@^4.2.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.1.tgz#45884194a71fc2cda71cbb4bceb3a4dd2f433ba4"
integrity sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==
@@ -15990,11 +16232,6 @@ dotenv@^10.0.0:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
-dotenv@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef"
- integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==
-
dotenv@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05"
@@ -16103,11 +16340,6 @@ ecstatic@^3.3.2:
minimist "^1.1.0"
url-join "^2.0.5"
-editor@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742"
- integrity sha1-YMf4e9YrzGqJT6jM1q+3gjok90I=
-
editorconfig@^0.15.3:
version "0.15.3"
resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5"
@@ -16298,7 +16530,7 @@ encodeurl@^1.0.2, encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
-encoding@^0.1.11, encoding@^0.1.12:
+encoding@^0.1.11, 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==
@@ -18033,6 +18265,11 @@ fast-xml-parser@3.19.0:
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz#cb637ec3f3999f51406dd8ff0e6fc4d83e520d01"
integrity sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==
+fastest-levenshtein@^1.0.12:
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
+ integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
+
fastparse@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
@@ -18356,11 +18593,6 @@ find-cache-dir@^2.0.0, find-cache-dir@^2.1.0:
make-dir "^2.0.0"
pkg-dir "^3.0.0"
-find-npm-prefix@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf"
- integrity sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA==
-
find-port@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/find-port/-/find-port-1.0.1.tgz#db084a6cbf99564d99869ae79fbdecf66e8a185c"
@@ -18431,13 +18663,6 @@ find-up@^4.0.0, find-up@^4.1.0:
locate-path "^5.0.0"
path-exists "^4.0.0"
-find-versions@^3.0.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e"
- integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==
- dependencies:
- semver-regex "^2.0.0"
-
find-versions@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965"
@@ -18571,10 +18796,10 @@ flex-exec@^1.0.0:
resolved "https://registry.yarnpkg.com/flex-exec/-/flex-exec-1.0.0.tgz#06974b68532839d2a12c32debcdb12378200fdf0"
integrity sha1-BpdLaFMoOdKhLDLevNsSN4IA/fA=
-floating-vue@2.0.0-beta.16:
- version "2.0.0-beta.16"
- resolved "https://registry.yarnpkg.com/floating-vue/-/floating-vue-2.0.0-beta.16.tgz#511d2eca106e67da6ccb4e85bb89c86b96297cbd"
- integrity sha512-MoVA9pLGMVkuyG9cvlzpSB9//HGynbWnkLr0cxDgnEWORL98kuSa2ph/bcq7sDGNM3l0/3v6HYSqhBMBp9F3/A==
+floating-vue@2.0.0-beta.17:
+ version "2.0.0-beta.17"
+ resolved "https://registry.yarnpkg.com/floating-vue/-/floating-vue-2.0.0-beta.17.tgz#f488d992f58d76b41fc3490f3ef969d58a5c8f99"
+ integrity sha512-zgHPIdlILFxMEq2kLpeUpE3SUSd/zHI4pNAO2QYtp2rATkiSOlcLJidTDjG3mcBKzN3ahoAF6t/FhA1VbMTkAg==
dependencies:
"@floating-ui/dom" "^0.1.10"
vue-resize "^2.0.0-alpha.1"
@@ -18756,14 +18981,6 @@ fresh@0.5.2, fresh@~0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
-from2@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/from2/-/from2-1.3.0.tgz#88413baaa5f9a597cfde9221d86986cd3c061dfd"
- integrity sha1-iEE7qqX5pZfP3pIh2GmGzTwGHf0=
- dependencies:
- inherits "~2.0.1"
- readable-stream "~1.1.10"
-
from2@^2.1.0, from2@^2.1.1, from2@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
@@ -18919,16 +19136,7 @@ fs-readdir-recursive@^1.1.0:
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==
-fs-vacuum@^1.2.10, fs-vacuum@~1.2.10:
- version "1.2.10"
- resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36"
- integrity sha1-t2Kb7AekAxolSP35n17PHMizHjY=
- dependencies:
- graceful-fs "^4.1.2"
- path-is-inside "^1.0.1"
- rimraf "^2.5.2"
-
-fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.10:
+fs-write-stream-atomic@^1.0.8:
version "1.0.10"
resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=
@@ -19087,23 +19295,6 @@ gensync@^1.0.0-beta.1, gensync@^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==
-gentle-fs@^2.3.0, gentle-fs@^2.3.1:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.3.1.tgz#11201bf66c18f930ddca72cf69460bdfa05727b1"
- integrity sha512-OlwBBwqCFPcjm33rF2BjW+Pr6/ll2741l+xooiwTCeaX2CA1ZuclavyMBe0/KlR21/XGsgY6hzEQZ15BdNa13Q==
- dependencies:
- aproba "^1.1.2"
- chownr "^1.1.2"
- cmd-shim "^3.0.3"
- fs-vacuum "^1.2.10"
- graceful-fs "^4.1.11"
- iferr "^0.1.5"
- infer-owner "^1.0.4"
- mkdirp "^0.5.1"
- path-is-inside "^1.0.2"
- read-cmd-shim "^1.0.1"
- slide "^1.1.6"
-
get-assigned-identifiers@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz#6dbf411de648cbaf8d9169ebb0d2d576191e2ff1"
@@ -19184,6 +19375,11 @@ get-port@^4.2.0:
resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119"
integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==
+get-port@^6.1.2:
+ version "6.1.2"
+ resolved "https://registry.yarnpkg.com/get-port/-/get-port-6.1.2.tgz#c1228abb67ba0e17fb346da33b15187833b9c08a"
+ integrity sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==
+
get-stdin@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
@@ -19501,7 +19697,7 @@ glob@7.1.6:
once "^1.3.0"
path-is-absolute "^1.0.0"
-glob@7.2.0, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
+glob@7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
@@ -19524,6 +19720,29 @@ glob@^5.0.15:
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, 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-agent@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-3.0.0.tgz#ae7cd31bd3583b93c5a16437a1afe27cc33a1ab6"
@@ -19536,13 +19755,6 @@ global-agent@^3.0.0:
semver "^7.3.2"
serialize-error "^7.0.1"
-global-dirs@^0.1.0:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445"
- integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=
- dependencies:
- ini "^1.3.4"
-
global-dirs@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686"
@@ -19808,23 +20020,6 @@ got@11.8.3:
p-cancelable "^2.0.0"
responselike "^2.0.0"
-got@^6.7.1:
- version "6.7.1"
- resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
- integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=
- dependencies:
- create-error-class "^3.0.0"
- duplexer3 "^0.1.4"
- get-stream "^3.0.0"
- is-redirect "^1.0.0"
- is-retry-allowed "^1.0.0"
- is-stream "^1.0.0"
- lowercase-keys "^1.0.0"
- safe-buffer "^5.0.1"
- timed-out "^4.0.0"
- unzip-response "^2.0.1"
- url-parse-lax "^1.0.0"
-
got@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937"
@@ -19865,7 +20060,12 @@ got@^9.6.0:
to-readable-stream "^1.0.0"
url-parse-lax "^3.0.0"
-graceful-fs@*, graceful-fs@4.2.9, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
+graceful-fs@*, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.10, graceful-fs@^4.2.2, graceful-fs@^4.2.3, 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==
+
+graceful-fs@4.2.9:
version "4.2.9"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
@@ -19933,6 +20133,11 @@ graphql-request@^3.3.0:
extract-files "^9.0.0"
form-data "^3.0.0"
+graphql-resolve-batch@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/graphql-resolve-batch/-/graphql-resolve-batch-1.0.3.tgz#eabffd89d929063d115fd5122939898dc649ee0b"
+ integrity sha512-GnrgWxHVV2Z+LbFkC3FS/kBBo4yUYAsLDFJGTK11MYfIcCStyiNAU2TeEdryJbIEndYMLUQY41pcUW1A5RY6Fg==
+
graphql-scalars@^1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/graphql-scalars/-/graphql-scalars-1.10.0.tgz#9daf9252b16e6fae553a06976163a23f41b65dfd"
@@ -19969,7 +20174,7 @@ graphql@14.0.0:
dependencies:
iterall "^1.2.2"
-graphql@^15.5.1:
+graphql@>=14, graphql@^15.5.1:
version "15.5.1"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.1.tgz#f2f84415d8985e7b84731e7f3536f8bb9d383aad"
integrity sha512-FeTRX67T3LoE3LWAxxOlW2K3Bz+rMYAC18rRguK4wgXaTZMiJwSUwDmPFo3UadAKbzirKIg5Qy+sNJXbpPRnQw==
@@ -20136,7 +20341,7 @@ handlebars@^3.0.3:
optionalDependencies:
uglify-js "^2.6"
-handlebars@^4.7.6:
+handlebars@^4.7.6, handlebars@^4.7.7:
version "4.7.7"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
@@ -20251,7 +20456,7 @@ has-tostringtag@^1.0.0:
dependencies:
has-symbols "^1.0.2"
-has-unicode@^2.0.0, has-unicode@^2.0.1, has-unicode@~2.0.1:
+has-unicode@^2.0.0, has-unicode@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
@@ -20430,12 +20635,12 @@ hook-std@^2.0.0:
resolved "https://registry.yarnpkg.com/hook-std/-/hook-std-2.0.0.tgz#ff9aafdebb6a989a354f729bb6445cf4a3a7077c"
integrity sha512-zZ6T5WcuBMIUVh49iPQS9t977t7C0l7OtHrpeMb5uk48JdflRX0NSFvCekfYNmGQETnLq9W/isMyHl69kxGi8g==
-hosted-git-info@^2.1.4, hosted-git-info@^2.7.1, hosted-git-info@^2.8.8:
+hosted-git-info@^2.1.4, hosted-git-info@^2.7.1:
version "2.8.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
-hosted-git-info@^3.0.0, hosted-git-info@^3.0.6:
+hosted-git-info@^3.0.6:
version "3.0.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d"
integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==
@@ -20449,6 +20654,13 @@ hosted-git-info@^4.0.0, hosted-git-info@^4.0.1, hosted-git-info@^4.0.2:
dependencies:
lru-cache "^6.0.0"
+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"
+
hotkeys-js@3.8.2:
version "3.8.2"
resolved "https://registry.yarnpkg.com/hotkeys-js/-/hotkeys-js-3.8.2.tgz#177c3e7dc19279c881e69983177849bed76e4747"
@@ -20727,6 +20939,15 @@ http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.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@0.19.1, 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"
@@ -20947,11 +21168,6 @@ iferr@^0.1.5:
resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE=
-iferr@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/iferr/-/iferr-1.0.2.tgz#e9fde49a9da06dc4a4194c6c9ed6d08305037a6d"
- integrity sha512-9AfeLfji44r5TKInjhz3W9DyZI1zR1JAf2hVBMGhddAKPqBsupb89jGfbCTHIGZd6fGZl9WlHdn4AObygyMKwg==
-
ignore-walk@^3.0.1, ignore-walk@^3.0.3:
version "3.0.4"
resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335"
@@ -20966,6 +21182,13 @@ ignore-walk@^4.0.1:
dependencies:
minimatch "^3.0.4"
+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@^3.0.9, ignore@^3.3.5:
version "3.3.10"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
@@ -21048,14 +21271,14 @@ import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
parent-module "^1.0.0"
resolve-from "^4.0.0"
-import-from@3.0.0, import-from@^3.0.0:
+import-from@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/import-from/-/import-from-3.0.0.tgz#055cfec38cd5a27d8057ca51376d7d3bf0891966"
integrity sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==
dependencies:
resolve-from "^5.0.0"
-import-from@4.0.0:
+import-from@4.0.0, import-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/import-from/-/import-from-4.0.0.tgz#2710b8d66817d232e16f4166e319248d3d5492e2"
integrity sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==
@@ -21129,7 +21352,7 @@ infer-owner@^1.0.3, infer-owner@^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, inflight@~1.0.6:
+inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
@@ -21157,11 +21380,16 @@ ini@2.0.0:
resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5"
integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==
-ini@^1.3.2, ini@^1.3.4, ini@^1.3.5, ini@^1.3.8, ini@~1.3.0, ini@~1.3.3:
+ini@^1.3.2, ini@^1.3.4, ini@^1.3.5, ini@~1.3.0, ini@~1.3.3:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
+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==
+
init-package-json@^1.10.3:
version "1.10.3"
resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.3.tgz#45ffe2f610a8ca134f2bd1db5637b235070f6cbe"
@@ -21176,6 +21404,19 @@ init-package-json@^1.10.3:
validate-npm-package-license "^3.0.1"
validate-npm-package-name "^3.0.0"
+init-package-json@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-3.0.2.tgz#f5bc9bac93f2bdc005778bc2271be642fecfcd69"
+ integrity sha512-YhlQPEjNFqlGdzrBfDNRLhvoSgX7iQRgSxgsNknRQ9ITXFT7UMfVMWhBTOh2Y+25lRnGrv5Xz8yZwQ3ACR6T3A==
+ dependencies:
+ npm-package-arg "^9.0.1"
+ promzard "^0.3.0"
+ read "^1.0.7"
+ read-package-json "^5.0.0"
+ semver "^7.3.5"
+ validate-npm-package-license "^3.0.4"
+ validate-npm-package-name "^4.0.0"
+
inline-source-map@~0.6.0:
version "0.6.2"
resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.6.2.tgz#f9393471c18a79d1724f863fa38b586370ade2a5"
@@ -21350,10 +21591,10 @@ into-stream@^3.1.0:
from2 "^2.1.1"
p-is-promise "^1.1.0"
-into-stream@^5.0.0:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-5.1.1.tgz#f9a20a348a11f3c13face22763f2d02e127f4db8"
- integrity sha512-krrAJ7McQxGGmvaYbB7Q1mcA+cRwg9Ij2RfWIeVesNBgVDZmzY/Fa4IpZUT3bmdRzMzdf/mzltCG2Dq99IZGBA==
+into-stream@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-6.0.0.tgz#4bfc1244c0128224e18b8870e85b2de8e66c6702"
+ integrity sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==
dependencies:
from2 "^2.3.0"
p-is-promise "^3.0.0"
@@ -21515,13 +21756,6 @@ is-ci@2.0.0, is-ci@^2.0.0:
dependencies:
ci-info "^2.0.0"
-is-ci@^1.0.10:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c"
- integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==
- dependencies:
- ci-info "^1.5.0"
-
is-ci@^3.0.0, is-ci@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867"
@@ -21529,12 +21763,12 @@ is-ci@^3.0.0, is-ci@^3.0.1:
dependencies:
ci-info "^3.2.0"
-is-cidr@^3.0.0:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-3.1.1.tgz#e92ef121bdec2782271a77ce487a8b8df3718ab7"
- integrity sha512-Gx+oErgq1j2jAKCR2Kbq0b3wbH0vQKqZ0wOlHxm0o56nq51Cs/DZA8oz9dMDhbHyHEGgJ86eTeVudtgMMOx3Mw==
+is-cidr@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-4.0.2.tgz#94c7585e4c6c77ceabf920f8cde51b8c0fda8814"
+ integrity sha512-z4a1ENUajDbEl/Q6/pVBpTR1nBjjEE1X7qb7bmWYanNnPoKAvUCPFKeXV6Fe4mgTkWKBqiHIcwsI3SndiO5FeA==
dependencies:
- cidr-regex "^2.0.10"
+ cidr-regex "^3.1.1"
is-color-stop@^1.0.0:
version "1.1.0"
@@ -21548,7 +21782,7 @@ is-color-stop@^1.0.0:
rgb-regex "^1.0.1"
rgba-regex "^1.0.0"
-is-core-module@^2.1.0, is-core-module@^2.2.0, is-core-module@^2.8.0, is-core-module@^2.8.1:
+is-core-module@^2.1.0, is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.8.0, is-core-module@^2.8.1:
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==
@@ -21723,14 +21957,6 @@ is-html@2.0.0, is-html@^2.0.0:
dependencies:
html-tags "^3.0.0"
-is-installed-globally@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80"
- integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=
- dependencies:
- global-dirs "^0.1.0"
- is-path-inside "^1.0.0"
-
is-installed-globally@^0.4.0, 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"
@@ -21802,11 +22028,6 @@ is-negative-zero@^2.0.1:
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==
-is-npm@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
- integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ=
-
is-npm@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8"
@@ -21968,11 +22189,6 @@ is-property@^1.0.0, is-property@^1.0.2:
resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=
-is-redirect@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24"
- integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=
-
is-reference@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7"
@@ -22012,7 +22228,7 @@ is-resolvable@^1.0.0, is-resolvable@^1.1.0:
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
-is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
+is-retry-allowed@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
@@ -22039,7 +22255,7 @@ is-ssh@^1.3.0:
dependencies:
protocols "^1.1.0"
-is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0:
+is-stream@^1.0.1, is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
@@ -23317,7 +23533,7 @@ json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-bet
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
-json-parse-even-better-errors@^2.3.0:
+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==
@@ -23366,6 +23582,11 @@ json-stable-stringify@~0.0.0:
dependencies:
jsonify "~0.0.0"
+json-stringify-nice@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz#2c937962b80181d3f317dd39aa323e14f5a60a67"
+ integrity sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==
+
json-stringify-safe@^5.0.0, json-stringify-safe@^5.0.1, 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"
@@ -23559,6 +23780,16 @@ just-debounce@^1.0.0:
resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.1.0.tgz#2f81a3ad4121a76bc7cb45dbf704c0d76a8e5ddf"
integrity sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==
+just-diff-apply@^5.2.0:
+ version "5.3.1"
+ resolved "https://registry.yarnpkg.com/just-diff-apply/-/just-diff-apply-5.3.1.tgz#30f40809ffed55ad76dccf73fa9b85a76964c867"
+ integrity sha512-dgFenZnMsc1xGNqgdtgnh7DK+Oy352CE3VZLbzcbQpsBs9iI2K3M0IRrdgREZ72eItTjbl0suRyvKRdVQa9GbA==
+
+just-diff@^5.0.1:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/just-diff/-/just-diff-5.0.3.tgz#4c9c514dec5526b25ab977590e3c39a0cf271554"
+ integrity sha512-a8p80xcpJ6sdurk5PxDKb4mav9MeKjA3zFKZpCWBIfvg8mznfnmb13MKZvlrwJ+Lhis0wM3uGAzE0ArhFHvIcg==
+
just-extend@^4.0.2:
version "4.1.1"
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.1.tgz#158f1fdb01f128c411dc8b286a7b4837b3545282"
@@ -23766,13 +23997,6 @@ latest-version@5.1.0, latest-version@^5.1.0:
dependencies:
package-json "^6.3.0"
-latest-version@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15"
- integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=
- dependencies:
- package-json "^4.0.0"
-
launch-editor@2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.2.1.tgz#871b5a3ee39d6680fcc26d37930b6eeda89db0ca"
@@ -23811,11 +24035,6 @@ lazy-cache@^2.0.1:
dependencies:
set-getter "^0.1.0"
-lazy-property@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/lazy-property/-/lazy-property-1.0.0.tgz#84ddc4b370679ba8bd4cdcfa4c06b43d57111147"
- integrity sha1-hN3Es3Bnm6i9TNz6TAa0PVcREUc=
-
lazy-val@^1.0.4, lazy-val@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.5.tgz#6cf3b9f5bc31cee7ee3e369c0832b7583dcd923d"
@@ -24032,27 +24251,6 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"
-libcipm@^4.0.8:
- version "4.0.8"
- resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-4.0.8.tgz#dcea4919e10dfbce420327e63901613b9141bc89"
- integrity sha512-IN3hh2yDJQtZZ5paSV4fbvJg4aHxCCg5tcZID/dSVlTuUiWktsgaldVljJv6Z5OUlYspx6xQkbR0efNodnIrOA==
- dependencies:
- bin-links "^1.1.2"
- bluebird "^3.5.1"
- figgy-pudding "^3.5.1"
- find-npm-prefix "^1.0.2"
- graceful-fs "^4.1.11"
- ini "^1.3.5"
- lock-verify "^2.1.0"
- mkdirp "^0.5.1"
- npm-lifecycle "^3.0.0"
- npm-logical-tree "^1.2.1"
- npm-package-arg "^6.1.0"
- pacote "^9.1.0"
- read-package-json "^2.0.13"
- rimraf "^2.6.2"
- worker-farm "^1.6.0"
-
libhoney@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/libhoney/-/libhoney-3.0.0.tgz#33cf6b24f54e15b8ad72a0d6a214805479e13099"
@@ -24062,118 +24260,116 @@ libhoney@3.0.0:
superagent-proxy "^3.0.0"
urljoin "^0.1.5"
-libnpm@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/libnpm/-/libnpm-3.0.1.tgz#0be11b4c9dd4d1ffd7d95c786e92e55d65be77a2"
- integrity sha512-d7jU5ZcMiTfBqTUJVZ3xid44fE5ERBm9vBnmhp2ECD2Ls+FNXWxHSkO7gtvrnbLO78gwPdNPz1HpsF3W4rjkBQ==
+libnpmaccess@^6.0.2:
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-6.0.3.tgz#473cc3e4aadb2bc713419d92e45d23b070d8cded"
+ integrity sha512-4tkfUZprwvih2VUZYMozL7EMKgQ5q9VW2NtRyxWtQWlkLTAWHRklcAvBN49CVqEkhUw7vTX2fNgB5LzgUucgYg==
dependencies:
- bin-links "^1.1.2"
- bluebird "^3.5.3"
- find-npm-prefix "^1.0.2"
- libnpmaccess "^3.0.2"
- libnpmconfig "^1.2.1"
- libnpmhook "^5.0.3"
- libnpmorg "^1.0.1"
- libnpmpublish "^1.1.2"
- libnpmsearch "^2.0.2"
- libnpmteam "^1.0.2"
- lock-verify "^2.0.2"
- npm-lifecycle "^3.0.0"
- npm-logical-tree "^1.2.1"
- npm-package-arg "^6.1.0"
- npm-profile "^4.0.2"
- npm-registry-fetch "^4.0.0"
- npmlog "^4.1.2"
- pacote "^9.5.3"
- read-package-json "^2.0.13"
- stringify-package "^1.0.0"
+ aproba "^2.0.0"
+ minipass "^3.1.1"
+ npm-package-arg "^9.0.1"
+ npm-registry-fetch "^13.0.0"
-libnpmaccess@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.2.tgz#8b2d72345ba3bef90d3b4f694edd5c0417f58923"
- integrity sha512-01512AK7MqByrI2mfC7h5j8N9V4I7MHJuk9buo8Gv+5QgThpOgpjB7sQBDDkeZqRteFb1QM/6YNdHfG7cDvfAQ==
+libnpmdiff@^4.0.2:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/libnpmdiff/-/libnpmdiff-4.0.3.tgz#ad3997330c887c1098ac42682f1e5ad014d49cec"
+ integrity sha512-AiwBtXtH7HjfmT7FbTf9LFzJB347RrIA4I+IewMfhq8vYXaUveHwJMVNgMM2H/o2J+7Hf12JCBoOF5bTwlmGyw==
dependencies:
- aproba "^2.0.0"
- get-stream "^4.0.0"
- npm-package-arg "^6.1.0"
- npm-registry-fetch "^4.0.0"
+ "@npmcli/disparity-colors" "^2.0.0"
+ "@npmcli/installed-package-contents" "^1.0.7"
+ binary-extensions "^2.2.0"
+ diff "^5.0.0"
+ minimatch "^5.0.1"
+ npm-package-arg "^9.0.1"
+ pacote "^13.0.5"
+ tar "^6.1.0"
-libnpmconfig@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/libnpmconfig/-/libnpmconfig-1.2.1.tgz#c0c2f793a74e67d4825e5039e7a02a0044dfcbc0"
- integrity sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==
+libnpmexec@^4.0.2:
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/libnpmexec/-/libnpmexec-4.0.6.tgz#600beffd6f265cf92a096a7f336f330bc0019e82"
+ integrity sha512-v1jAPJyFFex6R0YHYXuudR4liQ3tYJ7vVZ6eThOex4+WzQEnoShLVfK3MLyFbjdGNO85wCHcVWVpXaBOVnVa/w==
dependencies:
- figgy-pudding "^3.5.1"
- find-up "^3.0.0"
- ini "^1.3.5"
+ "@npmcli/arborist" "^5.0.0"
+ "@npmcli/ci-detect" "^2.0.0"
+ "@npmcli/run-script" "^3.0.0"
+ chalk "^4.1.0"
+ mkdirp-infer-owner "^2.0.0"
+ npm-package-arg "^9.0.1"
+ npmlog "^6.0.2"
+ pacote "^13.0.5"
+ proc-log "^2.0.0"
+ read "^1.0.7"
+ read-package-json-fast "^2.0.2"
+ walk-up-path "^1.0.0"
+
+libnpmfund@^3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/libnpmfund/-/libnpmfund-3.0.2.tgz#7da0827950f0db2cce0acb0dc7652d1834a8b239"
+ integrity sha512-wmFMP/93Wjy+jDg5LaSldDgAhSgCyA64JUUmp806Kae7y3YP9Qv5m1vUhPxT4yebxgB2v/I6G1/RUcNb1y0kVg==
+ dependencies:
+ "@npmcli/arborist" "^5.0.0"
-libnpmhook@^5.0.3:
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-5.0.3.tgz#4020c0f5edbf08ebe395325caa5ea01885b928f7"
- integrity sha512-UdNLMuefVZra/wbnBXECZPefHMGsVDTq5zaM/LgKNE9Keyl5YXQTnGAzEo+nFOpdRqTWI9LYi4ApqF9uVCCtuA==
+libnpmhook@^8.0.2:
+ version "8.0.3"
+ resolved "https://registry.yarnpkg.com/libnpmhook/-/libnpmhook-8.0.3.tgz#9628518a63455d21dafda312ee46175275707ff5"
+ integrity sha512-TEdNI1mC5zS+w/juCgxrwwQnpbq9lY76NDOS0N37pn6pWIUxB1Yq8mwy6MUEXR1TgH4HurSQyKT6I6Kp9Wjm4A==
dependencies:
aproba "^2.0.0"
- figgy-pudding "^3.4.1"
- get-stream "^4.0.0"
- npm-registry-fetch "^4.0.0"
+ npm-registry-fetch "^13.0.0"
-libnpmorg@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-1.0.1.tgz#5d2503f6ceb57f33dbdcc718e6698fea6d5ad087"
- integrity sha512-0sRUXLh+PLBgZmARvthhYXQAWn0fOsa6T5l3JSe2n9vKG/lCVK4nuG7pDsa7uMq+uTt2epdPK+a2g6btcY11Ww==
+libnpmorg@^4.0.2:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/libnpmorg/-/libnpmorg-4.0.3.tgz#a85cbdb3665ad4f7c7279d239a4581ec2eeef5a6"
+ integrity sha512-r4CpmCEF+e5PbFMBi64xSXmqn0uGgV4T7NWpGL4/A6KT/DTtIxALILQZq+l0ZdN1xm4RjOvqSDR22oT4il8rAQ==
dependencies:
aproba "^2.0.0"
- figgy-pudding "^3.4.1"
- get-stream "^4.0.0"
- npm-registry-fetch "^4.0.0"
+ npm-registry-fetch "^13.0.0"
-libnpmpublish@^1.1.2:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-1.1.3.tgz#e3782796722d79eef1a0a22944c117e0c4ca4280"
- integrity sha512-/3LsYqVc52cHXBmu26+J8Ed7sLs/hgGVFMH1mwYpL7Qaynb9RenpKqIKu0sJ130FB9PMkpMlWjlbtU8A4m7CQw==
+libnpmpack@^4.0.2:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/libnpmpack/-/libnpmpack-4.1.0.tgz#93a170b67bc52e15edc7b1f2e09b2c36e532b897"
+ integrity sha512-BHwojfEbJvVVJXivZjOCe3Y0IzQ47p6c/bfebrpzazuFNRoS9XOsbkncRbl3f23+u9b51eplzwaPh/5xSOAWHg==
dependencies:
- aproba "^2.0.0"
- figgy-pudding "^3.5.1"
- get-stream "^4.0.0"
- lodash.clonedeep "^4.5.0"
- normalize-package-data "^2.4.0"
- npm-package-arg "^6.1.0"
- npm-registry-fetch "^4.0.0"
- semver "^5.5.1"
- ssri "^6.0.1"
+ "@npmcli/run-script" "^3.0.0"
+ npm-package-arg "^9.0.1"
+ pacote "^13.5.0"
-libnpmsearch@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-2.0.2.tgz#9a4f059102d38e3dd44085bdbfe5095f2a5044cf"
- integrity sha512-VTBbV55Q6fRzTdzziYCr64+f8AopQ1YZ+BdPOv16UegIEaE8C0Kch01wo4s3kRTFV64P121WZJwgmBwrq68zYg==
+libnpmpublish@^6.0.2:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-6.0.4.tgz#adb41ec6b0c307d6f603746a4d929dcefb8f1a0b"
+ integrity sha512-lvAEYW8mB8QblL6Q/PI/wMzKNvIrF7Kpujf/4fGS/32a2i3jzUXi04TNyIBcK6dQJ34IgywfaKGh+Jq4HYPFmg==
dependencies:
- figgy-pudding "^3.5.1"
- get-stream "^4.0.0"
- npm-registry-fetch "^4.0.0"
+ normalize-package-data "^4.0.0"
+ npm-package-arg "^9.0.1"
+ npm-registry-fetch "^13.0.0"
+ semver "^7.3.7"
+ ssri "^9.0.0"
-libnpmteam@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-1.0.2.tgz#8b48bcbb6ce70dd8150c950fcbdbf3feb6eec820"
- integrity sha512-p420vM28Us04NAcg1rzgGW63LMM6rwe+6rtZpfDxCcXxM0zUTLl7nPFEnRF3JfFBF5skF/yuZDUthTsHgde8QA==
+libnpmsearch@^5.0.2:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-5.0.3.tgz#ed502a4c2c70ea36723180455fae1357546b2184"
+ integrity sha512-Ofq76qKAPhxbiyzPf/5LPjJln26VTKwU9hIU0ACxQ6tNtBJ1CHmI7iITrdp7vNezhZc0FlkXwrIpqXjhBJZgLQ==
+ dependencies:
+ npm-registry-fetch "^13.0.0"
+
+libnpmteam@^4.0.2:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/libnpmteam/-/libnpmteam-4.0.3.tgz#9335fbbd032b3770f5c9b7ffc6203f47d1ed144a"
+ integrity sha512-LsYYLz4TlTpcqkusInY5MhKjiHFaCx1GV0LmydXJ/QMh+3IWBJpUhes4ynTZuFoJKkDIFjxyMU09ul+RZixgdg==
dependencies:
aproba "^2.0.0"
- figgy-pudding "^3.4.1"
- get-stream "^4.0.0"
- npm-registry-fetch "^4.0.0"
+ npm-registry-fetch "^13.0.0"
-libnpx@^10.2.4:
- version "10.2.4"
- resolved "https://registry.yarnpkg.com/libnpx/-/libnpx-10.2.4.tgz#ef0e3258e29aef2ec7ee3276115e20e67f67d4ee"
- integrity sha512-BPc0D1cOjBeS8VIBKUu5F80s6njm0wbVt7CsGMrIcJ+SI7pi7V0uVPGpEMH9H5L8csOcclTxAXFE2VAsJXUhfA==
+libnpmversion@^3.0.1:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/libnpmversion/-/libnpmversion-3.0.4.tgz#a30f563416ea1e2dd69878b4a9edf4eb4a070ef8"
+ integrity sha512-q5hvZlso0SMLgKm4AMtleRWtq4pERprebEGV6OwKi24efgAOgNDP98+jNUX2mIR2wp9eAa6ybkNNWu4yMaCsVw==
dependencies:
- dotenv "^5.0.1"
- npm-package-arg "^6.0.0"
- rimraf "^2.6.2"
- safe-buffer "^5.1.0"
- update-notifier "^2.3.0"
- which "^1.3.0"
- y18n "^4.0.0"
- yargs "^14.2.3"
+ "@npmcli/git" "^3.0.0"
+ "@npmcli/run-script" "^3.0.0"
+ json-parse-even-better-errors "^2.3.1"
+ proc-log "^2.0.0"
+ semver "^7.3.7"
license-webpack-plugin@2.3.11:
version "2.3.11"
@@ -24473,16 +24669,7 @@ locate-path@^7.1.0:
dependencies:
p-locate "^6.0.0"
-lock-verify@^2.0.2, lock-verify@^2.1.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.2.1.tgz#81107948c51ed16f97b96ff8b60675affb243fc1"
- integrity sha512-n0Zw2DVupKfZMazy/HIFVNohJ1z8fIoZ77WBnyyBGG6ixw83uJNyrbiJvvHWe1QKkGiBCjj8RCPlymltliqEww==
- dependencies:
- "@iarna/cli" "^1.2.0"
- npm-package-arg "^6.1.0"
- semver "^5.4.1"
-
-lockfile@1.0.4, lockfile@^1.0.4:
+lockfile@1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609"
integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==
@@ -24512,19 +24699,6 @@ lodash._basecreate@^3.0.0:
resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821"
integrity sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=
-lodash._baseuniq@~4.6.0:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
- integrity sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg=
- dependencies:
- lodash._createset "~4.0.0"
- lodash._root "~3.0.0"
-
-lodash._createset@~4.0.0:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
- integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=
-
lodash._getnative@^3.0.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
@@ -24540,11 +24714,6 @@ lodash._reinterpolate@^3.0.0:
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
-lodash._root@~3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
- integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=
-
lodash.camelcase@4.3.0, lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
@@ -24555,7 +24724,7 @@ lodash.capitalize@^4.2.1:
resolved "https://registry.yarnpkg.com/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz#f826c9b4e2a8511d84e3aca29db05e1a4f3b72a9"
integrity sha1-+CbJtOKoUR2E46yinbBeGk87cqk=
-lodash.clonedeep@4.5.0, lodash.clonedeep@^4.5.0, lodash.clonedeep@~4.5.0:
+lodash.clonedeep@4.5.0, lodash.clonedeep@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
@@ -24748,17 +24917,12 @@ lodash.throttle@^4.1.1:
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=
-lodash.toarray@^4.4.0:
- version "4.4.0"
- resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
- integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE=
-
-lodash.union@^4.6.0, lodash.union@~4.6.0:
+lodash.union@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=
-lodash.uniq@^4.5.0, lodash.uniq@~4.5.0:
+lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
@@ -24768,7 +24932,7 @@ lodash.uniqby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302"
integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=
-lodash.without@^4.4.0, lodash.without@~4.4.0:
+lodash.without@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac"
integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=
@@ -24978,6 +25142,11 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
+lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1:
+ version "7.10.1"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.10.1.tgz#db577f42a94c168f676b638d15da8fb073448cab"
+ integrity sha512-BQuhQxPuRl79J5zSXRP+uNzPOyZw2oFI9JLRQ80XswSvg21KMKNtQza9eF42rfI/3Z40RvzBdXgziEkudzjo8A==
+
ltgt@^2.1.2:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5"
@@ -25007,6 +25176,13 @@ magic-string@0.25.7, magic-string@^0.25.0, magic-string@^0.25.5, magic-string@^0
dependencies:
sourcemap-codec "^1.4.4"
+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"
+
make-dir@^1.0.0, make-dir@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
@@ -25034,6 +25210,28 @@ make-error@^1, make-error@^1.1.1:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
+make-fetch-happen@^10.0.3, make-fetch-happen@^10.0.6, make-fetch-happen@^10.1.6:
+ version "10.1.7"
+ resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.1.7.tgz#b1402cb3c9fad92b380ff3a863cdae5414a42f76"
+ integrity sha512-J/2xa2+7zlIUKqfyXDCXFpH3ypxO4k3rgkZHPSZkyUYcBT/hM80M3oyKLM/9dVriZFiGeGGS2Ei+0v2zfhqj3Q==
+ 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@^5.0.0:
version "5.0.2"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd"
@@ -25184,27 +25382,22 @@ markdown-it@12.2.0:
mdurl "^1.0.1"
uc.micro "^1.0.5"
-marked-terminal@^4.0.0, marked-terminal@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-4.1.1.tgz#34a6f063cd6cfe26bffaf5bac3724e24242168a9"
- integrity sha512-t7Mdf6T3PvOEyN01c3tYxDzhyKZ8xnkp8Rs6Fohno63L/0pFTJ5Qtwto2AQVuDtbQiWzD+4E5AAu1Z2iLc8miQ==
+marked-terminal@^5.0.0:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-5.1.1.tgz#d2edc2991841d893ee943b44b40b2ee9518b4d9f"
+ integrity sha512-+cKTOx9P4l7HwINYhzbrBSyzgxO2HaHKGZGuB1orZsMIgXYaJyfidT81VXRdpelW/PcHEWxywscePVgI/oUF6g==
dependencies:
- ansi-escapes "^4.3.1"
+ ansi-escapes "^5.0.0"
cardinal "^2.1.1"
- chalk "^4.1.0"
- cli-table "^0.3.1"
- node-emoji "^1.10.0"
- supports-hyperlinks "^2.1.0"
+ chalk "^5.0.0"
+ cli-table3 "^0.6.1"
+ node-emoji "^1.11.0"
+ supports-hyperlinks "^2.2.0"
-marked@^1.0.0:
- version "1.2.9"
- resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.9.tgz#53786f8b05d4c01a2a5a76b7d1ec9943d29d72dc"
- integrity sha512-H8lIX2SvyitGX+TRdtS06m1jHMijKN/XjfH6Ooii9fvxMlh8QdqBfBDkGUpMWH2kQNrtixjzYUa3SH8ROTgRRw==
-
-marked@^2.0.0:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.5.tgz#2d15c759b9497b0e7b5b57f4c2edabe1002ef9e7"
- integrity sha512-yfCEUXmKhBPLOzEC7c+tc4XZdIeTdGoRCZakFMkCxodr7wDXqoapIME4wjcpBPJLNyUnKJ3e8rb8wlAgnLnaDw==
+marked@^4.0.10:
+ version "4.0.16"
+ resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.16.tgz#9ec18fc1a723032eb28666100344d9428cf7a264"
+ integrity sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==
matchdep@^2.0.0:
version "2.0.0"
@@ -25276,11 +25469,6 @@ mdurl@^1.0.1:
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
-meant@^1.0.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.3.tgz#67769af9de1d158773e928ae82c456114903554c"
- integrity sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw==
-
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -25439,7 +25627,7 @@ microevent.ts@~0.1.1:
resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0"
integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==
-micromatch@4.0.4, micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4:
+micromatch@4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
@@ -25485,6 +25673,14 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.2"
+micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
+ 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"
+
miller-rabin@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
@@ -25544,11 +25740,16 @@ mime@2.4.4:
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5"
integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==
-mime@^2.4.3, mime@^2.4.4, mime@^2.4.6, mime@^2.5.2:
+mime@^2.4.4, mime@^2.4.6, mime@^2.5.2:
version "2.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
+mime@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7"
+ integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==
+
mimic-fn@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
@@ -25632,7 +25833,7 @@ minimatch@0.3:
lru-cache "2"
sigmund "~1.0.0"
-"minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.4:
+"minimatch@2 || 3", minimatch@^3.0.2, 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==
@@ -25660,6 +25861,13 @@ minimatch@^2.0.3:
dependencies:
brace-expansion "^1.0.0"
+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-options@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619"
@@ -25715,6 +25923,17 @@ minipass-fetch@^1.3.0, minipass-fetch@^1.3.2:
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"
@@ -25752,7 +25971,7 @@ minipass@^2.3.5, minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
safe-buffer "^5.1.2"
yallist "^3.0.0"
-minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3:
+minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6:
version "3.1.6"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee"
integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==
@@ -25766,7 +25985,7 @@ minizlib@^1.2.1:
dependencies:
minipass "^2.9.0"
-minizlib@^2.0.0, minizlib@^2.1.1:
+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==
@@ -25811,6 +26030,15 @@ mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
+mkdirp-infer-owner@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz#55d3b368e7d89065c38f32fd38e638f0ab61d316"
+ integrity sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw==
+ dependencies:
+ chownr "^2.0.0"
+ infer-owner "^1.0.4"
+ mkdirp "^1.0.3"
+
mkdirp-promise@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1"
@@ -25842,7 +26070,7 @@ mkdirp@0.5.3:
dependencies:
minimist "^1.2.5"
-mkdirp@0.5.5, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1:
+mkdirp@0.5.5, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@@ -26404,7 +26632,7 @@ ms@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:
+ms@2.1.3, ms@^2.0.0, ms@^2.1.1, ms@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
@@ -26559,7 +26787,7 @@ needle@^2.5.2:
iconv-lite "^0.4.4"
sax "^1.2.4"
-negotiator@0.6.3, negotiator@^0.6.2:
+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==
@@ -26749,12 +26977,12 @@ node-dir@^0.1.17:
dependencies:
minimatch "^3.0.2"
-node-emoji@^1.10.0, node-emoji@^1.8.1:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da"
- integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==
+node-emoji@^1.11.0, node-emoji@^1.8.1:
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c"
+ integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==
dependencies:
- lodash.toarray "^4.4.0"
+ lodash "^4.17.21"
node-environment-flags@1.0.5:
version "1.0.5"
@@ -26821,7 +27049,7 @@ node-gyp-build@^4.3.0:
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3"
integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==
-node-gyp@^5.0.2, node-gyp@^5.1.0:
+node-gyp@^5.0.2:
version "5.1.1"
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e"
integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==
@@ -26854,7 +27082,7 @@ node-gyp@^7.1.0:
tar "^6.0.2"
which "^2.0.2"
-node-gyp@^8.2.0:
+node-gyp@^8.2.0, 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==
@@ -26870,6 +27098,22 @@ node-gyp@^8.2.0:
tar "^6.1.2"
which "^2.0.2"
+node-gyp@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.0.0.tgz#e1da2067427f3eb5bb56820cb62bc6b1e4bd2089"
+ integrity sha512-Ma6p4s+XCTPxCuAMrOA/IJRmVy16R8Sdhtwl4PrCr7IBlj4cPawF0vg/l7nOT1jPbuNS7lIRJpBSvVsXwEZuzw==
+ dependencies:
+ env-paths "^2.2.0"
+ glob "^7.1.4"
+ graceful-fs "^4.2.6"
+ make-fetch-happen "^10.0.3"
+ 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-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@@ -26982,7 +27226,7 @@ nopt@1.0.10:
dependencies:
abbrev "1"
-nopt@^4.0.1, nopt@^4.0.3:
+nopt@^4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==
@@ -27008,15 +27252,25 @@ normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-
validate-npm-package-license "^3.0.1"
normalize-package-data@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.0.tgz#1f8a7c423b3d2e85eb36985eaf81de381d01301a"
- integrity sha512-6lUjEI0d3v6kFrtgA/lOx4zHCWULXsFNIjHolnZCKCTLA6m/G625cdn3O7eNmT0iD3jfo6HZ9cdImGZwf21prw==
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e"
+ integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==
dependencies:
- hosted-git-info "^3.0.6"
- resolve "^1.17.0"
- semver "^7.3.2"
+ hosted-git-info "^4.0.1"
+ is-core-module "^2.5.0"
+ semver "^7.3.4"
validate-npm-package-license "^3.0.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@^2.0.1, normalize-path@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
@@ -27063,12 +27317,7 @@ normalize-url@^4.1.0:
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
-normalize-url@^5.0.0:
- version "5.3.1"
- resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-5.3.1.tgz#c8485c0f5ba2f9c17a6d2907b56117ae5967f882"
- integrity sha512-K1c7+vaAP+Yh5bOGmA10PGPpp+6h7WZrl7GwqKhUflBc9flU9pzG27DDeB9+iuhZkE3BJZOcgN1P/2sS5pqrWw==
-
-normalize-url@^6.0.1:
+normalize-url@^6.0.0, normalize-url@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
@@ -27085,26 +27334,20 @@ now-and-later@^2.0.0:
dependencies:
once "^1.3.2"
-npm-audit-report@^1.3.3:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-1.3.3.tgz#8226deeb253b55176ed147592a3995442f2179ed"
- integrity sha512-8nH/JjsFfAWMvn474HB9mpmMjrnKb1Hx/oTAdjv4PT9iZBvBxiZ+wtDUapHCJwLqYGQVPaAfs+vL5+5k9QndXw==
+npm-audit-report@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-3.0.0.tgz#1bf3e531208b5f77347c8d00c3d9badf5be30cd6"
+ integrity sha512-tWQzfbwz1sc4244Bx2BVELw0EmZlCsCF0X93RDcmmwhonCsPMoEviYsi+32R+mdRvOWXolPce9zo64n2xgPESw==
dependencies:
- cli-table3 "^0.5.0"
- console-control-strings "^1.1.0"
+ chalk "^4.0.0"
-npm-bundled@^1.0.1, npm-bundled@^1.1.1:
+npm-bundled@^1.0.1, 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-cache-filename@~1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11"
- integrity sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=
-
npm-conf@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9"
@@ -27113,13 +27356,6 @@ npm-conf@^1.1.3:
config-chain "^1.1.11"
pify "^3.0.0"
-npm-install-checks@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.2.tgz#ab2e32ad27baa46720706908e5b14c1852de44d9"
- integrity sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg==
- dependencies:
- semver "^2.3.0 || 3.x || 4 || 5"
-
npm-install-checks@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-4.0.0.tgz#a37facc763a2fde0497ef2c6d0ac7c3fbe00d7b4"
@@ -27127,7 +27363,14 @@ npm-install-checks@^4.0.0:
dependencies:
semver "^7.1.1"
-npm-lifecycle@^3.0.0, npm-lifecycle@^3.1.2, npm-lifecycle@^3.1.5:
+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-lifecycle@^3.1.2:
version "3.1.5"
resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz#9882d3642b8c82c815782a12e6a1bfeed0026309"
integrity sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g==
@@ -27141,11 +27384,6 @@ npm-lifecycle@^3.0.0, npm-lifecycle@^3.1.2, npm-lifecycle@^3.1.5:
umask "^1.1.0"
which "^1.3.1"
-npm-logical-tree@^1.2.1:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/npm-logical-tree/-/npm-logical-tree-1.2.1.tgz#44610141ca24664cad35d1e607176193fd8f5b88"
- integrity sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg==
-
npm-normalize-package-bin@^1.0.0, 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"
@@ -27169,7 +27407,7 @@ npm-package-arg@8.1.5, npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-packa
semver "^7.3.4"
validate-npm-package-name "^3.0.0"
-"npm-package-arg@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0, npm-package-arg@^6.1.1:
+"npm-package-arg@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0:
version "6.1.1"
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7"
integrity sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==
@@ -27179,7 +27417,16 @@ npm-package-arg@8.1.5, npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-packa
semver "^5.6.0"
validate-npm-package-name "^3.0.0"
-npm-packlist@^1.1.12, npm-packlist@^1.4.4, npm-packlist@^1.4.8:
+npm-package-arg@^9.0.0, npm-package-arg@^9.0.1, 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-packlist@^1.4.4:
version "1.4.8"
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
@@ -27208,6 +27455,16 @@ npm-packlist@^3.0.0:
npm-bundled "^1.1.1"
npm-normalize-package-bin "^1.0.1"
+npm-packlist@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.0.tgz#f3fd52903a021009913a133732022132eb355ce7"
+ integrity sha512-a04sqF6FbkyOAFA19AA0e94gS7Et5T2/IMj3VOT9nOF2RaRdVPQ1Q17Fb/HaDRFs+gbC7HOmhVZ29adpWgmDZg==
+ 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@6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.0.tgz#2befed87b0fce956790f62d32afb56d7539c022a"
@@ -27227,7 +27484,7 @@ npm-pick-manifest@6.1.1, npm-pick-manifest@^6.0.0, npm-pick-manifest@^6.1.1:
npm-package-arg "^8.1.2"
semver "^7.3.4"
-npm-pick-manifest@^3.0.0, npm-pick-manifest@^3.0.2:
+npm-pick-manifest@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-3.0.2.tgz#f4d9e5fd4be2153e5f4e5f9b7be8dc419a99abb7"
integrity sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==
@@ -27236,14 +27493,23 @@ npm-pick-manifest@^3.0.0, npm-pick-manifest@^3.0.2:
npm-package-arg "^6.0.0"
semver "^5.4.1"
-npm-profile@^4.0.2, npm-profile@^4.0.4:
- version "4.0.4"
- resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-4.0.4.tgz#28ee94390e936df6d084263ee2061336a6a1581b"
- integrity sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ==
+npm-pick-manifest@^7.0.0, npm-pick-manifest@^7.0.1:
+ 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:
- aproba "^1.1.2 || 2"
- figgy-pudding "^3.4.1"
- npm-registry-fetch "^4.0.0"
+ npm-install-checks "^5.0.0"
+ npm-normalize-package-bin "^1.0.1"
+ npm-package-arg "^9.0.0"
+ semver "^7.3.5"
+
+npm-profile@^6.0.3:
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-6.0.3.tgz#f4a11ce09467f00fa0832db7f27992e55fdfc94b"
+ integrity sha512-TVeHhnol2Iemud+Sr70/uqax5LnLJ9y361w+m5+Z7WYV2B1t6FhRDxDu72+yYYTvsgshkhnXEqbPjuD87kYXfA==
+ dependencies:
+ npm-registry-fetch "^13.0.1"
+ proc-log "^2.0.0"
npm-registry-client@^8.6.0:
version "8.6.0"
@@ -27276,18 +27542,18 @@ npm-registry-fetch@^11.0.0:
minizlib "^2.0.0"
npm-package-arg "^8.0.0"
-npm-registry-fetch@^4.0.0, npm-registry-fetch@^4.0.7:
- version "4.0.7"
- resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.7.tgz#57951bf6541e0246b34c9f9a38ab73607c9449d7"
- integrity sha512-cny9v0+Mq6Tjz+e0erFAB+RYJ/AVGzkjnISiobqP8OWj9c9FLoZZu8/SPSKJWE17F1tk4018wfjV+ZbIbqC7fQ==
+npm-registry-fetch@^13.0.0, npm-registry-fetch@^13.0.1, npm-registry-fetch@^13.1.1:
+ version "13.1.1"
+ resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-13.1.1.tgz#26dc4b26d0a545886e807748032ba2aefaaae96b"
+ integrity sha512-5p8rwe6wQPLJ8dMqeTnA57Dp9Ox6GH9H60xkyJup07FmVlu3Mk7pf/kIIpl9gaN5bM8NM+UUx3emUWvDNTt39w==
dependencies:
- JSONStream "^1.3.4"
- bluebird "^3.5.1"
- figgy-pudding "^3.4.1"
- lru-cache "^5.1.1"
- make-fetch-happen "^5.0.0"
- npm-package-arg "^6.1.0"
- safe-buffer "^5.2.0"
+ 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-registry-fetch@^9.0.0:
version "9.0.0"
@@ -27344,128 +27610,83 @@ npm-user-validate@^1.0.1:
resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.1.tgz#31428fc5475fe8416023f178c0ab47935ad8c561"
integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw==
-npm@^6.14.9:
- version "6.14.11"
- resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.11.tgz#e0b5598d7b9a42d275e61d8bd28cd7eee0074a3b"
- integrity sha512-1Zh7LjuIoEhIyjkBflSSGzfjuPQwDlghNloppjruOH5bmj9midT9qcNT0tRUZRR04shU9ekrxNy9+UTBrqeBpQ==
- dependencies:
- JSONStream "^1.3.5"
+npm@^8.3.0:
+ version "8.12.1"
+ resolved "https://registry.yarnpkg.com/npm/-/npm-8.12.1.tgz#624064fa7a8e0730223f6b2effe087e7127d567b"
+ integrity sha512-0yOlhfgu1UzP6UijnaFuIS2bES2H9D90EA5OVsf2iOZw7VBrjntXKEwKfCaFA6vMVWkCP8qnPwCxxPdnDVwlNw==
+ dependencies:
+ "@isaacs/string-locale-compare" "^1.1.0"
+ "@npmcli/arborist" "^5.0.4"
+ "@npmcli/ci-detect" "^2.0.0"
+ "@npmcli/config" "^4.1.0"
+ "@npmcli/fs" "^2.1.0"
+ "@npmcli/map-workspaces" "^2.0.3"
+ "@npmcli/package-json" "^2.0.0"
+ "@npmcli/run-script" "^3.0.1"
abbrev "~1.1.1"
- ansicolors "~0.3.2"
- ansistyles "~0.1.3"
- aproba "^2.0.0"
archy "~1.0.0"
- bin-links "^1.1.8"
- bluebird "^3.5.5"
- byte-size "^5.0.1"
- cacache "^12.0.3"
- call-limit "^1.1.1"
- chownr "^1.1.4"
- ci-info "^2.0.0"
- cli-columns "^3.1.2"
- cli-table3 "^0.5.1"
- cmd-shim "^3.0.3"
- columnify "~1.5.4"
- config-chain "^1.1.12"
- detect-indent "~5.0.0"
- detect-newline "^2.1.0"
- dezalgo "~1.0.3"
- editor "~1.0.0"
- figgy-pudding "^3.5.1"
- find-npm-prefix "^1.0.2"
- fs-vacuum "~1.2.10"
- fs-write-stream-atomic "~1.0.10"
- gentle-fs "^2.3.1"
- glob "^7.1.6"
- graceful-fs "^4.2.4"
- has-unicode "~2.0.1"
- hosted-git-info "^2.8.8"
- iferr "^1.0.2"
- infer-owner "^1.0.4"
- inflight "~1.0.6"
- inherits "^2.0.4"
- ini "^1.3.8"
- init-package-json "^1.10.3"
- is-cidr "^3.0.0"
- json-parse-better-errors "^1.0.2"
- lazy-property "~1.0.0"
- libcipm "^4.0.8"
- libnpm "^3.0.1"
- libnpmaccess "^3.0.2"
- libnpmhook "^5.0.3"
- libnpmorg "^1.0.1"
- libnpmsearch "^2.0.2"
- libnpmteam "^1.0.2"
- libnpx "^10.2.4"
- lock-verify "^2.1.0"
- lockfile "^1.0.4"
- lodash._baseuniq "~4.6.0"
- lodash.clonedeep "~4.5.0"
- lodash.union "~4.6.0"
- lodash.uniq "~4.5.0"
- lodash.without "~4.4.0"
- lru-cache "^5.1.1"
- meant "^1.0.2"
- mississippi "^3.0.0"
- mkdirp "^0.5.5"
- move-concurrently "^1.0.1"
- node-gyp "^5.1.0"
- nopt "^4.0.3"
- normalize-package-data "^2.5.0"
- npm-audit-report "^1.3.3"
- npm-cache-filename "~1.0.2"
- npm-install-checks "^3.0.2"
- npm-lifecycle "^3.1.5"
- npm-package-arg "^6.1.1"
- npm-packlist "^1.4.8"
- npm-pick-manifest "^3.0.2"
- npm-profile "^4.0.4"
- npm-registry-fetch "^4.0.7"
+ cacache "^16.1.0"
+ chalk "^4.1.2"
+ chownr "^2.0.0"
+ cli-columns "^4.0.0"
+ cli-table3 "^0.6.2"
+ columnify "^1.6.0"
+ fastest-levenshtein "^1.0.12"
+ glob "^8.0.1"
+ graceful-fs "^4.2.10"
+ hosted-git-info "^5.0.0"
+ ini "^3.0.0"
+ init-package-json "^3.0.2"
+ is-cidr "^4.0.2"
+ json-parse-even-better-errors "^2.3.1"
+ libnpmaccess "^6.0.2"
+ libnpmdiff "^4.0.2"
+ libnpmexec "^4.0.2"
+ libnpmfund "^3.0.1"
+ libnpmhook "^8.0.2"
+ libnpmorg "^4.0.2"
+ libnpmpack "^4.0.2"
+ libnpmpublish "^6.0.2"
+ libnpmsearch "^5.0.2"
+ libnpmteam "^4.0.2"
+ libnpmversion "^3.0.1"
+ make-fetch-happen "^10.1.6"
+ minipass "^3.1.6"
+ minipass-pipeline "^1.2.4"
+ mkdirp "^1.0.4"
+ mkdirp-infer-owner "^2.0.0"
+ ms "^2.1.2"
+ node-gyp "^9.0.0"
+ nopt "^5.0.0"
+ npm-audit-report "^3.0.0"
+ npm-install-checks "^5.0.0"
+ npm-package-arg "^9.0.2"
+ npm-pick-manifest "^7.0.1"
+ npm-profile "^6.0.3"
+ npm-registry-fetch "^13.1.1"
npm-user-validate "^1.0.1"
- npmlog "~4.1.2"
- once "~1.4.0"
+ npmlog "^6.0.2"
opener "^1.5.2"
- osenv "^0.1.5"
- pacote "^9.5.12"
- path-is-inside "~1.0.2"
- promise-inflight "~1.0.1"
+ pacote "^13.6.0"
+ parse-conflict-json "^2.0.2"
+ proc-log "^2.0.1"
qrcode-terminal "^0.12.0"
- query-string "^6.8.2"
- qw "~1.0.1"
read "~1.0.7"
- read-cmd-shim "^1.0.5"
- read-installed "~4.0.3"
- read-package-json "^2.1.1"
- read-package-tree "^5.3.1"
- readable-stream "^3.6.0"
+ read-package-json "^5.0.1"
+ read-package-json-fast "^2.0.3"
readdir-scoped-modules "^1.1.0"
- request "^2.88.0"
- retry "^0.12.0"
- rimraf "^2.7.1"
- safe-buffer "^5.1.2"
- semver "^5.7.1"
- sha "^3.0.0"
- slide "~1.1.6"
- sorted-object "~2.0.1"
- sorted-union-stream "~2.1.3"
- ssri "^6.0.1"
- stringify-package "^1.0.1"
- tar "^4.4.13"
+ rimraf "^3.0.2"
+ semver "^7.3.7"
+ ssri "^9.0.1"
+ tar "^6.1.11"
text-table "~0.2.0"
tiny-relative-date "^1.3.0"
- uid-number "0.0.6"
- umask "~1.1.0"
- unique-filename "^1.1.1"
- unpipe "~1.0.0"
- update-notifier "^2.5.0"
- uuid "^3.3.3"
- validate-npm-package-license "^3.0.4"
- validate-npm-package-name "~3.0.0"
- which "^1.3.1"
- worker-farm "^1.7.0"
- write-file-atomic "^2.4.3"
+ treeverse "^2.0.0"
+ validate-npm-package-name "^4.0.0"
+ which "^2.0.2"
+ write-file-atomic "^4.0.1"
-"npmlog@2 || ^3.1.0 || ^4.0.0", npmlog@^4.0.1, npmlog@^4.1.2, npmlog@~4.1.2:
+"npmlog@2 || ^3.1.0 || ^4.0.0", npmlog@^4.0.1, npmlog@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
@@ -27475,7 +27696,7 @@ npm@^6.14.9:
gauge "~2.7.3"
set-blocking "~2.0.0"
-npmlog@^6.0.0:
+npmlog@^6.0.0, npmlog@^6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830"
integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==
@@ -27776,7 +27997,7 @@ on-headers@~1.0.1, 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.3.2, once@^1.3.3, once@^1.4.0, once@~1.4.0:
+once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.3.3, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
@@ -28309,16 +28530,6 @@ package-hash@^4.0.0:
lodash.flattendeep "^4.4.0"
release-zalgo "^1.0.0"
-package-json@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed"
- integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=
- dependencies:
- got "^6.7.1"
- registry-auth-token "^3.0.1"
- registry-url "^3.0.3"
- semver "^5.1.0"
-
package-json@^6.3.0:
version "6.5.0"
resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0"
@@ -28379,41 +28590,32 @@ pacote@12.0.2:
ssri "^8.0.1"
tar "^6.1.0"
-pacote@^9.1.0, pacote@^9.5.12, pacote@^9.5.3:
- version "9.5.12"
- resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.12.tgz#1e11dd7a8d736bcc36b375a9804d41bb0377bf66"
- integrity sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ==
+pacote@^13.0.3, pacote@^13.0.5, pacote@^13.5.0, pacote@^13.6.0:
+ version "13.6.0"
+ resolved "https://registry.yarnpkg.com/pacote/-/pacote-13.6.0.tgz#79ea3d3ae5a2b29e2994dcf18d75494e8d888032"
+ integrity sha512-zHmuCwG4+QKnj47LFlW3LmArwKoglx2k5xtADiMCivVWPgNRP5QyLDGOIjGjwOe61lhl1rO63m/VxT16pEHLWg==
dependencies:
- bluebird "^3.5.3"
- cacache "^12.0.2"
- chownr "^1.1.2"
- figgy-pudding "^3.5.1"
- get-stream "^4.1.0"
- glob "^7.1.3"
+ "@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"
- lru-cache "^5.1.1"
- make-fetch-happen "^5.0.0"
- minimatch "^3.0.4"
- minipass "^2.3.5"
- mississippi "^3.0.0"
- mkdirp "^0.5.1"
- normalize-package-data "^2.4.0"
- npm-normalize-package-bin "^1.0.0"
- npm-package-arg "^6.1.0"
- npm-packlist "^1.1.12"
- npm-pick-manifest "^3.0.0"
- npm-registry-fetch "^4.0.0"
- osenv "^0.1.5"
- promise-inflight "^1.0.1"
- promise-retry "^1.1.1"
- protoduck "^5.0.1"
- rimraf "^2.6.2"
- safe-buffer "^5.1.2"
- semver "^5.6.0"
- ssri "^6.0.1"
- tar "^4.4.10"
- unique-filename "^1.1.1"
- which "^1.3.1"
+ minipass "^3.1.6"
+ mkdirp "^1.0.4"
+ npm-package-arg "^9.0.0"
+ npm-packlist "^5.1.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"
pad-component@^0.0.1:
version "0.0.1"
@@ -28499,6 +28701,15 @@ parse-bmfont-xml@^1.1.4:
xml-parse-from-string "^1.0.0"
xml2js "^0.4.5"
+parse-conflict-json@^2.0.1, parse-conflict-json@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/parse-conflict-json/-/parse-conflict-json-2.0.2.tgz#3d05bc8ffe07d39600dc6436c6aefe382033d323"
+ integrity sha512-jDbRGb00TAPFsKWCpZZOT93SxVP9nONOSgES3AevqRq/CHvavEBvKAjxX9p5Y5F0RZLxH9Ufd9+RwtCsa+lFDA==
+ dependencies:
+ json-parse-even-better-errors "^2.3.1"
+ just-diff "^5.0.1"
+ just-diff-apply "^5.2.0"
+
parse-filepath@^1.0.1, parse-filepath@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891"
@@ -28764,7 +28975,7 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
-path-is-inside@1.0.2, path-is-inside@^1.0.1, path-is-inside@^1.0.2, path-is-inside@~1.0.2:
+path-is-inside@1.0.2, path-is-inside@^1.0.1, 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 sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
@@ -28856,7 +29067,7 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
-pathe@0.2.0:
+pathe@0.2.0, pathe@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/pathe/-/pathe-0.2.0.tgz#30fd7bbe0a0d91f0e60bae621f5d19e9e225c339"
integrity sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==
@@ -28914,10 +29125,10 @@ picocolors@^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.2.2, picomatch@^2.2.3:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
- integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
+ integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pidtree@^0.3.0:
version "0.3.1"
@@ -30168,7 +30379,7 @@ prelude-ls@~1.1.2:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
-prepend-http@^1.0.0, prepend-http@^1.0.1:
+prepend-http@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
@@ -30272,6 +30483,11 @@ private@^0.1.6, private@^0.1.8, private@~0.1.5:
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
+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-es6@^0.11.2:
version "0.11.6"
resolved "https://registry.yarnpkg.com/process-es6/-/process-es6-0.11.6.tgz#c6bb389f9a951f82bd4eb169600105bd2ff9c778"
@@ -30299,7 +30515,17 @@ progress@^2.0.0, progress@^2.0.3:
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
-promise-inflight@^1.0.1, promise-inflight@~1.0.1:
+promise-all-reject-late@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz#f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2"
+ integrity sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==
+
+promise-call-limit@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/promise-call-limit/-/promise-call-limit-1.0.1.tgz#4bdee03aeb85674385ca934da7114e9bcd3c6e24"
+ integrity sha512-3+hgaa19jzCGLuSCbieeRsu5C2joKfYn8pY6JAuXFRVfF4IO+L7UPpFWNTeWT9pM7uhskvbPPd/oEOktCn317Q==
+
+promise-inflight@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
@@ -30693,7 +30919,7 @@ query-string@^5.0.1:
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
-query-string@^6.13.8, query-string@^6.8.2:
+query-string@^6.13.8:
version "6.14.1"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a"
integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==
@@ -30757,11 +30983,6 @@ quote@0.4.0:
resolved "https://registry.yarnpkg.com/quote/-/quote-0.4.0.tgz#10839217f6c1362b89194044d29b233fd7f32f01"
integrity sha1-EIOSF/bBNiuJGUBE0psjP9fzLwE=
-qw@~1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/qw/-/qw-1.0.1.tgz#efbfdc740f9ad054304426acb183412cc8b996d4"
- integrity sha1-77/cdA+a0FQwRCassYNBLMi5ltQ=
-
raf@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
@@ -31287,13 +31508,18 @@ read-chunk@^1.0.1:
resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194"
integrity sha1-X2jKswfmY/GZk1J9m1icrORmEZQ=
-read-cmd-shim@^1.0.1, read-cmd-shim@^1.0.5:
+read-cmd-shim@^1.0.1:
version "1.0.5"
resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16"
integrity sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA==
dependencies:
graceful-fs "^4.1.2"
+read-cmd-shim@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-3.0.0.tgz#62b8c638225c61e6cc607f8f4b779f3b8238f155"
+ integrity sha512-KQDVjGqhZk92PPNRj9ZEXEuqg8bUobSKRw+q0YQ3TKI5xkce7bUJobL4Z/OtiEbAAv70yEpYIXp4iQ9L8oPVog==
+
read-config-file@6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-6.2.0.tgz#71536072330bcd62ba814f91458b12add9fc7ade"
@@ -31305,20 +31531,6 @@ read-config-file@6.2.0:
json5 "^2.2.0"
lazy-val "^1.0.4"
-read-installed@~4.0.3:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067"
- integrity sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=
- dependencies:
- debuglog "^1.0.1"
- read-package-json "^2.0.0"
- readdir-scoped-modules "^1.0.0"
- semver "2 || 3 || 4 || 5"
- slide "~1.1.3"
- util-extend "^1.0.1"
- optionalDependencies:
- graceful-fs "^4.1.2"
-
read-only-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0"
@@ -31334,15 +31546,15 @@ read-package-json-fast@^1.1.3:
json-parse-even-better-errors "^2.3.0"
npm-normalize-package-bin "^1.0.1"
-read-package-json-fast@^2.0.1:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.2.tgz#2dcb24d9e8dd50fb322042c8c35a954e6cc7ac9e"
- integrity sha512-5fyFUyO9B799foVk4n6ylcoAktG/FbE3jwRKxvwaeSrIunaoMc0u81dzXxjeAFKOce7O5KncdfwpGvvs6r5PsQ==
+read-package-json-fast@^2.0.1, read-package-json-fast@^2.0.2, 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@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.10, read-package-json@^2.0.13, read-package-json@^2.0.4, read-package-json@^2.1.1:
+"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@^2.0.10, read-package-json@^2.0.13, read-package-json@^2.0.4:
version "2.1.2"
resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a"
integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==
@@ -31352,7 +31564,17 @@ read-package-json-fast@^2.0.1:
normalize-package-data "^2.0.0"
npm-normalize-package-bin "^1.0.0"
-read-package-tree@^5.1.6, read-package-tree@^5.3.1:
+read-package-json@^5.0.0, read-package-json@^5.0.1:
+ 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"
+
+read-package-tree@^5.1.6:
version "5.3.1"
resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.3.1.tgz#a32cb64c7f31eb8a6f31ef06f9cedf74068fe636"
integrity sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==
@@ -31439,7 +31661,7 @@ read-pkg@^5.0.0, read-pkg@^5.2.0:
parse-json "^5.0.0"
type-fest "^0.6.0"
-read@1, read@~1.0.1, read@~1.0.7:
+read@1, read@^1.0.7, read@~1.0.1, read@~1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=
@@ -31459,7 +31681,7 @@ read@1, read@~1.0.1, read@~1.0.7:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-readable-stream@1.1.x, readable-stream@^1.0.26-4, readable-stream@~1.1.10:
+readable-stream@1.1.x, readable-stream@^1.0.26-4:
version "1.1.14"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
@@ -31802,7 +32024,7 @@ regexpu@^1.3.0:
regjsgen "^0.2.0"
regjsparser "^0.1.4"
-registry-auth-token@3.3.2, registry-auth-token@^3.0.1:
+registry-auth-token@3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20"
integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==
@@ -31833,7 +32055,7 @@ registry-js@1.8.0:
nan "^2.10.0"
prebuild-install "^5.2.4"
-registry-url@3.1.0, registry-url@^3.0.3:
+registry-url@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942"
integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI=
@@ -32376,7 +32598,7 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
-rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1:
+rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
@@ -32827,50 +33049,16 @@ semantic-release-plugin-decorators@^3.0.0:
resolved "https://registry.yarnpkg.com/semantic-release-plugin-decorators/-/semantic-release-plugin-decorators-3.0.1.tgz#961b5fec7e1ab113aa10aed5256ee7c3ee6804d9"
integrity sha512-f5Qjvv/AJYByvkaj11a+05gQwfPwgQKo5OIhj8YVM2Dhf2rOPEOLD83jGrTdM7Nuf//sZYw77/cGUSVygUG9Kg==
-semantic-release@17.2.3:
- version "17.2.3"
- resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-17.2.3.tgz#11f10b851d4e75b1015b17515c433049b3df994c"
- integrity sha512-MY1MlowGQrkOR7+leOD8ICkVOC6i1szbwDODdbJ0UdshtMx8Ms0bhpRQmEEliqYKEb5PLv/dqs6zKKuHT7UxTg==
+semantic-release@19.0.3:
+ version "19.0.3"
+ resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-19.0.3.tgz#9291053ad9890052f28e7c5921d4741530d516fd"
+ integrity sha512-HaFbydST1cDKZHuFZxB8DTrBLJVK/AnDExpK0s3EqLIAAUAHUgnd+VSJCUtTYQKkAkauL8G9CucODrVCc7BuAA==
dependencies:
- "@semantic-release/commit-analyzer" "^8.0.0"
- "@semantic-release/error" "^2.2.0"
- "@semantic-release/github" "^7.0.0"
- "@semantic-release/npm" "^7.0.0"
- "@semantic-release/release-notes-generator" "^9.0.0"
- aggregate-error "^3.0.0"
- cosmiconfig "^6.0.0"
- debug "^4.0.0"
- env-ci "^5.0.0"
- execa "^4.0.0"
- figures "^3.0.0"
- find-versions "^3.0.0"
- get-stream "^5.0.0"
- git-log-parser "^1.2.0"
- hook-std "^2.0.0"
- hosted-git-info "^3.0.0"
- lodash "^4.17.15"
- marked "^1.0.0"
- marked-terminal "^4.0.0"
- micromatch "^4.0.2"
- p-each-series "^2.1.0"
- p-reduce "^2.0.0"
- read-pkg-up "^7.0.0"
- resolve-from "^5.0.0"
- semver "^7.3.2"
- semver-diff "^3.1.1"
- signale "^1.2.1"
- yargs "^15.0.1"
-
-semantic-release@17.4.2:
- version "17.4.2"
- resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-17.4.2.tgz#b5147b5a629c227b7074ad4cc89920a14cb08c96"
- integrity sha512-TPLWuoe2L2DmgnQEh+OLWW5V1T+ZAa1xWuHXsuPAWEko0BqSdLPl+5+BlQ+D5Bp27S5gDJ1//Y1tgbmvUhnOCw==
- dependencies:
- "@semantic-release/commit-analyzer" "^8.0.0"
- "@semantic-release/error" "^2.2.0"
- "@semantic-release/github" "^7.0.0"
- "@semantic-release/npm" "^7.0.0"
- "@semantic-release/release-notes-generator" "^9.0.0"
+ "@semantic-release/commit-analyzer" "^9.0.2"
+ "@semantic-release/error" "^3.0.0"
+ "@semantic-release/github" "^8.0.0"
+ "@semantic-release/npm" "^9.0.0"
+ "@semantic-release/release-notes-generator" "^10.0.0"
aggregate-error "^3.0.0"
cosmiconfig "^7.0.0"
debug "^4.0.0"
@@ -32882,9 +33070,9 @@ semantic-release@17.4.2:
git-log-parser "^1.2.0"
hook-std "^2.0.0"
hosted-git-info "^4.0.0"
- lodash "^4.17.15"
- marked "^2.0.0"
- marked-terminal "^4.1.1"
+ lodash "^4.17.21"
+ marked "^4.0.10"
+ marked-terminal "^5.0.0"
micromatch "^4.0.2"
p-each-series "^2.1.0"
p-reduce "^2.0.0"
@@ -32905,13 +33093,6 @@ semver-compare@^1.0.0:
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
-semver-diff@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
- integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=
- dependencies:
- semver "^5.0.3"
-
semver-diff@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
@@ -32940,17 +33121,12 @@ semver-intersect@1.4.0:
dependencies:
semver "^5.0.0"
-semver-regex@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338"
- integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==
-
semver-regex@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.2.tgz#34b4c0d361eef262e07199dbef316d0f2ab11807"
integrity sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==
-"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.0, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
+"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -32989,7 +33165,7 @@ semver@7.3.5:
dependencies:
lru-cache "^6.0.0"
-semver@7.3.7, semver@^7.0.0, semver@^7.1.1, semver@^7.1.2, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5:
+semver@7.3.7, semver@^7.0.0, semver@^7.1.1, semver@^7.1.2, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7:
version "7.3.7"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
@@ -33206,13 +33382,6 @@ sha.js@^2.4.0, sha.js@^2.4.8, sha.js@~2.4.4:
inherits "^2.0.1"
safe-buffer "^5.0.1"
-sha@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/sha/-/sha-3.0.0.tgz#b2f2f90af690c16a3a839a6a6c680ea51fedd1ae"
- integrity sha512-DOYnM37cNsLNSGIG/zZWch5CKIRNoLdYUQTQlcgkRkoYIUwDYjqDyye16YcDZg/OPdcbUgTKMjc4SY6TB7ZAPw==
- dependencies:
- graceful-fs "^4.1.2"
-
shallow-clone@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060"
@@ -33650,7 +33819,7 @@ slice-ansi@^4.0.0:
astral-regex "^2.0.0"
is-fullwidth-code-point "^3.0.0"
-slide@^1.1.3, slide@^1.1.5, slide@^1.1.6, slide@~1.1.3, slide@~1.1.6:
+slide@^1.1.3, slide@^1.1.5, slide@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707"
integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=
@@ -33969,6 +34138,15 @@ socks-proxy-agent@^6.0.0:
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.3.3, socks@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a"
@@ -34023,19 +34201,6 @@ sort-package-json@^1.22.1:
is-plain-obj "2.1.0"
sort-object-keys "^1.1.3"
-sorted-object@~2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc"
- integrity sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw=
-
-sorted-union-stream@~2.1.3:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/sorted-union-stream/-/sorted-union-stream-2.1.3.tgz#c7794c7e077880052ff71a8d4a2dbb4a9a638ac7"
- integrity sha1-x3lMfgd4gAUv9xqNSi27Sppjisc=
- dependencies:
- from2 "^1.3.0"
- stream-iterate "^1.1.0"
-
source-list-map@^2.0.0, source-list-map@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
@@ -34382,6 +34547,13 @@ ssri@^8.0.0, ssri@^8.0.1:
dependencies:
minipass "^3.1.1"
+ssri@^9.0.0, ssri@^9.0.1:
+ 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"
+
stable@^0.1.8, stable@~0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
@@ -34501,14 +34673,6 @@ stream-http@^2.0.0, stream-http@^2.7.2:
to-arraybuffer "^1.0.0"
xtend "^4.0.0"
-stream-iterate@^1.1.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/stream-iterate/-/stream-iterate-1.2.0.tgz#2bd7c77296c1702a46488b8ad41f79865eecd4e1"
- integrity sha1-K9fHcpbBcCpGSIuK1B95hl7s1OE=
- dependencies:
- readable-stream "^2.1.5"
- stream-shift "^1.0.0"
-
"stream-parser@>= 0.0.2":
version "0.3.1"
resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773"
@@ -34703,11 +34867,6 @@ stringify-object@^3.0.0, stringify-object@^3.3.0:
is-obj "^1.0.1"
is-regexp "^1.0.0"
-stringify-package@^1.0.0, stringify-package@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85"
- integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==
-
stringmap@~0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/stringmap/-/stringmap-0.2.2.tgz#556c137b258f942b8776f5b2ef582aa069d7d1b1"
@@ -35078,7 +35237,7 @@ supports-color@^7.0.0, supports-color@^7.1.0, supports-color@^7.2.0:
dependencies:
has-flag "^4.0.0"
-supports-hyperlinks@^2.1.0:
+supports-hyperlinks@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb"
integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==
@@ -35286,7 +35445,7 @@ tar@^2.2.2:
fstream "^1.0.12"
inherits "2"
-tar@^4.4.10, tar@^4.4.12, tar@^4.4.13, tar@^4.4.8:
+tar@^4.4.10, tar@^4.4.12, tar@^4.4.8:
version "4.4.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
@@ -35299,7 +35458,7 @@ tar@^4.4.10, tar@^4.4.12, tar@^4.4.13, tar@^4.4.8:
safe-buffer "^5.1.2"
yallist "^3.0.3"
-tar@^6.0.2, tar@^6.1.0, tar@^6.1.2:
+tar@^6.0.2, tar@^6.1.0, 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==
@@ -35629,7 +35788,7 @@ time-stamp@^1.0.0:
resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3"
integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=
-timed-out@^4.0.0, timed-out@^4.0.1:
+timed-out@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
@@ -35915,6 +36074,11 @@ tree-kill@1.2.2, tree-kill@^1.2.2:
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
+treeverse@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/treeverse/-/treeverse-2.0.0.tgz#036dcef04bc3fd79a9b79a68d4da03e882d8a9ca"
+ integrity sha512-N5gJCkLu1aXccpOTtqV6ddSEi6ZmGkh3hjmbu1IjcavJK4qyOVQmi0myQKM7z5jVGmD68SJoliaVrMmVObhj6A==
+
trim-newlines@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
@@ -35930,11 +36094,6 @@ trim-newlines@^3.0.0:
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30"
integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==
-trim-off-newlines@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3"
- integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM=
-
trim-repeated@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21"
@@ -36091,7 +36250,7 @@ tslib@2.1.0, tslib@~2.1.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
-tslib@2.3.1, tslib@^2, tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.0, tslib@^2.3.1, tslib@~2.3.0:
+tslib@2.3.1, tslib@~2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
@@ -36101,6 +36260,11 @@ tslib@^1.0.0, tslib@^1.10.0, tslib@^1.11.1, tslib@^1.13.0, tslib@^1.8.0, tslib@^
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
+tslib@^2, tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.0, tslib@^2.3.1, tslib@~2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
+ integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
+
tslib@~2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c"
@@ -36288,6 +36452,11 @@ type-fest@^0.8.0, type-fest@^0.8.1:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
+type-fest@^1.0.2:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1"
+ integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==
+
type-fest@^2.3.4:
version "2.3.4"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.3.4.tgz#59bd28c5715a7ea39f8fb0d7e424355ae231a24e"
@@ -36407,7 +36576,7 @@ ultron@~1.1.0:
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==
-umask@^1.1.0, umask@~1.1.0:
+umask@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d"
integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=
@@ -36571,13 +36740,6 @@ unique-stream@^2.0.2:
json-stable-stringify-without-jsonify "^1.0.1"
through2-filter "^3.0.0"
-unique-string@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a"
- integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=
- dependencies:
- crypto-random-string "^1.0.0"
-
unique-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"
@@ -36717,11 +36879,6 @@ unused-filename@^2.1.0:
modify-filename "^1.1.0"
path-exists "^4.0.0"
-unzip-response@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97"
- integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=
-
upath@^1.1.1, upath@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
@@ -36740,22 +36897,6 @@ update-check@1.5.2:
registry-auth-token "3.3.2"
registry-url "3.1.0"
-update-notifier@^2.2.0, update-notifier@^2.3.0, update-notifier@^2.5.0:
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6"
- integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==
- dependencies:
- boxen "^1.2.1"
- chalk "^2.0.1"
- configstore "^3.0.0"
- import-lazy "^2.1.0"
- is-ci "^1.0.10"
- is-installed-globally "^0.1.0"
- is-npm "^1.0.0"
- latest-version "^3.0.0"
- semver-diff "^2.0.0"
- xdg-basedir "^3.0.0"
-
update-notifier@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9"
@@ -36833,13 +36974,6 @@ url-loader@2.1.0:
mime "^2.4.4"
schema-utils "^2.0.0"
-url-parse-lax@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
- integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=
- dependencies:
- prepend-http "^1.0.1"
-
url-parse-lax@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
@@ -36944,11 +37078,6 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-util-extend@^1.0.1:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f"
- integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=
-
util-promisify@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/util-promisify/-/util-promisify-2.1.0.tgz#3c2236476c4d32c5ff3c47002add7c13b9a82a53"
@@ -37054,13 +37183,20 @@ validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3, valida
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
-validate-npm-package-name@^3.0.0, validate-npm-package-name@~3.0.0:
+validate-npm-package-name@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e"
integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34=
dependencies:
builtins "^1.0.3"
+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"
+
validator@^7.0.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/validator/-/validator-7.2.0.tgz#a63dcbaba51d4350bf8df20988e0d5a54d711791"
@@ -37267,13 +37403,13 @@ vite-plugin-windicss@1.2.4:
debug "^4.3.2"
windicss "^3.1.4"
-vite-plugin-windicss@^1.4.7:
- version "1.8.2"
- resolved "https://registry.yarnpkg.com/vite-plugin-windicss/-/vite-plugin-windicss-1.8.2.tgz#0d07964018d6d0f97bb2a02a452b6bc1e66ba968"
- integrity sha512-tO9bCoqIW945ehwMr9D41YPods8b7HXtVtYVPx62dxadxlbcoD7PQ/8wSvLEiIkMMfuDG5WQ6LZaUdmfALC/vQ==
+vite-plugin-windicss@^1.4.7, vite-plugin-windicss@^1.8.4:
+ version "1.8.4"
+ resolved "https://registry.yarnpkg.com/vite-plugin-windicss/-/vite-plugin-windicss-1.8.4.tgz#98430706691d54d6b9bf43ac0e3c74dd26b10664"
+ integrity sha512-LSZAO8BZn3x406GRbYX5t5ONXXJVdqiQtN1qrznLA/Dy5/NzZVhfcrL6N1qEYYO7HsCDT4pLAjTzObvDnM9Y8A==
dependencies:
- "@windicss/plugin-utils" "1.8.2"
- debug "^4.3.3"
+ "@windicss/plugin-utils" "1.8.4"
+ debug "^4.3.4"
kolorist "^1.5.1"
windicss "^3.5.1"
@@ -37581,6 +37717,11 @@ wait-on@4.0.0:
request-promise-native "^1.0.8"
rxjs "^6.5.4"
+walk-up-path@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-1.0.0.tgz#d4745e893dd5fd0dbb58dd0a4c6a33d9c9fec53e"
+ integrity sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==
+
walker@^1.0.7, walker@~1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
@@ -38310,10 +38451,19 @@ windicss-analysis@^0.3.4:
fs-extra "^10.0.0"
sirv "^1.0.12"
-windicss@3.1.4:
- version "3.1.4"
- resolved "https://registry.yarnpkg.com/windicss/-/windicss-3.1.4.tgz#557eaf8e3c08064a309ccb5d887c82c4bce25069"
- integrity sha512-3RBcANxdOy/n4dLVT8+0X409sGI+piO06ARbQ8RncxGuYgdw5Ip3hrhGIYajH67lV+tHc7xNVGxj73amOC9N0g==
+windicss-webpack-plugin@^1.6.10:
+ version "1.7.2"
+ resolved "https://registry.yarnpkg.com/windicss-webpack-plugin/-/windicss-webpack-plugin-1.7.2.tgz#e00382ba8b487813d340ba799effa26e1be3356b"
+ integrity sha512-7KopGPg63RXyJfsq/2OAHYoAFyIHSeexAk+MYMlW4CsBlEb+sw0Kt2v0gLgsPc1zs90oky1crAElKk+DDk8/5A==
+ dependencies:
+ "@windicss/plugin-utils" "^1.8.4"
+ debug "^4.3.4"
+ get-port "^6.1.2"
+ loader-utils "^2.0.0"
+ lodash "^4.17.21"
+ pathe "^0.2.0"
+ webpack-virtual-modules "^0.4.3"
+ windicss "^3.5.1"
windicss@^3.1.4, windicss@^3.5.1:
version "3.5.1"
@@ -38507,7 +38657,7 @@ workbox-window@^4.3.1:
dependencies:
workbox-core "^4.3.1"
-worker-farm@^1.6.0, worker-farm@^1.7.0:
+worker-farm@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==
@@ -38604,7 +38754,7 @@ write-file-atomic@^1.2.0:
imurmurhash "^0.1.4"
slide "^1.1.5"
-write-file-atomic@^2.0.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.2, write-file-atomic@^2.4.3:
+write-file-atomic@^2.0.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.2:
version "2.4.3"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481"
integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==
@@ -38623,6 +38773,14 @@ write-file-atomic@^3.0.0:
signal-exit "^3.0.2"
typedarray-to-buffer "^3.1.5"
+write-file-atomic@^4.0.0, write-file-atomic@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.1.tgz#9faa33a964c1c85ff6f849b80b42a88c2c537c8f"
+ integrity sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==
+ dependencies:
+ imurmurhash "^0.1.4"
+ signal-exit "^3.0.7"
+
write-json-file@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f"
@@ -38712,11 +38870,6 @@ xdg-basedir@^2.0.0:
dependencies:
os-homedir "^1.0.0"
-xdg-basedir@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
- integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=
-
xdg-basedir@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
@@ -38983,13 +39136,6 @@ yargs-parser@^20.0.0, yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
-yargs-parser@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9"
- integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k=
- dependencies:
- camelcase "^4.1.0"
-
yargs-parser@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950"
@@ -39140,7 +39286,7 @@ yargs@^12.0.5:
y18n "^3.2.1 || ^4.0.0"
yargs-parser "^11.1.1"
-yargs@^14.2.2, yargs@^14.2.3:
+yargs@^14.2.2:
version "14.2.3"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414"
integrity sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==
@@ -39157,7 +39303,7 @@ yargs@^14.2.2, yargs@^14.2.3:
y18n "^4.0.0"
yargs-parser "^15.0.1"
-yargs@^15.0.1, yargs@^15.0.2, yargs@^15.1.0, yargs@^15.3.1:
+yargs@^15.0.2, yargs@^15.1.0, yargs@^15.3.1:
version "15.4.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
@@ -39206,25 +39352,6 @@ yargs@^7.0.2, yargs@^7.1.0:
y18n "^3.2.1"
yargs-parser "5.0.0-security.0"
-yargs@^8.0.2:
- version "8.0.2"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360"
- integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A=
- dependencies:
- camelcase "^4.1.0"
- cliui "^3.2.0"
- decamelize "^1.1.1"
- get-caller-file "^1.0.1"
- os-locale "^2.0.0"
- read-pkg-up "^2.0.0"
- require-directory "^2.1.1"
- require-main-filename "^1.0.1"
- set-blocking "^2.0.0"
- string-width "^2.0.0"
- which-module "^2.0.0"
- y18n "^3.2.1"
- yargs-parser "^7.0.0"
-
yargs@~3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"