diff --git a/.github/workflows/health-check.yml b/.github/workflows/health-check.yml index 70294ac3..9bd93bb1 100644 --- a/.github/workflows/health-check.yml +++ b/.github/workflows/health-check.yml @@ -16,14 +16,13 @@ jobs: - uses: pnpm/action-setup@v4 with: - version: 10 run_install: false # https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping - - name: Use Node.js 24.x + - name: Use Node.js 22.x uses: actions/setup-node@v5 with: - node-version: 24.x + node-version: 22.x cache: pnpm - name: Install dependencies diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml deleted file mode 100644 index 3538a335..00000000 --- a/.github/workflows/pull-request.yml +++ /dev/null @@ -1,102 +0,0 @@ -name: Pull request - -on: - pull_request: - paths-ignore: - - '**.md' - -env: - CI: true - -jobs: - lint: - name: Lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - - uses: pnpm/action-setup@v4 - with: - version: 10 - run_install: false - - - name: Use Node.js 22.x - uses: actions/setup-node@v5 - with: - node-version: 22.x - cache: pnpm - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile - - - name: TypeScript check - run: pnpm lint - - - name: Eslint check - run: pnpm lint - - unit_test: - name: Unit test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - - uses: pnpm/action-setup@v4 - with: - version: 10 - run_install: false - - - name: Use Node.js 22.x - uses: actions/setup-node@v5 - with: - node-version: 22.x - cache: pnpm - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile - - - name: Unit test - run: pnpm test:unit - - - name: Update coverage report - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - - e2e_tests: - name: E2E test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - - uses: pnpm/action-setup@v4 - with: - version: 10 - run_install: false - - - name: Use Node.js 22.x - uses: actions/setup-node@v5 - with: - node-version: 22.x - cache: pnpm - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile - - - name: Get cypress version - id: cypress-version - run: echo "version=$(pnpm info cypress version)" >> $GITHUB_OUTPUT - - - name: Cache cypress binary - id: cache-cypress-binary - uses: actions/cache@v4 - with: - path: ~/.cache/Cypress - key: cypress-binary-${{ runner.os }}-${{ steps.cypress-version.outputs.version }} - - - name: Install cypress binary - if: steps.cache-cypress-binary.outputs.cache-hit != 'true' - run: pnpm cypress install - - - name: E2E test - run: pnpm test:e2e:ci diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 50363023..06d2112b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,6 +4,9 @@ on: push: paths-ignore: - '**.md' + pull_request: + paths-ignore: + - '**.md' env: CI: true @@ -17,13 +20,12 @@ jobs: - uses: pnpm/action-setup@v4 with: - version: 10 run_install: false - - name: Use Node.js 24.x + - name: Use Node.js 22.x uses: actions/setup-node@v5 with: - node-version: 24.x + node-version: 22.x cache: pnpm - name: Install dependencies @@ -43,13 +45,12 @@ jobs: - uses: pnpm/action-setup@v4 with: - version: 10 run_install: false - - name: Use Node.js 24.x + - name: Use Node.js 22.x uses: actions/setup-node@v5 with: - node-version: 24.x + node-version: 22.x cache: pnpm - name: Install dependencies @@ -62,41 +63,65 @@ jobs: uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage/unit/lcov.info + + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: unit-test-report + path: | + coverage/ + retention-days: 30 e2e_tests: - name: E2E test - runs-on: ubuntu-latest + name: Playwright E2E test + timeout-minutes: 10 + runs-on: macos-latest steps: - uses: actions/checkout@v5 - uses: pnpm/action-setup@v4 with: - version: 10 run_install: false - - name: Use Node.js 24.x - uses: actions/setup-node@v5 + - name: Use Node.js 22.x + uses: actions/setup-node@v4 with: - node-version: 24.x + node-version: 22.x cache: pnpm - name: Install dependencies run: pnpm install - - name: Get cypress version - id: cypress-version - run: echo "version=$(pnpm info cypress version)" >> $GITHUB_OUTPUT + - name: Get playwright version + id: playwright-version + run: echo "version=$(pnpm info playwright version)" >> $GITHUB_OUTPUT - - name: Cache cypress binary - id: cache-cypress-binary + - name: Cache playwright binary + id: cache-playwright-binary uses: actions/cache@v4 with: - path: ~/.cache/Cypress - key: cypress-binary-${{ runner.os }}-${{ steps.cypress-version.outputs.version }} + path: ~/.cache/ms-playwright + key: playwright-binary-${{ runner.os }}-${{ steps.playwright-version.outputs.version }} - - name: Install cypress binary - if: steps.cache-cypress-binary.outputs.cache-hit != 'true' - run: pnpm cypress install + - name: Install Playwright binary + if: steps.cache-playwright-binary.outputs.cache-hit != 'true' + run: pnpm playwright install --with-deps - name: E2E test - run: pnpm test:e2e:ci + run: pnpm test:e2e + + - name: Update coverage report + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage/e2e/lcov.info + + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: e2e-test-report + path: | + playwright-report/ + coverage/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index 38adffa6..77fbcfde 100644 --- a/.gitignore +++ b/.gitignore @@ -11,11 +11,14 @@ node_modules .DS_Store dist dist-ssr -coverage *.local -/cypress/videos/ -/cypress/screenshots/ +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ +/coverage-reports +/coverage # Editor directories and files .vscode/* diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..a923ebee --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + "recommendations": [ + "cenfun.monocart-coverage-vscode", + "vue.volar", + "dbaeumer.vscode-eslint", + "antfu.vite", + "vitest.explorer", + "ms-playwright.playwright" + ] +} diff --git a/README.md b/README.md index f9e823fb..71ff9910 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ For more information on how to this works with other frontends/backends, head ov - [x] [ESLint](https://eslint.vuejs.org/) and [@mutoe/eslint-config](https://github.com/mutoe/eslint-config) for linting and styling (based on [@anthony/eslint-config](https://github.com/anthony/eslint-config)) - [x] [Vitest](https://vitest.dev/) for unit testing - [x] [Testing Library](https://testing-library.com/docs/vue-testing-library/intro/) for component testing -- [x] [Cypress](https://docs.cypress.io) for E2E testing +- [x] [Playwright](https://playwright.dev) for E2E and visual testing - [x] [GitHub Actions](https://docs.github.com/en/actions) CI/CD > Basically, some of they are necessary features for the development of medium to large projects, and you can also use this repository as a starter. diff --git a/config/mcr.base.config.ts b/config/mcr.base.config.ts new file mode 100644 index 00000000..6f192d13 --- /dev/null +++ b/config/mcr.base.config.ts @@ -0,0 +1,53 @@ +import type { CoverageReportOptions } from 'monocart-coverage-reports' + +// https://github.com/cenfun/monocart-coverage-reports +const coverageOptions = { + reports: [ + 'text', + 'v8', + 'v8-json', + 'lcovonly', + 'raw', + ], + + /** + * V8 entity filter. The entry.url is the URL of the entity. + * @example http://localhost:4173/assets/index-Bn6Ml0wL.js + * @example https://fonts.googleapis.com/css?family=Titillium+Web:700 + * @example https://demo.realworld.io/main.css + * @example https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css + */ + entryFilter: entry => { + const excludeList = [ + 'googleapis.com', + 'realworld.(io|show)/main.css', + 'ionicons.min.css', + ] + for (const regexp of excludeList) { + if (new RegExp(regexp).test(entry.url)) return false + } + return true + }, + + /** + * Source filter. The sourcePath is the path of the source file. + * @example src/components/HelloWorld.vue + * @example src/config.ts + * @example node_modules/.pnpm/@vue+devtools-kit@7.7.7/node_modules/@vue/devtools-kit/dist/index.js + */ + sourceFilter: sourcePath => { + const excludeList = [ + 'node_modules', + 'src/services/api.ts', + 'src/setup-tests.ts', + 'src/utils/test', + '.(spec|test).ts$', + ] + for (const regexp of excludeList) { + if (new RegExp(regexp).test(sourcePath)) return false + } + return true + }, +} satisfies CoverageReportOptions + +export default coverageOptions diff --git a/config/mcr.e2e.config.ts b/config/mcr.e2e.config.ts new file mode 100644 index 00000000..80742521 --- /dev/null +++ b/config/mcr.e2e.config.ts @@ -0,0 +1,13 @@ +import type { CoverageReportOptions } from 'monocart-coverage-reports' +import baseConfig from './mcr.base.config' + +// https://github.com/cenfun/monocart-coverage-reports +const coverageOptions: CoverageReportOptions = { + ...baseConfig, + + name: 'E2E Test Coverage Report', + + outputDir: './coverage/e2e', +} + +export default coverageOptions diff --git a/config/mcr.unit.config.ts b/config/mcr.unit.config.ts new file mode 100644 index 00000000..bbc2ced2 --- /dev/null +++ b/config/mcr.unit.config.ts @@ -0,0 +1,13 @@ +import type { CoverageReportOptions } from 'monocart-coverage-reports' +import baseConfig from './mcr.base.config' + +// https://github.com/cenfun/monocart-coverage-reports +const coverageOptions: CoverageReportOptions = { + ...baseConfig, + + name: 'Unit Test Coverage Report', + + outputDir: './coverage/unit', +} + +export default coverageOptions diff --git a/cypress.config.ts b/cypress.config.ts deleted file mode 100644 index ef44da13..00000000 --- a/cypress.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { defineConfig } from 'cypress' - -export default defineConfig({ - projectId: 'j7s91r', - e2e: { - specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}', - baseUrl: 'http://localhost:4173', - defaultCommandTimeout: 8000, - }, -}) diff --git a/cypress/e2e/article.cy.ts b/cypress/e2e/article.cy.ts deleted file mode 100644 index 7eab3100..00000000 --- a/cypress/e2e/article.cy.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { ROUTES } from './constant' - -describe('article', () => { - beforeEach(() => { - cy.intercept('GET', /articles\?limit/, { fixture: 'articles.json' }) - cy.intercept('GET', /articles\/.+/, { fixture: 'article.json' }) - cy.intercept('GET', /tags/, { fixture: 'articles-of-tag.json' }) - cy.intercept('GET', /profiles\/.+/, { fixture: 'profile.json' }) - cy.intercept('DELETE', /articles\/.+/, { statusCode: 200, body: {} }).as('deleteArticle') - }) - - describe('post article', () => { - it('jump to post detail page when submit create article form', () => { - cy.login() - cy.visit('/') - - cy.intercept('POST', /articles$/, { fixture: 'article.json' }) - - cy.get('[href="#/article/create"]').click() - - cy.get('[placeholder="Article Title"]').type('Title') - cy.get('[placeholder="What\'s this article about?"]').type('content') - cy.get('[placeholder="Write your article (in markdown)"]').type('## test') - cy.get('[placeholder="Enter tags"]').type('butt') - - cy.get('[type="submit"]').click() - - cy.url() - .should('contain', 'article/article-title') - cy.get('.container > h1') - .should('contain', 'Article title') - }) - - it('should render markdown correctly', () => { - cy.login() - cy.visit(ROUTES.ARTICLE) - - cy.get('.article-content').within(() => { - cy.get('h1') - .should('contain', 'Article body') - - cy.get('strong') - .should('contain', 'Strong') - }) - }) - }) - - describe('delete article', () => { - it('delete article', () => { - cy.login() - cy.visit(ROUTES.ARTICLE) - - cy.get('.article-actions button.btn-outline-danger') - .contains('Delete Article') - .click() - - cy.wait('@deleteArticle') - cy.get('.home-page p') - .should('contain', 'A place to share your knowledge.') - }) - }) -}) diff --git a/cypress/e2e/auth.cy.ts b/cypress/e2e/auth.cy.ts deleted file mode 100644 index b2d78db9..00000000 --- a/cypress/e2e/auth.cy.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { ROUTES } from './constant' - -describe('auth', () => { - beforeEach(() => { - cy.intercept('GET', /users/, { fixture: 'user.json' }).as('getUser') - cy.intercept('GET', /tags/, { fixture: 'tags.json' }).as('getTags') - cy.intercept('GET', /articles/, { fixture: 'articles.json' }).as('getArticles') - }) - - describe('login and logout', () => { - it('should login success when submit a valid login form', () => { - cy.login() - - cy.url().should('match', /\/#\/$/) - }) - - it('should logout when click logout button', () => { - cy.login() - cy.get(`[href="${ROUTES.SETTINGS}"]`).click() - - cy.get('button.btn-outline-danger') - .contains('logout') - .click() - - cy.get('ul.navbar-nav') - .should('contain', 'Sign in') - .should('contain', 'Sign up') - }) - - it('should display error when submit an invalid form (password not match)', () => { - cy.intercept('POST', /users\/login/, { - statusCode: 403, - body: { errors: { 'email or password': ['is invalid'] } }, - }) - cy.visit(ROUTES.LOGIN) - - cy.get('[type="email"]').type('foo@example.com') - cy.get('[type="password"]').type('12345678') - cy.get('[type="submit"]').click() - - cy.contains('email or password is invalid') - }) - - it('should display format error without API call when submit an invalid format', () => { - cy.intercept('POST', /users\/login/).as('loginRequest') - cy.visit(ROUTES.LOGIN) - - cy.get('[type="email"]').type('foo') - cy.get('[type="password"]').type('123456') - cy.get('[type="submit"]').click() - - cy.get('form').then($el => { - cy.wrap($el[0].checkValidity()).should('to.be', false) - }) - }) - - it('should not allow visiting login page when the user is logged in', () => { - cy.login() - - cy.visit(ROUTES.LOGIN) - - cy.url().should('match', /\/#\/$/) - }) - - it('should has credential header after login success', () => { - cy.login() - - cy.visit(ROUTES.SETTINGS) - cy.intercept('PUT', /user/).as('updateSettingsRequest') - - cy.findByRole('textbox', { name: 'Username' }).type('foo') - cy.findByRole('button', { name: 'Update Settings' }).click() - - cy.wait('@updateSettingsRequest').its('request.headers').should('have.property', 'authorization') - }) - }) - - describe('register', () => { - it('should call register API and jump to home page when submit a valid form', () => { - cy.intercept('POST', /users$/, { fixture: 'user.json' }).as('registerRequest') - cy.visit(ROUTES.REGISTER) - - cy.get('[placeholder="Your Name"]').type('foo') - cy.get('[placeholder="Email"]').type('foo@example.com') - cy.get('[placeholder="Password"]').type('12345678') - - cy.get('[type="submit"]').click() - - cy.wait('@registerRequest') - cy.url().should('match', /\/#\/$/) - }) - - it('should display error message when submit the form that username already exist', () => { - cy.intercept('POST', /users$/, { - statusCode: 422, - body: { errors: { email: ['has already been taken'], username: ['has already been taken'] } }, - }).as('registerRequest') - - cy.visit(ROUTES.REGISTER) - - cy.get('[placeholder="Your Name"]').type('foo') - cy.get('[placeholder="Email"]').type('foo@example.com') - cy.get('[placeholder="Password"]').type('12345678') - - cy.get('[type="submit"]').click() - - cy.wait('@registerRequest') - cy.contains('email has already been taken') - cy.contains('username has already been taken') - }) - - it('should not allow visiting register page when the user is logged in', () => { - cy.login() - - cy.visit('/#/register') - - cy.url().should('match', /\/#\/$/) - }) - }) -}) diff --git a/cypress/e2e/constant.ts b/cypress/e2e/constant.ts deleted file mode 100644 index d0b48cd1..00000000 --- a/cypress/e2e/constant.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const ROUTES = { - HOME: '#/', - LOGIN: '#/login', - REGISTER: '#/register', - SETTINGS: '#/settings', - ARTICLE: '#/article/article-title', -} diff --git a/cypress/e2e/favorite.cy.ts b/cypress/e2e/favorite.cy.ts deleted file mode 100644 index 16b2e6d8..00000000 --- a/cypress/e2e/favorite.cy.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ROUTES } from './constant' - -describe('favorite', () => { - beforeEach(() => { - cy.intercept('GET', /articles\?/, { fixture: 'articles.json' }).as('getArticles') - cy.intercept('GET', /tags/, { fixture: 'tags.json' }).as('getTags') - }) - - it('should jump to login page when click favorite article button given user not logged', () => { - cy.intercept('POST', /articles\/\S+\/favorite$/, { statusCode: 401, body: {} }).as('favoriteArticle') - cy.visit(ROUTES.HOME) - - Cypress.on('uncaught:exception', error => { - expect(error.message).to.contain('Need to login') - return false - }) - cy.get('i.ion-heart:first').click() - - cy.url().should('contain', 'login') - }) - - it('should call favorite api and highlight favorite button when click favorite button', () => { - cy.intercept('POST', /articles\/\S+\/favorite$/, { fixture: 'article.json' }).as('favoriteArticle') - cy.login() - cy.visit(ROUTES.HOME) - - // like articles - cy.get('i.ion-heart:first').click() - - cy.wait('@favoriteArticle') - cy.get('.article-meta:first button') - .should('have.class', 'btn-primary') - }) -}) diff --git a/cypress/e2e/follow.cy.ts b/cypress/e2e/follow.cy.ts deleted file mode 100644 index a682f7dc..00000000 --- a/cypress/e2e/follow.cy.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ROUTES } from './constant' - -describe('follow', () => { - beforeEach(() => { - cy.intercept('GET', /articles\?/, { fixture: 'articles.json' }).as('getArticles') - cy.intercept('GET', /tags/, { fixture: 'tags.json' }).as('getTags') - cy.intercept('GET', /profiles\/\S+/, { fixture: 'profile.json' }).as('getProfile') - cy.fixture('article.json').then(article => { - article.article.author.username = 'foo' - cy.intercept('GET', /articles\/\S+/, { statusCode: 200, body: article }).as('getArticle') - }) - }) - - it('should not display follow button when user not logged', () => { - cy.visit(ROUTES.ARTICLE) - - cy.get('body').should('contain', ' to add comments on this article. ') - - cy.get('.article-meta button.space:first') - .should('not.contain.text', 'Follow') - }) - - it('should call follow user api when click follow user button', () => { - cy.fixture('profile.json').then(profile => { - profile.profile.following = true - cy.intercept('POST', /profiles\/\S+\/follow/, { statusCode: 200, body: profile }).as('followUser') - }) - cy.login() - cy.visit(ROUTES.ARTICLE) - - // follow author - cy.get('.article-meta button.btn-outline-secondary') - .contains('Follow') - .click() - - cy.wait('@followUser') - cy.get('.article-actions button.btn-outline-secondary:last') - .should('contain', 'Unfollow') - }) -}) diff --git a/cypress/e2e/home.cy.ts b/cypress/e2e/home.cy.ts deleted file mode 100644 index 0c50ef09..00000000 --- a/cypress/e2e/home.cy.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { ROUTES } from './constant' - -describe('homepage', () => { - beforeEach(() => { - cy.intercept('GET', /articles\?tag=butt/, { fixture: 'articles-of-tag.json' }).as('getArticlesOfTag') - cy.intercept('GET', /articles\?limit/, { fixture: 'articles.json' }).as('getArticles') - cy.intercept('GET', /articles\/.+/, { fixture: 'article.json' }).as('getArticle') - cy.intercept('GET', /tags/, { fixture: 'tags.json' }).as('getTags') - }) - - it('should can access home page', () => { - cy.visit(ROUTES.HOME) - - cy.get('h1.logo-font') - .should('contain.text', 'conduit') - }) - - it('should highlight Global Feed when home page loaded', () => { - cy.visit(ROUTES.HOME) - cy.get('.articles-toggle > .nav') - .contains('Global Feed') - .should('have.class', 'active') - }) - - it('should display article when page loaded', () => { - cy.visit(ROUTES.HOME) - cy.get('.article-preview:first') - .find('h1') - .should('contain.text', 'abc123') - }) - - it('should read more information of the first articles', () => { - cy.visit(ROUTES.HOME) - cy.get('div.article-preview:first span') - .contains('Read more...') - .click() - - cy.get('.article-page') - .contains(' to add comments on this article. ') - }) - - it('should highlight Home nav-item top menu bar when page load', () => { - cy.visit(ROUTES.HOME) - - cy.get('ul.nav.navbar-nav.pull-xs-right a.nav-link') - .contains('Home') - .should('have.class', 'active') - }) - - it('should jump to next page when click page 2 in pagination', () => { - cy.visit(ROUTES.HOME) - cy.wait('@getArticles') - - cy.get('ul.pagination li.page-item:nth-child(2) a.page-link') - .click() - - cy.wait('@getArticles') - .its('request.url') - .should('contain', 'limit=10&offset=10') - }) - - it('should display popular tags in home page', () => { - cy.visit(ROUTES.HOME) - cy.wait('@getTags') - - cy.contains('Popular Tags') - .parent('.sidebar') - .find('.tag-pill') - .should('have.length', 8) - }) -}) diff --git a/cypress/e2e/tag.cy.ts b/cypress/e2e/tag.cy.ts deleted file mode 100644 index 21a69c72..00000000 --- a/cypress/e2e/tag.cy.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { ROUTES } from './constant' - -describe('tag', () => { - beforeEach(() => { - cy.intercept('GET', /articles\?tag=butt/, { fixture: 'articles-of-tag.json' }).as('getArticlesOfTag') - cy.intercept('GET', /articles\?limit/, { fixture: 'articles.json' }).as('getArticles') - cy.intercept('GET', /tags/, { fixture: 'tags.json' }).as('getTags') - }) - - it('should display correct tags when page loaded', () => { - cy.visit(ROUTES.HOME) - cy.wait('@getTags') - - cy.get('div.tag-list') - .find('a.tag-pill.tag-default') - .should('have.length', 8) - - cy.get('div.tag-list') - .find('a.tag-pill.tag-default:nth-child(3)') - .should('contain.text', 'HITLER') - }) - - it('should show right articles of tag', () => { - cy.visit(ROUTES.HOME) - cy.wait('@getTags') - - cy.get('a.tag-pill.tag-default:last').click() - cy.wait('@getArticlesOfTag') - - cy.get('a.tag-pill.tag-default:last') - .should('have.class', 'router-link-active') - .should('have.class', 'router-link-exact-active') - - cy.get('a.tag-pill.tag-default:last').invoke('text').then(tag => { - const path = `#/tag/${tag}` - - cy.url() - .should('include', path) - - // check sheet - cy.get('a.active.router-link-exact-active.nav-link') - .should('contain', tag) - }) - }) -}) diff --git a/cypress/e2e/tsconfig.json b/cypress/e2e/tsconfig.json deleted file mode 100644 index 66dcfbdc..00000000 --- a/cypress/e2e/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "composite": true, - "target": "ESNext", - "lib": ["ESNext", "DOM"], - "baseUrl": ".", - "types": ["cypress", "@testing-library/cypress"], - "noEmit": false, - "isolatedModules": false - }, - "include": [ - "./**/*", - "../fixtures/**/*", - "../support/commands.ts", - "../support/e2e.ts" - ], - "exclude": [ - "../../src" - ] -} diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts deleted file mode 100644 index 34031085..00000000 --- a/cypress/support/commands.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -import '@testing-library/cypress/add-commands' diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts deleted file mode 100644 index 9cfd0a87..00000000 --- a/cypress/support/e2e.ts +++ /dev/null @@ -1,43 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -import { ROUTES } from '../e2e/constant' -import './commands' - -declare global { - // eslint-disable-next-line ts/no-namespace - namespace Cypress { - // noinspection JSUnusedGlobalSymbols - interface Chainable { - login(): void - } - } -} - -Cypress.Commands.add('login', (username = 'plumrx') => { - cy.fixture('user.json').then(authResponse => { - authResponse.user.username = username - cy.intercept('POST', /users\/login$/, { statusCode: 200, body: authResponse }) - }) - - // click sign in button in home page - cy.visit(ROUTES.LOGIN) - - cy.get('[type="email"]').type('foo@example.com') - cy.get('[type="password"]').type('12345678') - cy.get('[type="submit"]').contains('Sign in').click() - - cy.url().should('match', /#\/$/) -}) diff --git a/eslint.config.js b/eslint.config.js index 44d8826c..b58e56ca 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -3,10 +3,6 @@ import defineConfig from '@mutoe/eslint-config' export default defineConfig({ typescript: { tsconfigPath: 'tsconfig.json', - ignoresTypeAware: [ - 'cypress/**', - '**/*.cy.ts', - ], }, vue: { sfcBlocks: { @@ -22,8 +18,11 @@ export default defineConfig({ 'src/services/api.ts', ], }, { - files: ['cypress/support/**/*.ts'], + files: [ + '*.config.ts', + 'playwright/**/*', + ], rules: { - 'ts/method-signature-style': 'off', + 'node/prefer-global/process': 'off', }, }) diff --git a/index.html b/index.html index 08e2c793..6142a68f 100644 --- a/index.html +++ b/index.html @@ -6,10 +6,10 @@ - - + + - +
diff --git a/package.json b/package.json index 479b8689..57a2ed3b 100644 --- a/package.json +++ b/package.json @@ -2,19 +2,23 @@ "name": "vue3-realworld-example-app", "private": true, "license": "MIT", + "engines": { + "node": ">= 20" + }, + "packageManager": "pnpm@10.17.1", "type": "module", "scripts": { "prepare": "simple-git-hooks", - "dev": "vite", + "dev": "vite --port 4173", "build": "vite build", "serve": "vite preview --port 4173", "type-check": "vue-tsc --noEmit", "lint": "eslint --fix .", - "test": "npm run test:unit && npm run test:e2e:ci", - "test:e2e": "npm run build && concurrently -rk -s first \"npm run serve\" \"cypress open --e2e -c baseUrl=http://localhost:4173\"", - "test:e2e:ci": "npm run build && concurrently -rk -s first \"npm run serve\" \"cypress run --e2e -c baseUrl=http://localhost:4173\"", - "test:e2e:local": "cypress open --e2e -c baseUrl=http://localhost:5173", - "test:e2e:prod": "cypress run --e2e -c baseUrl=https://vue3-realworld-example-app-mutoe.vercel.app", + "test": "pnpm test:unit && pnpm test:e2e && tsx scripts/merge-coverage.ts", + "test:e2e": "cross-env NODE_ENV=testing pnpm build && cross-env CI=true playwright test", + "test:e2e:prod": "cross-env E2E_BASE_URL='https://vue3-realworld-example-app-mutoe.vercel.app' playwright test", + "test:e2e:ui": "playwright test --ui", + "test:e2e:ui:debug": "playwright test --ui --headed --debug", "test:unit": "vitest run", "generate:api": "curl -sL https://raw.githubusercontent.com/gothinkster/realworld/refs/heads/main/api/openapi.yml -o ./src/services/openapi.yml && sta generate -p ./src/services/openapi.yml -o ./src/services -n api.ts" }, @@ -28,30 +32,33 @@ "devDependencies": { "@mutoe/eslint-config": "^4.11.0-2", "@pinia/testing": "^1.0.2", - "@testing-library/cypress": "^10.1.0", + "@playwright/test": "1.55.1", "@testing-library/user-event": "^14.6.1", "@testing-library/vue": "^8.1.0", + "@types/node": "^24.5.2", "@vitejs/plugin-vue": "^6.0.1", "@vitest/coverage-v8": "^3.2.4", - "concurrently": "^9.2.1", - "cypress": "^13.13.2", + "cross-env": "^7.0.3", "eslint": "^9.36.0", - "eslint-plugin-cypress": "^5.1.1", + "eslint-plugin-vuejs-accessibility": "^2.4.1", "happy-dom": "^18.0.1", "lint-staged": "^16.2.0", + "monocart-coverage-reports": "^2.12.9", "msw": "^2.11.3", "rollup-plugin-analyzer": "^4.0.0", "simple-git-hooks": "^2.13.1", "swagger-typescript-api": "^13.2.13", + "tsx": "^4.20.6", "typescript": "~5.9.2", "vite": "^7.1.7", "vitest": "^3.2.4", "vitest-dom": "^0.1.1", + "vitest-monocart-coverage": "^3.0.2", "vue-tsc": "^3.0.8" }, "simple-git-hooks": { "pre-commit": "npm exec lint-staged", - "pre-push": "npm run type-check && npm run build" + "pre-push": "pnpm type-check && pnpm build" }, "lint-staged": { "*": "eslint --fix" diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000..ec699125 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,81 @@ +import { defineConfig, devices } from '@playwright/test' + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// import dotenv from 'dotenv'; +// dotenv.config({ path: path.resolve(__dirname, '.env') }); + +const isCI = process.env.CI +const baseURL = process.env.E2E_BASE_URL || 'http://localhost:4173' + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './playwright', + /* Run tests in files in parallel */ + fullyParallel: false, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!isCI, + /* Retry on CI only */ + retries: isCI ? 1 : 0, + /* Opt out of parallel tests on CI. */ + workers: isCI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: [ + ['html', { open: 'never' }], + isCI ? ['github'] : ['list'], + ], + + globalSetup: './playwright/global.setup.ts', + globalTeardown: './playwright/global.teardown.ts', + + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL, + + navigationTimeout: isCI ? 10_000 : 20_000, + actionTimeout: isCI ? 10_000 : 20_000, + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + screenshot: 'only-on-failure', + trace: isCI ? 'on-first-retry' : 'retain-on-failure', + video: isCI ? 'on-first-retry' : 'retain-on-failure', + }, + + /* Configure projects for major browsers */ + projects: isCI + ? [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + // { + // name: 'firefox', + // use: { ...devices['Desktop Firefox'] }, + // }, + // { + // name: 'webkit', + // use: { ...devices['Desktop Safari'] }, + // }, + ] + : [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'], + }, + }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: isCI ? 'pnpm serve' : 'pnpm dev', + url: baseURL, + reuseExistingServer: !isCI, + ignoreHTTPSErrors: true, + }, +}) diff --git a/playwright/constant.ts b/playwright/constant.ts new file mode 100644 index 00000000..0f2a523f --- /dev/null +++ b/playwright/constant.ts @@ -0,0 +1,8 @@ +export enum Route { + Home = '/#/', + Login = '/#/login', + Register = '/#/register', + Settings = '/#/settings', + ArticleCreate = '/#/article/create', + ArticleDetail = '/#/article/article-title', +} diff --git a/playwright/extends.ts b/playwright/extends.ts new file mode 100644 index 00000000..b8df7b22 --- /dev/null +++ b/playwright/extends.ts @@ -0,0 +1,65 @@ +import type { Page } from '@playwright/test' +import { test as base } from '@playwright/test' +import MCR from 'monocart-coverage-reports' +import { ConduitPageObject } from 'page-objects/conduit.page-object' +import coverageOptions from '../config/mcr.e2e.config' + +export const test = base.extend<{ + conduit: ConduitPageObject + autoTestFixture: string +}>({ + conduit: async ({ page }, use) => { + const buyscoutPageObject = new ConduitPageObject(page) + await use(buyscoutPageObject) + }, + + autoTestFixture: [async ({ context }, use) => { + const isChromium = test.info().project.name === 'chromium' + + // eslint-disable-next-line unicorn/consistent-function-scoping + const handlePageEvent = async (page: Page) => { + await Promise.all([ + page.coverage.startJSCoverage({ + resetOnNavigation: false, + }), + page.coverage.startCSSCoverage({ + resetOnNavigation: false, + }), + ]) + } + + // coverage API is chromium only + if (isChromium) { + context.on('page', handlePageEvent) + } + + await use('autoTestFixture') + + if (isChromium) { + context.off('page', handlePageEvent) + const coverageList = await Promise.all(context.pages().map(async page => { + const jsCoverage = await page.coverage.stopJSCoverage() + const cssCoverage = await page.coverage.stopCSSCoverage() + return [...jsCoverage, ...cssCoverage] + })) + // console.log(coverageList.map((item) => item.url)); + + const mcr = MCR(coverageOptions) + await mcr.add(coverageList.flat()) + } + }, { + scope: 'test', + auto: true, + }], +}) + +test.afterEach(async ({ page }, testInfo) => { + if (!process.env.CI && testInfo.status !== testInfo.expectedStatus) { + // eslint-disable-next-line ts/restrict-template-expressions + process.stderr.write(`❌ ❌ PLAYWRIGHT TEST FAILURE ❌ ❌\n${testInfo.error?.stack || testInfo.error}\n`) + testInfo.setTimeout(0) + await page.pause() + } +}) + +export const expect = test.expect diff --git a/cypress/fixtures/article-comments.json b/playwright/fixtures/article-comments.json similarity index 100% rename from cypress/fixtures/article-comments.json rename to playwright/fixtures/article-comments.json diff --git a/cypress/fixtures/article.json b/playwright/fixtures/article.json similarity index 93% rename from cypress/fixtures/article.json rename to playwright/fixtures/article.json index 82bd64cd..a3d000f3 100644 --- a/cypress/fixtures/article.json +++ b/playwright/fixtures/article.json @@ -5,7 +5,7 @@ "body": "# Article body\n\nThis is **Strong** text", "createdAt": "2020-11-01T14:59:39.404Z", "updatedAt": "2020-11-01T14:59:39.404Z", - "tagList": [], + "tagList": ["foo", "bar"], "description": "this is descripion", "author": { "username": "plumrx", diff --git a/cypress/fixtures/articles-of-tag.json b/playwright/fixtures/articles-of-tag.json similarity index 100% rename from cypress/fixtures/articles-of-tag.json rename to playwright/fixtures/articles-of-tag.json diff --git a/cypress/fixtures/articles.json b/playwright/fixtures/articles.json similarity index 100% rename from cypress/fixtures/articles.json rename to playwright/fixtures/articles.json diff --git a/cypress/fixtures/profile.json b/playwright/fixtures/profile.json similarity index 100% rename from cypress/fixtures/profile.json rename to playwright/fixtures/profile.json diff --git a/cypress/fixtures/tags.json b/playwright/fixtures/tags.json similarity index 100% rename from cypress/fixtures/tags.json rename to playwright/fixtures/tags.json diff --git a/cypress/fixtures/user.json b/playwright/fixtures/user.json similarity index 100% rename from cypress/fixtures/user.json rename to playwright/fixtures/user.json diff --git a/playwright/global.setup.ts b/playwright/global.setup.ts new file mode 100644 index 00000000..55508919 --- /dev/null +++ b/playwright/global.setup.ts @@ -0,0 +1,10 @@ +import type { FullConfig } from '@playwright/test' +import MCR from 'monocart-coverage-reports' +import coverageOptions from '../config/mcr.e2e.config' + +async function globalSetup(_config: FullConfig) { + const mcr = MCR(coverageOptions) + mcr.cleanCache() +} + +export default globalSetup diff --git a/playwright/global.teardown.ts b/playwright/global.teardown.ts new file mode 100644 index 00000000..c523ea23 --- /dev/null +++ b/playwright/global.teardown.ts @@ -0,0 +1,10 @@ +import type { FullConfig } from '@playwright/test' +import MCR from 'monocart-coverage-reports' +import coverageOptions from '../config/mcr.e2e.config' + +async function globalTeardown(_config: FullConfig) { + const mcr = MCR(coverageOptions) + await mcr.generate() +} + +export default globalTeardown diff --git a/playwright/page-objects/article-detail.page-object.ts b/playwright/page-objects/article-detail.page-object.ts new file mode 100644 index 00000000..162228a0 --- /dev/null +++ b/playwright/page-objects/article-detail.page-object.ts @@ -0,0 +1,33 @@ +import type { Page } from '@playwright/test' +import { ConduitPageObject } from './conduit.page-object' + +export class ArticleDetailPageObject extends ConduitPageObject { + constructor(public page: Page) { + super(page) + } + + positionMap = { + 'banner': 0, + 'article footer': 1, + } as const + + private async clickOperationButton(position: keyof typeof this.positionMap = 'banner', buttonName: string) { + await this.page.getByRole('button', { name: buttonName }).nth(this.positionMap[position]).click() + } + + async clickEditArticle(position: keyof typeof this.positionMap = 'banner') { + return await this.clickOperationButton(position, 'Edit Article') + } + + async clickDeleteArticle(position: keyof typeof this.positionMap = 'banner') { + await this.page.getByRole('button', { name: 'Delete article' }).nth(this.positionMap[position]).dispatchEvent('click') + } + + async clickFollowUser(position: keyof typeof this.positionMap = 'banner') { + await this.page.getByRole('button', { name: 'Follow' }).nth(this.positionMap[position]).dispatchEvent('click') + } + + async clickFavoriteArticle(position: keyof typeof this.positionMap = 'banner') { + await this.page.getByRole('button', { name: 'Favorite article' }).nth(this.positionMap[position]).dispatchEvent('click') + } +} diff --git a/playwright/page-objects/conduit.page-object.ts b/playwright/page-objects/conduit.page-object.ts new file mode 100644 index 00000000..d249ee25 --- /dev/null +++ b/playwright/page-objects/conduit.page-object.ts @@ -0,0 +1,88 @@ +import fs from 'node:fs/promises' +import path from 'node:path' +import url from 'node:url' +import type { Page, Response } from '@playwright/test' +import type { User } from 'src/services/api' +import { Route } from '../constant' +import { expect } from '../extends' +import { boxedStep } from '../utils/test-decorators' + +const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) +const fixtureDir = path.join(__dirname, '../fixtures') + +export class ConduitPageObject { + constructor( + public readonly page: Page, + ) {} + + async intercept(method: 'POST' | 'GET' | 'PATCH' | 'DELETE' | 'PUT', url: string | RegExp, options: { + fixture?: string + postFixture?: (fixture: any) => void | unknown + statusCode?: number + body?: unknown + timeout?: number + } = {}): Promise<() => Promise> { + await this.page.route(url, async route => { + if (route.request().url().endsWith('.ts')) + return await route.continue() + if (route.request().method() !== method) + return await route.continue() + + if (options.postFixture && options.fixture) { + const body = await this.getFixture(options.fixture) + const returnValue = await options.postFixture(body) + options.body = returnValue === undefined ? body : returnValue + options.fixture = undefined + } + + return await route.fulfill({ + status: options.statusCode || undefined, + json: options.body ?? undefined, + path: options.fixture ? path.join(fixtureDir, options.fixture) : undefined, + }) + }) + + return () => this.page.waitForResponse(response => { + const request = response.request() + if (request.method() !== method) + return false + + if (typeof url === 'string') + return request.url().includes(url) + + return url.test(request.url()) + }, { timeout: options.timeout ?? 4000 }) + } + + async getFixture(fixture: string): Promise { + const file = path.join(fixtureDir, fixture) + return JSON.parse(await fs.readFile(file, 'utf8')) as T + } + + async goto(route: Route) { + await this.page.goto(route, { waitUntil: 'domcontentloaded' }) + } + + @boxedStep + async login(username = 'plumrx') { + const userFixture = await this.getFixture<{ user: User }>('user.json') + userFixture.user.username = username + + await this.goto(Route.Login) + + await this.page.getByPlaceholder('Email').fill('foo@example.com') + await this.page.getByPlaceholder('Password').fill('12345678') + + const waitForLogin = await this.intercept('POST', /users\/login$/, { statusCode: 200, body: userFixture }) + await Promise.all([ + waitForLogin(), + this.page.getByRole('button', { name: 'Sign in' }).click(), + ]) + + await expect(this.page).toHaveURL(Route.Home) + } + + async toContainText(text: string) { + await expect(this.page.locator('body')).toContainText(text) + } +} diff --git a/playwright/page-objects/edit-article.page-object.ts b/playwright/page-objects/edit-article.page-object.ts new file mode 100644 index 00000000..8179cf35 --- /dev/null +++ b/playwright/page-objects/edit-article.page-object.ts @@ -0,0 +1,44 @@ +import type { Page } from '@playwright/test' +import { ConduitPageObject } from './conduit.page-object' + +export class EditArticlePageObject extends ConduitPageObject { + constructor(public page: Page) { + super(page) + } + + async fillTitle(title: string) { + await this.page.getByPlaceholder('Article Title').fill(title) + } + + async fillDescription(description: string) { + await this.page.getByPlaceholder("What's this article about?").fill(description) + } + + async fillContent(content: string) { + await this.page.getByPlaceholder('Write your article (in markdown)').fill(content) + } + + async fillTags(tags: string | string[]) { + if (!Array.isArray(tags)) + tags = [tags] + for (const tag of tags) { + await this.page.getByPlaceholder('Enter tags').fill(tag) + await this.page.getByPlaceholder('Enter tags').press('Enter') + } + } + + async fillForm({ title, description, content, tags }: { title?: string, description?: string, content?: string, tags?: string | string[] }) { + if (title !== undefined) + await this.fillTitle(title) + if (description !== undefined) + await this.fillDescription(description) + if (content !== undefined) + await this.fillContent(content) + if (tags !== undefined) + await this.fillTags(tags) + } + + async clickPublishArticle() { + await this.page.getByRole('button', { name: 'Publish Article' }).dispatchEvent('click') + } +} diff --git a/playwright/page-objects/login.page-object.ts b/playwright/page-objects/login.page-object.ts new file mode 100644 index 00000000..eb166d5e --- /dev/null +++ b/playwright/page-objects/login.page-object.ts @@ -0,0 +1,27 @@ +import type { Page } from '@playwright/test' +import { ConduitPageObject } from './conduit.page-object' + +export class LoginPageObject extends ConduitPageObject { + constructor(public page: Page) { + super(page) + } + + async fillEmail(email: string = 'foo@example.com') { + await this.page.getByPlaceholder('Email').fill(email) + } + + async fillPassword(password = '12345678') { + await this.page.getByPlaceholder('Password').fill(password) + } + + async fillForm(form: { email?: string, password?: string }) { + if (form.email !== undefined) + await this.fillEmail(form.email) + if (form.password !== undefined) + await this.fillPassword(form.password) + } + + async clickSignIn() { + await this.page.getByRole('button', { name: 'Sign in' }).dispatchEvent('click') + } +} diff --git a/playwright/page-objects/register.page-object.ts b/playwright/page-objects/register.page-object.ts new file mode 100644 index 00000000..b8302d09 --- /dev/null +++ b/playwright/page-objects/register.page-object.ts @@ -0,0 +1,33 @@ +import type { Page } from '@playwright/test' +import { ConduitPageObject } from './conduit.page-object' + +export class RegisterPageObject extends ConduitPageObject { + constructor(public page: Page) { + super(page) + } + + async fillName(name: string = 'foo') { + await this.page.getByPlaceholder('Your Name').fill(name) + } + + async fillEmail(email: string = 'foo@example.com') { + await this.page.getByPlaceholder('Email').fill(email) + } + + async fillPassword(password = '12345678') { + await this.page.getByPlaceholder('Password').fill(password) + } + + async fillForm(form: { name?: string, email?: string, password?: string }) { + if (form.name !== undefined) + await this.fillName(form.name) + if (form.email !== undefined) + await this.fillEmail(form.email) + if (form.password !== undefined) + await this.fillPassword(form.password) + } + + async clickSignUp() { + await this.page.getByRole('button', { name: 'Sign up' }).dispatchEvent('click') + } +} diff --git a/playwright/specs/article.spec.ts b/playwright/specs/article.spec.ts new file mode 100644 index 00000000..e196b81a --- /dev/null +++ b/playwright/specs/article.spec.ts @@ -0,0 +1,137 @@ +import { ArticleDetailPageObject } from 'page-objects/article-detail.page-object' +import { EditArticlePageObject } from 'page-objects/edit-article.page-object' +import type { Article } from 'src/services/api' +import { Route } from '../constant' +import { expect, test } from '../extends' + +test.beforeEach(async ({ conduit }) => { + await conduit.intercept('GET', /articles\?limit/, { fixture: 'articles.json' }) + await conduit.intercept('GET', /tags/, { fixture: 'tags.json' }) + await conduit.intercept('GET', /profiles\/.+/, { fixture: 'profile.json' }) +}) + +test.describe('post article', () => { + let editArticlePage!: EditArticlePageObject + + test.beforeEach(async ({ conduit, page }) => { + await conduit.login() + editArticlePage = new EditArticlePageObject(page) + }) + + test('jump to post detail page when submit create article form', async ({ page, conduit }) => { + await conduit.goto(Route.ArticleCreate) + + const articleFixture = await conduit.getFixture<{ article: Article }>('article.json') + const waitForPostArticle = await editArticlePage.intercept('POST', /articles$/, { body: articleFixture }) + + await editArticlePage.fillForm({ + title: articleFixture.article.title, + description: articleFixture.article.description, + content: articleFixture.article.body, + tags: articleFixture.article.tagList, + }) + + await editArticlePage.clickPublishArticle() + await waitForPostArticle() + + await conduit.intercept('GET', /articles\/.+/, { fixture: 'article.json' }) + await page.waitForURL(/article\/article-title/) + await conduit.toContainText('Article title') + }) + + test('should render markdown correctly', async ({ browserName, page, conduit }) => { + test.skip(browserName !== 'chromium') + const waitForArticleRequest = await conduit.intercept('GET', /articles\/.+/, { fixture: 'article.json' }) + await Promise.all([ + waitForArticleRequest(), + conduit.goto(Route.ArticleDetail), + ]) + const articleContent = page.locator('.article-content') + await expect(articleContent).toMatchAriaSnapshot({ name: 'article-content.yml' }) + }) +}) + +test.describe('delete article', () => { + for (const position of ['banner', 'article footer'] as const) { + test(`delete article from ${position}`, async ({ page, conduit }) => { + await conduit.login() + const articlePage = new ArticleDetailPageObject(page) + const waitForArticle = await articlePage.intercept('GET', /articles\/.+/, { fixture: 'article.json' }) + await conduit.goto(Route.ArticleDetail) + await waitForArticle() + + const waitForDeleteArticle = await conduit.intercept('DELETE', /articles\/.+/) + + const [response] = await Promise.all([ + waitForDeleteArticle(), + articlePage.clickDeleteArticle(position), + ]) + + expect(response).toBeInstanceOf(Object) + await expect(page).toHaveURL(Route.Home) + }) + } +}) + +test.describe('favorite article', () => { + test.beforeEach(async ({ conduit }) => { + await conduit.intercept('GET', /tags/, { fixture: 'tags.json' }) + }) + + test('should jump to login page when click favorite article button given user not logged', async ({ page, conduit }) => { + await conduit.goto(Route.Home) + + const waitForFavoriteArticle = await conduit.intercept('POST', /articles\/\S+\/favorite$/, { statusCode: 401 }) + await Promise.all([ + waitForFavoriteArticle(), + page.getByRole('button', { name: 'Favorite article' }).first().click(), + ]) + + await expect(page).toHaveURL(Route.Login) + }) + + test('should call favorite api and highlight favorite button when click favorite button', async ({ page, conduit }) => { + await conduit.login() + await conduit.goto(Route.Home) + + // like articles + const waitForFavoriteArticle = await conduit.intercept('POST', /articles\/\S+\/favorite$/, { fixture: 'article.json' }) + await Promise.all([ + waitForFavoriteArticle(), + page.getByRole('button', { name: 'Favorite article' }).first().click(), + ]) + + await expect(page.getByRole('button', { name: 'Favorite article' }).first()).toContainClass('btn-primary') + }) +}) + +test.describe('tag', () => { + test.beforeEach(async ({ conduit }) => { + await conduit.login() + await conduit.intercept('GET', /articles\?tag=butt/, { fixture: 'articles-of-tag.json' }) + }) + + test('should display popular tags in home page', async ({ page, conduit }) => { + await conduit.goto(Route.Home) + + const tagItemsWrapper = page.getByText('Popular Tags') + .locator('..') + .locator('.tag-pill') + .locator('..') + await expect(tagItemsWrapper).toMatchAriaSnapshot({ name: 'popular-tags.yml' }) + }) + + test('should show right articles of tag', async ({ page, conduit }) => { + const tagName = 'butt' + await conduit.goto(Route.Home) + + await conduit.intercept('GET', /articles\?tag/, { fixture: 'articles-of-tag.json' }) + await page.getByLabel(tagName).click() + + await expect(page).toHaveURL(`/#/tag/${tagName}`) + await expect(page.locator('a.tag-pill.tag-default').last()) + .toHaveClass(/(router-link-active|router-link-exact-active)/) + + await expect(page.getByLabel('tag')).toContainText('butt') + }) +}) diff --git a/playwright/specs/article.spec.ts-snapshots/article-content.yml b/playwright/specs/article.spec.ts-snapshots/article-content.yml new file mode 100644 index 00000000..1299c9e4 --- /dev/null +++ b/playwright/specs/article.spec.ts-snapshots/article-content.yml @@ -0,0 +1,8 @@ +- heading "Article body" [level=1] +- paragraph: + - text: This is + - strong: Strong + - text: text +- list: + - listitem: foo + - listitem: bar diff --git a/playwright/specs/article.spec.ts-snapshots/popular-tags.yml b/playwright/specs/article.spec.ts-snapshots/popular-tags.yml new file mode 100644 index 00000000..2d605d3f --- /dev/null +++ b/playwright/specs/article.spec.ts-snapshots/popular-tags.yml @@ -0,0 +1,16 @@ +- link "HuManIty": + - /url: '#/tag/HuManIty' +- link "Gandhi": + - /url: '#/tag/Gandhi' +- link "HITLER": + - /url: '#/tag/HITLER' +- link "SIDA": + - /url: '#/tag/SIDA' +- link "BlackLivesMatter": + - /url: '#/tag/BlackLivesMatter' +- link "test": + - /url: '#/tag/test' +- link "dragons": + - /url: '#/tag/dragons' +- link "butt": + - /url: '#/tag/butt' diff --git a/playwright/specs/auth.spec.ts b/playwright/specs/auth.spec.ts new file mode 100644 index 00000000..dc817211 --- /dev/null +++ b/playwright/specs/auth.spec.ts @@ -0,0 +1,124 @@ +import { LoginPageObject } from 'page-objects/login.page-object' +import { RegisterPageObject } from 'page-objects/register.page-object' +import { Route } from '../constant' +import { expect, test } from '../extends' + +test.beforeEach(async ({ conduit }) => { + await conduit.intercept('GET', /users/, { fixture: 'user.json' }) + await conduit.intercept('GET', /tags/, { fixture: 'tags.json' }) + await conduit.intercept('GET', /articles/, { fixture: 'articles.json' }) +}) + +test.describe('login and logout', () => { + let loginPage!: LoginPageObject + + test.beforeEach(({ page }) => { + loginPage = new LoginPageObject(page) + }) + + test('should login success when submit a valid login form', async ({ page, conduit }) => { + await conduit.login() + + await expect(page).toHaveURL(Route.Home) + }) + + test('should logout when click logout button', async ({ page, conduit }) => { + await conduit.login() + await conduit.goto(Route.Settings) + + await page.getByRole('button', { name: 'logout' }).click() + await conduit.toContainText('Sign in') + }) + + test('should display error when submit an invalid form (password not match)', async ({ conduit }) => { + await conduit.goto(Route.Login) + + await loginPage.intercept('POST', /users\/login/, { + statusCode: 403, + body: { errors: { 'email or password': ['is invalid'] } }, + }) + await loginPage.fillForm({ email: 'foo@example.com', password: '12345678' }) + await loginPage.clickSignIn() + + await loginPage.toContainText('email or password is invalid') + }) + + test('should display format error without API call when submit an invalid format', async ({ page, conduit }) => { + await conduit.goto(Route.Login) + + await loginPage.intercept('POST', /users\/login/) + await loginPage.fillForm({ email: 'foo', password: '123456' }) + await loginPage.clickSignIn() + + expect(await page.$eval('form', form => form.checkValidity())).toBe(false) + }) + + test('should not allow visiting login page when the user is logged in', async ({ page, conduit }) => { + await conduit.login() + await conduit.goto(Route.Login) + + await expect(page).toHaveURL(Route.Home) + }) + + test('should has credential header after login success', async ({ page, conduit }) => { + await conduit.login() + await conduit.goto(Route.Settings) + + const waitForUpdateSettingsRequest = await conduit.intercept('PUT', /user/) + + await page.getByRole('textbox', { name: 'Username' }).fill('foo') + await page.getByRole('button', { name: 'Update Settings' }).dispatchEvent('click') + + const response = await waitForUpdateSettingsRequest() + expect(response.request().headers()).toHaveProperty('authorization') + }) +}) + +test.describe('register', () => { + let registerPage!: RegisterPageObject + + test.beforeEach(({ page }) => { + registerPage = new RegisterPageObject(page) + }) + + test('should call register API and jump to home page when submit a valid form', async ({ conduit }) => { + await conduit.goto(Route.Register) + + const waitForRegisterRequest = await registerPage.intercept('POST', /users$/, { fixture: 'user.json' }) + await registerPage.fillForm({ + name: 'foo', + email: 'foo@example.com', + password: '12345678', + }) + await registerPage.clickSignUp() + + await waitForRegisterRequest() + await expect(conduit.page).toHaveURL(Route.Home) + }) + + test('should display error message when submit the form that username already exist', async ({ conduit }) => { + await conduit.goto(Route.Register) + + const waitForRegisterRequest = await registerPage.intercept('POST', /users$/, { + statusCode: 422, + body: { errors: { email: ['has already been taken'], username: ['has already been taken'] } }, + }) + await registerPage.fillForm({ + name: 'foo', + email: 'foo@example.com', + password: '12345678', + }) + await registerPage.clickSignUp() + + await waitForRegisterRequest() + await registerPage.toContainText('email has already been taken') + await registerPage.toContainText('username has already been taken') + }) + + test('should not allow visiting register page when the user is logged in', async ({ page, conduit }) => { + await conduit.login() + await conduit.goto(Route.Register) + + await expect(page).toHaveURL(Route.Home) + }) +}) diff --git a/playwright/specs/home.spec.ts b/playwright/specs/home.spec.ts new file mode 100644 index 00000000..83233fad --- /dev/null +++ b/playwright/specs/home.spec.ts @@ -0,0 +1,59 @@ +import { Route } from '../constant' +import { expect, test } from '../extends' + +test.beforeEach(async ({ conduit }) => { + await conduit.intercept('GET', /articles\?tag=butt/, { fixture: 'articles-of-tag.json' }) + await conduit.intercept('GET', /articles\?limit/, { fixture: 'articles.json' }) + await conduit.intercept('GET', /articles\/.+/, { fixture: 'article.json' }) + await conduit.intercept('GET', /tags/, { fixture: 'tags.json' }) +}) + +test('should can access home page', async ({ page, conduit }) => { + await conduit.goto(Route.Home) + + await expect(page.getByRole('heading', { name: 'conduit' })).toContainText('conduit') +}) + +test.describe('navigation bar', () => { + test('should highlight Home nav-item top menu bar when page load', async ({ page, conduit }) => { + await conduit.goto(Route.Home) + + await expect(page.getByRole('link', { name: 'Home', exact: true })).toHaveClass(/active/) + }) +}) + +test.describe('article previews', () => { + test('should highlight Global Feed when home page loaded', async ({ page, conduit }) => { + await conduit.goto(Route.Home) + await expect(page.getByText('Global Feed')).toHaveClass(/active/) + }) + + test('should display article when page loaded', async ({ page, conduit }) => { + await conduit.goto(Route.Home) + const articlePreview = page.getByTestId('article-preview').first() + + await test.step('should have article preview', async () => { + await expect(articlePreview.getByRole('heading')).toContainText('abc123') + await expect(articlePreview.getByTestId('article-description')).toContainText('aaaaaaaaaaassssssssss') + }) + + await test.step('should redirect to article details page when click read more', async () => { + await articlePreview.getByText('Read more...').click() + + await expect(page).toHaveURL(/#\/article\/.+/) + }) + }) + + test('should jump to next page when click page 2 in pagination', async ({ page, conduit }) => { + await conduit.goto(Route.Home) + + const waitForGetArticles = await conduit.intercept('GET', /articles\?limit=10&offset=10/, { fixture: 'articles.json' }) + + const [response] = await Promise.all([ + waitForGetArticles(), + page.getByRole('link', { name: 'Go to page 2', exact: true }).click(), + ]) + + expect(response.request().url()).toContain('limit=10&offset=10') + }) +}) diff --git a/playwright/specs/user.spec.ts b/playwright/specs/user.spec.ts new file mode 100644 index 00000000..c5442e50 --- /dev/null +++ b/playwright/specs/user.spec.ts @@ -0,0 +1,52 @@ +import type { Article, Profile } from 'src/services/api' +import { Route } from '../constant' +import { expect, test } from '../extends' +import { ArticleDetailPageObject } from '../page-objects/article-detail.page-object' + +test.beforeEach(async ({ conduit }) => { + await conduit.intercept('GET', /articles\?/, { fixture: 'articles.json' }) + await conduit.intercept('GET', /tags/, { fixture: 'tags.json' }) + await conduit.intercept('GET', /profiles\/\S+/, { fixture: 'profile.json' }) +}) + +test.describe('follow', () => { + test.beforeEach(async ({ conduit }) => { + await conduit.intercept('GET', /articles\/\S+/, { + statusCode: 200, + fixture: 'article.json', + postFixture: (article: { article: Article }) => { + article.article.author.username = 'foo' + }, + }) + }) + + for (const [index, position] of (['banner', 'article footer'] as const).entries()) { + test(`should call follow user api when click ${position} follow user button`, async ({ page, conduit }) => { + await conduit.login() + await conduit.goto(Route.ArticleDetail) + const articlePage = new ArticleDetailPageObject(page) + + const waitForFollowUser = await conduit.intercept('POST', /profiles\/\S+\/follow/, { + statusCode: 200, + fixture: 'profile.json', + postFixture: (profile: { profile: Profile }) => { + profile.profile.following = true + }, + }) + + await Promise.all([ + waitForFollowUser(), + articlePage.clickFollowUser(position), + ]) + + await expect(page.getByRole('button', { name: 'Unfollow' }).nth(index)).toBeVisible() + }) + } + + test('should not display follow button when user not logged', async ({ page, conduit }) => { + await conduit.goto(Route.ArticleDetail) + + await expect(page.getByRole('heading', { name: 'Article body' })).toBeVisible() + await expect(page.getByRole('button', { name: 'Follow' })).not.toBeVisible() + }) +}) diff --git a/playwright/tsconfig.json b/playwright/tsconfig.json new file mode 100644 index 00000000..7a942302 --- /dev/null +++ b/playwright/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "composite": true, + "target": "ESNext", + "lib": ["ESNext", "DOM"], + "baseUrl": "..", + "paths": { + "src/*": ["./src/*"], + "page-objects/*": ["./playwright/page-objects/*"] + }, + "noEmit": false, + "isolatedModules": false + }, + "include": [ + ".", + "../config/*" + ] +} diff --git a/playwright/utils/test-decorators.ts b/playwright/utils/test-decorators.ts new file mode 100644 index 00000000..4a222d6b --- /dev/null +++ b/playwright/utils/test-decorators.ts @@ -0,0 +1,22 @@ +/* eslint-disable ts/no-unsafe-function-type,ts/no-unsafe-return */ +import { test } from '../extends' + +export function step(target: Function, context: ClassMethodDecoratorContext) { + return async function replacementMethod(this: Function, ...args: unknown[]) { + const className = this.constructor.name + const name = `${className.replace(/PageObject$/, '')}.${context.name as string}` + return await test.step(name, async () => { + return await target.call(this, ...args) + }) + } +} + +export function boxedStep(target: Function, context: ClassMethodDecoratorContext) { + return async function replacementMethod(this: Function, ...args: unknown[]) { + const className = this.constructor.name + const name = `${className.replace(/PageObject$/, '')}.${context.name as string}` + return await test.step(name, async () => { + return await target.call(this, ...args) + }, { box: true }) + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e2374fd4..34145569 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,46 +26,49 @@ importers: devDependencies: '@mutoe/eslint-config': specifier: ^4.11.0-2 - version: 4.11.0-2(@typescript-eslint/utils@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(@vue/compiler-sfc@3.5.22)(eslint-import-resolver-node@0.3.9)(eslint-plugin-vuejs-accessibility@2.4.1(eslint@9.36.0(jiti@2.6.0)))(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1)) + version: 4.11.0-2(@typescript-eslint/utils@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(@vue/compiler-sfc@3.5.22)(eslint-import-resolver-node@0.3.9)(eslint-plugin-vuejs-accessibility@2.4.1(eslint@9.36.0(jiti@2.6.0)))(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1)) '@pinia/testing': specifier: ^1.0.2 version: 1.0.2(pinia@3.0.3(typescript@5.9.2)(vue@3.5.22(typescript@5.9.2))) - '@testing-library/cypress': - specifier: ^10.1.0 - version: 10.1.0(cypress@13.13.2) + '@playwright/test': + specifier: 1.55.1 + version: 1.55.1 '@testing-library/user-event': specifier: ^14.6.1 version: 14.6.1(@testing-library/dom@10.4.0) '@testing-library/vue': specifier: ^8.1.0 version: 8.1.0(@vue/compiler-sfc@3.5.22)(@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.2)))(vue@3.5.22(typescript@5.9.2)) + '@types/node': + specifier: ^24.5.2 + version: 24.5.2 '@vitejs/plugin-vue': specifier: ^6.0.1 - version: 6.0.1(vite@7.1.7(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.2)) + version: 6.0.1(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.2)) '@vitest/coverage-v8': specifier: ^3.2.4 - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1)) - concurrently: - specifier: ^9.2.1 - version: 9.2.1 - cypress: - specifier: ^13.13.2 - version: 13.13.2 + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1)) + cross-env: + specifier: ^7.0.3 + version: 7.0.3 eslint: specifier: ^9.36.0 version: 9.36.0(jiti@2.6.0) - eslint-plugin-cypress: - specifier: ^5.1.1 - version: 5.1.1(eslint@9.36.0(jiti@2.6.0)) + eslint-plugin-vuejs-accessibility: + specifier: ^2.4.1 + version: 2.4.1(eslint@9.36.0(jiti@2.6.0)) happy-dom: specifier: ^18.0.1 version: 18.0.1 lint-staged: specifier: ^16.2.0 version: 16.2.0 + monocart-coverage-reports: + specifier: ^2.12.9 + version: 2.12.9 msw: specifier: ^2.11.3 - version: 2.11.3(@types/node@20.19.17)(typescript@5.9.2) + version: 2.11.3(@types/node@24.5.2)(typescript@5.9.2) rollup-plugin-analyzer: specifier: ^4.0.0 version: 4.0.0 @@ -75,18 +78,24 @@ importers: swagger-typescript-api: specifier: ^13.2.13 version: 13.2.13(magicast@0.3.5) + tsx: + specifier: ^4.20.6 + version: 4.20.6 typescript: specifier: ~5.9.2 version: 5.9.2 vite: specifier: ^7.1.7 - version: 7.1.7(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1) + version: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1) vitest: specifier: ^3.2.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1) vitest-dom: specifier: ^0.1.1 - version: 0.1.1(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1)) + version: 0.1.1(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1)) + vitest-monocart-coverage: + specifier: ^3.0.2 + version: 3.0.2(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1)) vue-tsc: specifier: ^3.0.8 version: 3.0.8(typescript@5.9.2) @@ -112,6 +121,36 @@ packages: resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} + '@babel/compat-data@7.28.4': + resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.4': + resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.3': + resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-string-parser@7.24.8': resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} engines: {node: '>=6.9.0'} @@ -124,10 +163,22 @@ packages: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.27.1': resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + '@babel/highlight@7.23.4': resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} @@ -146,6 +197,14 @@ packages: resolution: {integrity: sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==} engines: {node: '>=6.9.0'} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.4': + resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} + engines: {node: '>=6.9.0'} + '@babel/types@7.25.2': resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} engines: {node: '>=6.9.0'} @@ -187,17 +246,6 @@ packages: '@clack/prompts@0.10.1': resolution: {integrity: sha512-Q0T02vx8ZM9XSv9/Yde0jTmmBQufZhPJfYAg2XrrrxWWaZgq1rr8nU8Hv710BQ1dhoP8rtY7YUdpGej2Qza/cw==} - '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} - - '@cypress/request@3.0.1': - resolution: {integrity: sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==} - engines: {node: '>= 6'} - - '@cypress/xvfb@1.2.4': - resolution: {integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==} - '@emnapi/core@1.5.0': resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} @@ -373,12 +421,22 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.9.0': resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/regexpp@4.10.0': + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + '@eslint-community/regexpp@4.12.1': resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -494,10 +552,16 @@ packages: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.1': resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} @@ -613,6 +677,11 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@playwright/test@1.55.1': + resolution: {integrity: sha512-IVAh/nOJaw6W9g+RJVlIQJ6gSiER+ae6mKQ5CX1bERzQgbC1VSeBlwdvczT7pxb0GWiyrxH4TGKbMfDb4Sq/ig==} + engines: {node: '>=18'} + hasBin: true + '@rolldown/pluginutils@1.0.0-beta.29': resolution: {integrity: sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==} @@ -732,12 +801,6 @@ packages: peerDependencies: eslint: '>=9.0.0' - '@testing-library/cypress@10.1.0': - resolution: {integrity: sha512-tNkNtYRqPQh71xXKuMizr146zlellawUfDth7A/urYU4J66g0VGZ063YsS0gqS79Z58u1G/uo9UxN05qvKXMag==} - engines: {node: '>=12', npm: '>=6'} - peerDependencies: - cypress: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 - '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} @@ -780,6 +843,9 @@ packages: '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -798,18 +864,12 @@ packages: '@types/node@20.19.17': resolution: {integrity: sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ==} - '@types/node@22.1.0': - resolution: {integrity: sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==} + '@types/node@24.5.2': + resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - '@types/sinonjs__fake-timers@8.1.1': - resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==} - - '@types/sizzle@2.3.8': - resolution: {integrity: sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==} - '@types/statuses@2.0.4': resolution: {integrity: sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==} @@ -825,9 +885,6 @@ packages: '@types/whatwg-mimetype@3.0.2': resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} - '@types/yauzl@2.10.3': - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.44.1': resolution: {integrity: sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -989,6 +1046,11 @@ packages: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vue: ^3.2.25 + '@vitest/coverage-istanbul@3.2.4': + resolution: {integrity: sha512-IDlpuFJiWU9rhcKLkpzj8mFu/lpe64gVgnV15ZOrYx1iFzxxrxCzbExiUEKtwwXRvEiEMUS6iZeYgnMxgbqbxQ==} + peerDependencies: + vitest: 3.2.4 + '@vitest/coverage-v8@3.2.4': resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} peerDependencies: @@ -1127,29 +1189,30 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-loose@8.5.2: + resolution: {integrity: sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==} + engines: {node: '>=0.4.0'} + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} hasBin: true - aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} alien-signals@2.0.7: resolution: {integrity: sha512-wE7y3jmYeb0+h6mr5BOovuqhFv22O/MV9j5p0ndJsa7z1zJNPGQ4ph5pQk/kTTCWRC3xsA4SmtwmkzQO+7NCNg==} - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - - ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - ansi-escapes@7.0.0: resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} engines: {node: '>=18'} @@ -1182,9 +1245,6 @@ packages: resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} engines: {node: '>=14'} - arch@2.2.0: - resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} - are-docs-informative@0.0.2: resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} engines: {node: '>=14'} @@ -1198,20 +1258,9 @@ packages: aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} - array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - - assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -1222,52 +1271,20 @@ packages: ast-v8-to-istanbul@0.3.5: resolution: {integrity: sha512-9SdXjNheSiE8bALAQCQQuT6fgQaoxJh7IRYrRGZ8/9nv8WhJeC1aXAwN8TbaOssGOukUvyvnkgD9+Yuykvl1aA==} - astral-regex@2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} - - async@3.2.5: - resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - at-least-node@1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} - available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} - aws-sign2@0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - - aws4@1.12.0: - resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.8.6: resolution: {integrity: sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==} hasBin: true - bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - birpc@2.5.0: resolution: {integrity: sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==} - blob-util@2.0.2: - resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==} - - bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -1286,12 +1303,6 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - builtin-modules@4.0.0: resolution: {integrity: sha512-p1n8zyCkt1BVrKNFymOHjcDSAl7oq/gUvfgULv2EblgpPVQlQr9yHnWjg9IJ2MhfwPqiYqMMrr01OY7yQoK2yA==} engines: {node: '>=18.20'} @@ -1308,10 +1319,6 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - cachedir@2.4.0: - resolution: {integrity: sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==} - engines: {node: '>=6'} - call-bind@1.0.5: resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} @@ -1325,9 +1332,6 @@ packages: caniuse-lite@1.0.30001745: resolution: {integrity: sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==} - caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1354,18 +1358,10 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} - check-more-types@2.24.0: - resolution: {integrity: sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==} - engines: {node: '>= 0.8.0'} - chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - ci-info@4.3.0: resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==} engines: {node: '>=8'} @@ -1377,26 +1373,10 @@ packages: resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} engines: {node: '>=4'} - clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - cli-cursor@5.0.0: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} engines: {node: '>=18'} - cli-table3@0.6.3: - resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} - engines: {node: 10.* || >= 12.*} - - cli-truncate@2.1.0: - resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} - engines: {node: '>=8'} - cli-truncate@5.1.0: resolution: {integrity: sha512-7JDGG+4Zp0CsknDCedl0DYdaeOhc46QNpXi3NLQblkZpXXgA6LncLDUUyvrjSvZeF3VRQa+KiMGomazQrC1V8g==} engines: {node: '>=20'} @@ -1425,10 +1405,6 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} @@ -1437,26 +1413,13 @@ packages: resolution: {integrity: sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==} engines: {node: '>=20'} - commander@6.2.1: - resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} - engines: {node: '>= 6'} - comment-parser@1.4.1: resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} engines: {node: '>= 12.0.0'} - common-tags@1.8.2: - resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} - engines: {node: '>=4.0.0'} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - concurrently@9.2.1: - resolution: {integrity: sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==} - engines: {node: '>=18'} - hasBin: true - confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -1470,6 +1433,12 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + console-grid@2.2.3: + resolution: {integrity: sha512-+mecFacaFxGl+1G31IsCx41taUXuW2FxX+4xIE0TIPhgML+Jb9JFcBWGhhWerd1/vhScubdmHqTwOhB0KCUUAg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} @@ -1481,12 +1450,10 @@ packages: core-js-compat@3.45.1: resolution: {integrity: sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA==} - core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} + cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} @@ -1503,18 +1470,6 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - cypress@13.13.2: - resolution: {integrity: sha512-PvJQU33933NvS1StfzEb8/mu2kMy4dABwCF+yd5Bi7Qly1HOVf+Bufrygee/tlmty/6j5lX+KIi8j9Q3JUMbhA==} - engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} - hasBin: true - - dashdash@1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} - - dayjs@1.11.10: - resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} - de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} @@ -1569,10 +1524,6 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -1596,14 +1547,14 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - ecc-jsbn@0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - editorconfig@1.0.4: resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==} engines: {node: '>=14'} hasBin: true + eight-colors@1.3.1: + resolution: {integrity: sha512-7nXPYDeKh6DgJDR/mpt2G7N/hCNSGwwoPVmoI3+4TEwOb07VFN1WMPG0DFf6nMEjrkgdj8Og7l7IaEEk3VE6Zg==} + electron-to-chromium@1.5.223: resolution: {integrity: sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==} @@ -1616,17 +1567,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - enhanced-resolve@5.18.3: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} - enquirer@2.4.1: - resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} - engines: {node: '>=8.6'} - entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -1649,6 +1593,10 @@ packages: engines: {node: '>=18'} hasBin: true + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1723,11 +1671,6 @@ packages: peerDependencies: eslint: '*' - eslint-plugin-cypress@5.1.1: - resolution: {integrity: sha512-LxTmZf1LLh9EklZBVvKNEZj71X9tCJnlYDviAJGsOgEVc6jz+tBODSpm02CS/9eJOfRqGsmVyvIw7LHXQ13RaA==} - peerDependencies: - eslint: '>=9' - eslint-plugin-es-x@7.8.0: resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -1899,20 +1842,9 @@ packages: resolution: {integrity: sha512-0h0oBEsF6qAJU7eu9ztvJoTo8D2PAq/4FvXVIQA1fek3WOTe6KPsVJycekG1+g1N6mfpblkheoGwaUhMtnlH4A==} engines: {node: '>=20'} - eventemitter2@6.4.7: - resolution: {integrity: sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==} - eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - execa@4.1.0: - resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} - engines: {node: '>=10'} - - executable@4.1.1: - resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} - engines: {node: '>=4'} - expect-type@1.2.2: resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} engines: {node: '>=12.0.0'} @@ -1920,18 +1852,6 @@ packages: exsolve@1.0.7: resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - extract-zip@2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true - - extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1954,9 +1874,6 @@ packages: fault@2.0.1: resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1966,10 +1883,6 @@ packages: picomatch: optional: true - figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -2004,20 +1917,18 @@ packages: resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} engines: {node: '>=14'} - forever-agent@0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - - form-data@2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} format@0.2.2: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} - fs-extra@9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} @@ -2030,6 +1941,10 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -2048,19 +1963,9 @@ packages: get-intrinsic@1.2.2: resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} - get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - get-tsconfig@4.10.1: resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} - getos@3.2.1: - resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} - - getpass@0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - giget@2.0.0: resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} hasBin: true @@ -2085,10 +1990,6 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true - global-dirs@3.0.1: - resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} - engines: {node: '>=10'} - globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -2172,19 +2073,12 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - http-signature@1.3.6: - resolution: {integrity: sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==} - engines: {node: '>=0.10'} - http2-client@1.3.5: resolution: {integrity: sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==} - human-signals@1.1.1: - resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} - engines: {node: '>=8.12.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} @@ -2202,10 +2096,6 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - indent-string@5.0.0: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} @@ -2217,10 +2107,6 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - ini@2.0.0: - resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} - engines: {node: '>=10'} - insane@2.6.2: resolution: {integrity: sha512-BqEL1CJsjJi+/C/zKZxv31zs3r6zkLH5Nz1WMFb7UBX2KHY2yXDpbFTSEmNHzomBbGDysIfkTX55A0mQZ2CQiw==} @@ -2250,10 +2136,6 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-ci@3.0.1: - resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} - hasBin: true - is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} @@ -2277,10 +2159,6 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-installed-globally@0.4.0: - resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} - engines: {node: '>=10'} - is-map@2.0.2: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} @@ -2295,10 +2173,6 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -2309,10 +2183,6 @@ packages: is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -2325,13 +2195,6 @@ packages: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} - is-typedarray@1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - is-weakmap@2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} @@ -2348,13 +2211,14 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + istanbul-lib-report@3.0.1: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} @@ -2367,6 +2231,10 @@ packages: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + jackspeak@2.3.6: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} @@ -2393,8 +2261,9 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsbn@0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + jsdoc-type-pratt-parser@4.0.0: + resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==} + engines: {node: '>=12.0.0'} jsdoc-type-pratt-parser@4.1.0: resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} @@ -2416,33 +2285,21 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true jsonc-eslint-parser@2.4.0: resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - - jsprim@2.0.2: - resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} - engines: {'0': node >=0.6.0} - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - lazy-ass@1.6.0: - resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} - engines: {node: '> 0.8'} - levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -2452,15 +2309,6 @@ packages: engines: {node: '>=20.17'} hasBin: true - listr2@3.14.0: - resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==} - engines: {node: '>=10.0.0'} - peerDependencies: - enquirer: '>= 2.3.0 < 3' - peerDependenciesMeta: - enquirer: - optional: true - listr2@9.0.4: resolution: {integrity: sha512-1wd/kpAdKRLwv7/3OKC8zZ5U8e/fajCfWMxacUvB79S5nLrYGPtUI/8chMQhn3LQjsRVErTb9i1ECAwW0ZIHnQ==} engines: {node: '>=20.0.0'} @@ -2479,20 +2327,9 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash.once@4.1.1: - resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - log-update@4.0.0: - resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} - engines: {node: '>=10'} - log-update@6.1.0: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} @@ -2513,10 +2350,16 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true + lz-utils@2.1.0: + resolution: {integrity: sha512-CMkfimAypidTtWjNDxY8a1bc1mJdyEh04V2FfEQ5Zh8Nx4v7k850EYa+dOWGn9hKG5xOyHP5MkuduAZCTHRvJw==} + magic-string@0.30.19: resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} @@ -2571,9 +2414,6 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2673,18 +2513,6 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - mimic-function@5.0.1: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} @@ -2704,9 +2532,6 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.0.4: resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} @@ -2721,6 +2546,13 @@ packages: mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + monocart-coverage-reports@2.12.9: + resolution: {integrity: sha512-vtFqbC3Egl4nVa1FSIrQvMPO6HZtb9lo+3IW7/crdvrLNW2IH8lUsxaK0TsKNmMO2mhFWwqQywLV2CZelqPgwA==} + hasBin: true + + monocart-locator@1.0.2: + resolution: {integrity: sha512-v8W5hJLcWMIxLCcSi/MHh+VeefI+ycFmGz23Froer9QzWjrbg4J3gFJBuI/T1VLNoYxF47bVPPxq8ZlNX4gVCw==} + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -2804,10 +2636,6 @@ packages: resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} engines: {node: ^16.14.0 || >=18.0.0} - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -2850,13 +2678,6 @@ packages: ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - onetime@7.0.0: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} @@ -2868,9 +2689,6 @@ packages: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} - ospath@1.2.2: - resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==} - outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} @@ -2882,10 +2700,6 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} - package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} @@ -2942,18 +2756,12 @@ packages: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} perfect-debounce@2.0.0: resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} - performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2974,10 +2782,6 @@ packages: engines: {node: '>=0.10'} hasBin: true - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - pinia@3.0.3: resolution: {integrity: sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==} peerDependencies: @@ -2993,6 +2797,16 @@ packages: pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + playwright-core@1.55.1: + resolution: {integrity: sha512-Z6Mh9mkwX+zxSlHqdr5AOcJnfp+xUWLCt9uKV18fhzA8eyxUd8NUWzAjxUh55RZKSYwDGX0cfaySdhZJGMoJ+w==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.55.1: + resolution: {integrity: sha512-cJW4Xd/G3v5ovXtJJ52MAOclqeac9S/aGGgRzLabuF8TnIb6xHvMzKIa6JmrRzUkeXJgfL1MhukP0NK6l39h3A==} + engines: {node: '>=18'} + hasBin: true + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -3012,44 +2826,20 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - pretty-bytes@5.6.0: - resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} - engines: {node: '>=6'} - pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} - process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} - proxy-from-env@1.0.0: - resolution: {integrity: sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==} - - psl@1.9.0: - resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - - pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - qs@6.10.4: - resolution: {integrity: sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==} - engines: {node: '>=0.6'} - quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} - querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -3101,16 +2891,10 @@ packages: resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} hasBin: true - request-progress@3.0.0: - resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==} - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -3122,10 +2906,6 @@ packages: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - restore-cursor@5.1.0: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} @@ -3137,9 +2917,6 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rfdc@1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} - rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} @@ -3155,22 +2932,14 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - rxjs@7.8.1: - resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} - - rxjs@7.8.2: - resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - scslre@0.3.0: resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} engines: {node: ^14.0.0 || >=16.0.0} + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + semver@7.6.3: resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} @@ -3197,10 +2966,6 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.8.3: - resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} - engines: {node: '>= 0.4'} - should-equal@2.0.0: resolution: {integrity: sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==} @@ -3225,9 +2990,6 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} @@ -3239,14 +3001,6 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - slice-ansi@3.0.0: - resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} - engines: {node: '>=8'} - - slice-ansi@4.0.0: - resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} - engines: {node: '>=10'} - slice-ansi@7.1.0: resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} engines: {node: '>=18'} @@ -3274,11 +3028,6 @@ packages: resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} engines: {node: '>=0.10.0'} - sshpk@1.18.0: - resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} - engines: {node: '>=0.10.0'} - hasBin: true - stable-hash-x@0.2.0: resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} engines: {node: '>=12.0.0'} @@ -3328,10 +3077,6 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - strip-indent@4.0.0: resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} engines: {node: '>=12'} @@ -3355,10 +3100,6 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -3387,12 +3128,6 @@ packages: resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} - throttleit@1.0.1: - resolution: {integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==} - - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -3425,10 +3160,6 @@ packages: resolution: {integrity: sha512-5bdPHSwbKTeHmXrgecID4Ljff8rQjv7g8zKQPkCozRo2HWWni+p310FSn5ImI+9kWw9kK4lzOB5q/a6iv0IJsw==} hasBin: true - tmp@0.2.3: - resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} - engines: {node: '>=14.14'} - to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -3441,10 +3172,6 @@ packages: resolution: {integrity: sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} - engines: {node: '>=6'} - tough-cookie@6.0.0: resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} engines: {node: '>=16'} @@ -3452,10 +3179,6 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - ts-api-utils@2.1.0: resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} @@ -3470,20 +3193,15 @@ packages: tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - - tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + tsx@4.20.6: + resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + engines: {node: '>=18.0.0'} + hasBin: true type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - type-fest@4.24.0: resolution: {integrity: sha512-spAaHzc6qre0TlZQQ2aA/nGMe+2Z/wyGk5Z+Ru2VUfdNwT6kWO6TjevOlpebsATEG1EIQ2sOiDszud3lO5mt/Q==} engines: {node: '>=16'} @@ -3500,12 +3218,12 @@ packages: ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - undici-types@6.13.0: - resolution: {integrity: sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==} - undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.12.0: + resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} + unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} @@ -3522,24 +3240,12 @@ packages: unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - unrs-resolver@1.11.1: resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} until-async@3.0.2: resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} - untildify@4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} - update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true @@ -3549,23 +3255,12 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - vite-node@3.2.4: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -3616,6 +3311,9 @@ packages: peerDependencies: vitest: '>=0.31.0' + vitest-monocart-coverage@3.0.2: + resolution: {integrity: sha512-5Bs89Apt/tJeBiman/IDekGTgyhonqA4UV/nBW153358uyO5vfBH0mAChz+l52C/+FVzAQR1zOl4nOKE/TP6EA==} + vitest@3.2.4: resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -3727,9 +3425,6 @@ packages: resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} engines: {node: '>=18'} - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} @@ -3738,6 +3433,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml-eslint-parser@1.3.0: resolution: {integrity: sha512-E/+VitOorXSLiAqtTd7Yqax0/pAS3xaYMP+AUUJGOK1OZG3rhcj9fcJOM5HJ2VrP1FrStVCWr1muTfQCdj4tAA==} engines: {node: ^14.17.0 || >=16.0.0} @@ -3764,9 +3462,6 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -3803,14 +3498,79 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/compat-data@7.28.4': {} + + '@babel/core@7.28.4': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.4 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.3': + dependencies: + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.4 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.26.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/helper-string-parser@7.24.8': {} '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.22.20': {} + '@babel/helper-validator-identifier@7.24.7': {} + '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.4 + '@babel/highlight@7.23.4': dependencies: '@babel/helper-validator-identifier': 7.22.20 @@ -3829,10 +3589,28 @@ snapshots: dependencies: regenerator-runtime: 0.14.0 + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 + + '@babel/traverse@7.28.4': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.3 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.4 + '@babel/template': 7.27.2 + '@babel/types': 7.28.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + '@babel/types@7.25.2': dependencies: '@babel/helper-string-parser': 7.24.8 - '@babel/helper-validator-identifier': 7.27.1 + '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 '@babel/types@7.28.4': @@ -3867,37 +3645,6 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 - '@colors/colors@1.5.0': - optional: true - - '@cypress/request@3.0.1': - dependencies: - aws-sign2: 0.7.0 - aws4: 1.12.0 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - http-signature: 1.3.6 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - performance-now: 2.1.0 - qs: 6.10.4 - safe-buffer: 5.2.1 - tough-cookie: 4.1.4 - tunnel-agent: 0.6.0 - uuid: 8.3.2 - - '@cypress/xvfb@1.2.4(supports-color@8.1.1)': - dependencies: - debug: 3.2.7(supports-color@8.1.1) - lodash.once: 4.1.1 - transitivePeerDependencies: - - supports-color - '@emnapi/core@1.5.0': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -4004,13 +3751,20 @@ snapshots: dependencies: escape-string-regexp: 4.0.0 eslint: 9.36.0(jiti@2.6.0) - ignore: 5.3.2 + ignore: 5.3.1 + + '@eslint-community/eslint-utils@4.4.0(eslint@9.36.0(jiti@2.6.0))': + dependencies: + eslint: 9.36.0(jiti@2.6.0) + eslint-visitor-keys: 3.4.3 '@eslint-community/eslint-utils@4.9.0(eslint@9.36.0(jiti@2.6.0))': dependencies: eslint: 9.36.0(jiti@2.6.0) eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.10.0': {} + '@eslint-community/regexpp@4.12.1': {} '@eslint/compat@1.4.0(eslint@9.36.0(jiti@2.6.0))': @@ -4022,7 +3776,7 @@ snapshots: '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.3.6 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -4044,10 +3798,10 @@ snapshots: '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.3.6 espree: 10.4.0 globals: 14.0.0 - ignore: 5.3.2 + ignore: 5.3.1 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -4092,31 +3846,31 @@ snapshots: '@inquirer/ansi@1.0.0': {} - '@inquirer/confirm@5.1.18(@types/node@20.19.17)': + '@inquirer/confirm@5.1.18(@types/node@24.5.2)': dependencies: - '@inquirer/core': 10.2.2(@types/node@20.19.17) - '@inquirer/type': 3.0.8(@types/node@20.19.17) + '@inquirer/core': 10.2.2(@types/node@24.5.2) + '@inquirer/type': 3.0.8(@types/node@24.5.2) optionalDependencies: - '@types/node': 20.19.17 + '@types/node': 24.5.2 - '@inquirer/core@10.2.2(@types/node@20.19.17)': + '@inquirer/core@10.2.2(@types/node@24.5.2)': dependencies: '@inquirer/ansi': 1.0.0 '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@20.19.17) + '@inquirer/type': 3.0.8(@types/node@24.5.2) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 20.19.17 + '@types/node': 24.5.2 '@inquirer/figures@1.0.13': {} - '@inquirer/type@3.0.8(@types/node@20.19.17)': + '@inquirer/type@3.0.8(@types/node@24.5.2)': optionalDependencies: - '@types/node': 20.19.17 + '@types/node': 24.5.2 '@isaacs/cliui@8.0.2': dependencies: @@ -4129,12 +3883,22 @@ snapshots: '@istanbuljs/schema@0.1.3': {} + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/resolve-uri@3.1.1': {} '@jridgewell/set-array@1.2.1': {} @@ -4162,7 +3926,7 @@ snapshots: outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@mutoe/eslint-config@4.11.0-2(@typescript-eslint/utils@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(@vue/compiler-sfc@3.5.22)(eslint-import-resolver-node@0.3.9)(eslint-plugin-vuejs-accessibility@2.4.1(eslint@9.36.0(jiti@2.6.0)))(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1))': + '@mutoe/eslint-config@4.11.0-2(@typescript-eslint/utils@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(@vue/compiler-sfc@3.5.22)(eslint-import-resolver-node@0.3.9)(eslint-plugin-vuejs-accessibility@2.4.1(eslint@9.36.0(jiti@2.6.0)))(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@antfu/install-pkg': 1.1.0 '@clack/prompts': 0.10.1 @@ -4172,7 +3936,7 @@ snapshots: '@stylistic/eslint-plugin': 4.4.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2) '@typescript-eslint/eslint-plugin': 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2) '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2) - '@vitest/eslint-plugin': 1.3.12(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1)) + '@vitest/eslint-plugin': 1.3.12(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1)) ansis: 3.17.0 cac: 6.7.14 eslint: 9.36.0(jiti@2.6.0) @@ -4262,6 +4026,10 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@playwright/test@1.55.1': + dependencies: + playwright: 1.55.1 + '@rolldown/pluginutils@1.0.0-beta.29': {} '@rollup/rollup-android-arm-eabi@4.52.2': @@ -4342,12 +4110,6 @@ snapshots: - supports-color - typescript - '@testing-library/cypress@10.1.0(cypress@13.13.2)': - dependencies: - '@babel/runtime': 7.23.4 - '@testing-library/dom': 10.4.0 - cypress: 13.13.2 - '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.27.1 @@ -4404,6 +4166,8 @@ snapshots: '@types/deep-eql@4.0.2': {} + '@types/estree@1.0.5': {} + '@types/estree@1.0.8': {} '@types/json-schema@7.0.15': {} @@ -4420,17 +4184,12 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@22.1.0': + '@types/node@24.5.2': dependencies: - undici-types: 6.13.0 - optional: true + undici-types: 7.12.0 '@types/normalize-package-data@2.4.4': {} - '@types/sinonjs__fake-timers@8.1.1': {} - - '@types/sizzle@2.3.8': {} - '@types/statuses@2.0.4': {} '@types/swagger-schema-official@2.0.25': {} @@ -4441,14 +4200,9 @@ snapshots: '@types/whatwg-mimetype@3.0.2': {} - '@types/yauzl@2.10.3': - dependencies: - '@types/node': 22.1.0 - optional: true - '@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)': dependencies: - '@eslint-community/regexpp': 4.12.1 + '@eslint-community/regexpp': 4.10.0 '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2) '@typescript-eslint/scope-manager': 8.44.1 '@typescript-eslint/type-utils': 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2) @@ -4469,7 +4223,7 @@ snapshots: '@typescript-eslint/types': 8.44.1 '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.44.1 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.3.6 eslint: 9.36.0(jiti@2.6.0) typescript: 5.9.2 transitivePeerDependencies: @@ -4479,7 +4233,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) '@typescript-eslint/types': 8.44.1 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.3.6 typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -4498,7 +4252,7 @@ snapshots: '@typescript-eslint/types': 8.44.1 '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) '@typescript-eslint/utils': 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2) - debug: 4.4.3(supports-color@8.1.1) + debug: 4.3.6 eslint: 9.36.0(jiti@2.6.0) ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 @@ -4513,11 +4267,11 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) '@typescript-eslint/types': 8.44.1 '@typescript-eslint/visitor-keys': 8.44.1 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.3.6 fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.6.3 ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: @@ -4598,18 +4352,34 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true - '@vitejs/plugin-vue@6.0.1(vite@7.1.7(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.2))': + '@vitejs/plugin-vue@6.0.1(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.2))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.29 - vite: 7.1.7(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1) vue: 3.5.22(typescript@5.9.2) - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1))': + '@vitest/coverage-istanbul@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1))': + dependencies: + '@istanbuljs/schema': 0.1.3 + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.2.0 + magicast: 0.3.5 + test-exclude: 7.0.1 + tinyrainbow: 2.0.0 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1) + transitivePeerDependencies: + - supports-color + + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 ast-v8-to-istanbul: 0.3.5 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 @@ -4619,18 +4389,18 @@ snapshots: std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@vitest/eslint-plugin@1.3.12(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1))': + '@vitest/eslint-plugin@1.3.12(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@typescript-eslint/scope-manager': 8.44.1 '@typescript-eslint/utils': 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2) eslint: 9.36.0(jiti@2.6.0) optionalDependencies: typescript: 5.9.2 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -4642,14 +4412,14 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(vite@7.1.7(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: - msw: 2.11.3(@types/node@20.19.17)(typescript@5.9.2) - vite: 7.1.7(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1) + msw: 2.11.3(@types/node@24.5.2)(typescript@5.9.2) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -4766,7 +4536,7 @@ snapshots: alien-signals: 2.0.7 muggle-string: 0.4.1 path-browserify: 1.0.1 - picomatch: 4.0.3 + picomatch: 4.0.2 optionalDependencies: typescript: 5.9.2 @@ -4806,16 +4576,25 @@ snapshots: abbrev@2.0.0: {} + acorn-jsx@5.3.2(acorn@8.12.1): + dependencies: + acorn: 8.12.1 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 - acorn@8.15.0: {} + acorn-loose@8.5.2: + dependencies: + acorn: 8.15.0 - aggregate-error@3.1.0: + acorn-walk@8.3.4: dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 + acorn: 8.15.0 + + acorn@8.12.1: {} + + acorn@8.15.0: {} ajv@6.12.6: dependencies: @@ -4826,12 +4605,6 @@ snapshots: alien-signals@2.0.7: {} - ansi-colors@4.1.3: {} - - ansi-escapes@4.3.2: - dependencies: - type-fest: 0.21.3 - ansi-escapes@7.0.0: dependencies: environment: 1.1.0 @@ -4854,8 +4627,6 @@ snapshots: ansis@3.17.0: {} - arch@2.2.0: {} - are-docs-informative@0.0.2: {} argparse@2.0.1: {} @@ -4868,20 +4639,11 @@ snapshots: dependencies: dequal: 2.0.3 - aria-query@5.3.2: - optional: true - array-buffer-byte-length@1.0.0: dependencies: call-bind: 1.0.5 is-array-buffer: 3.0.2 - asn1@0.2.6: - dependencies: - safer-buffer: 2.1.2 - - assert-plus@1.0.0: {} - assertion-error@2.0.1: {} assignment@2.0.0: {} @@ -4892,36 +4654,14 @@ snapshots: estree-walker: 3.0.3 js-tokens: 9.0.1 - astral-regex@2.0.0: {} - - async@3.2.5: {} - - asynckit@0.4.0: {} - - at-least-node@1.0.0: {} - available-typed-arrays@1.0.5: {} - aws-sign2@0.7.0: {} - - aws4@1.12.0: {} - balanced-match@1.0.2: {} - base64-js@1.5.1: {} - baseline-browser-mapping@2.8.6: {} - bcrypt-pbkdf@1.0.2: - dependencies: - tweetnacl: 0.14.5 - birpc@2.5.0: {} - blob-util@2.0.2: {} - - bluebird@3.7.2: {} - boolbase@1.0.0: {} brace-expansion@1.1.11: @@ -4945,13 +4685,6 @@ snapshots: node-releases: 2.0.21 update-browserslist-db: 1.1.3(browserslist@4.26.2) - buffer-crc32@0.2.13: {} - - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - builtin-modules@4.0.0: {} c12@3.3.0(magicast@0.3.5): @@ -4973,8 +4706,6 @@ snapshots: cac@6.7.14: {} - cachedir@2.4.0: {} - call-bind@1.0.5: dependencies: function-bind: 1.1.2 @@ -4987,8 +4718,6 @@ snapshots: caniuse-lite@1.0.30001745: {} - caseless@0.12.0: {} - ccount@2.0.1: {} chai@5.3.3: @@ -5016,14 +4745,10 @@ snapshots: check-error@2.1.1: {} - check-more-types@2.24.0: {} - chokidar@4.0.3: dependencies: readdirp: 4.1.2 - ci-info@3.9.0: {} - ci-info@4.3.0: {} citty@0.1.6: @@ -5034,27 +4759,10 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - clean-stack@2.2.0: {} - - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - cli-cursor@5.0.0: dependencies: restore-cursor: 5.1.0 - cli-table3@0.6.3: - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - - cli-truncate@2.1.0: - dependencies: - slice-ansi: 3.0.0 - string-width: 4.2.3 - cli-truncate@5.1.0: dependencies: slice-ansi: 7.1.0 @@ -5082,31 +4790,14 @@ snapshots: colorette@2.0.20: {} - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - commander@10.0.1: {} commander@14.0.1: {} - commander@6.2.1: {} - comment-parser@1.4.1: {} - common-tags@1.8.2: {} - concat-map@0.0.1: {} - concurrently@9.2.1: - dependencies: - chalk: 4.1.2 - rxjs: 7.8.2 - shell-quote: 1.8.3 - supports-color: 8.1.1 - tree-kill: 1.2.2 - yargs: 17.7.2 - confbox@0.1.8: {} confbox@0.2.2: {} @@ -5118,6 +4809,10 @@ snapshots: consola@3.4.2: {} + console-grid@2.2.3: {} + + convert-source-map@2.0.0: {} + cookie@0.7.2: {} copy-anything@3.0.5: @@ -5128,13 +4823,9 @@ snapshots: dependencies: browserslist: 4.26.2 - core-util-is@1.0.2: {} - - cross-spawn@7.0.3: + cross-env@7.0.3: dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 + cross-spawn: 7.0.6 cross-spawn@7.0.6: dependencies: @@ -5148,76 +4839,20 @@ snapshots: csstype@3.1.3: {} - cypress@13.13.2: - dependencies: - '@cypress/request': 3.0.1 - '@cypress/xvfb': 1.2.4(supports-color@8.1.1) - '@types/sinonjs__fake-timers': 8.1.1 - '@types/sizzle': 2.3.8 - arch: 2.2.0 - blob-util: 2.0.2 - bluebird: 3.7.2 - buffer: 5.7.1 - cachedir: 2.4.0 - chalk: 4.1.2 - check-more-types: 2.24.0 - cli-cursor: 3.1.0 - cli-table3: 0.6.3 - commander: 6.2.1 - common-tags: 1.8.2 - dayjs: 1.11.10 - debug: 4.3.6(supports-color@8.1.1) - enquirer: 2.4.1 - eventemitter2: 6.4.7 - execa: 4.1.0 - executable: 4.1.1 - extract-zip: 2.0.1(supports-color@8.1.1) - figures: 3.2.0 - fs-extra: 9.1.0 - getos: 3.2.1 - is-ci: 3.0.1 - is-installed-globally: 0.4.0 - lazy-ass: 1.6.0 - listr2: 3.14.0(enquirer@2.4.1) - lodash: 4.17.21 - log-symbols: 4.1.0 - minimist: 1.2.8 - ospath: 1.2.2 - pretty-bytes: 5.6.0 - process: 0.11.10 - proxy-from-env: 1.0.0 - request-progress: 3.0.0 - semver: 7.6.3 - supports-color: 8.1.1 - tmp: 0.2.3 - untildify: 4.0.0 - yauzl: 2.10.0 - - dashdash@1.14.1: - dependencies: - assert-plus: 1.0.0 - - dayjs@1.11.10: {} - de-indent@1.0.2: {} - debug@3.2.7(supports-color@8.1.1): + debug@3.2.7: dependencies: ms: 2.1.3 - optionalDependencies: - supports-color: 8.1.1 + optional: true - debug@4.3.6(supports-color@8.1.1): + debug@4.3.6: dependencies: ms: 2.1.2 - optionalDependencies: - supports-color: 8.1.1 - debug@4.4.3(supports-color@8.1.1): + debug@4.4.3: dependencies: ms: 2.1.3 - optionalDependencies: - supports-color: 8.1.1 decode-named-character-reference@1.2.0: dependencies: @@ -5262,8 +4897,6 @@ snapshots: defu@6.1.4: {} - delayed-stream@1.0.0: {} - dequal@2.0.3: {} destr@2.0.5: {} @@ -5280,11 +4913,6 @@ snapshots: eastasianwidth@0.2.0: {} - ecc-jsbn@0.1.2: - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - editorconfig@1.0.4: dependencies: '@one-ini/wasm': 0.1.1 @@ -5292,6 +4920,8 @@ snapshots: minimatch: 9.0.1 semver: 7.6.3 + eight-colors@1.3.1: {} + electron-to-chromium@1.5.223: {} emoji-regex@10.5.0: {} @@ -5300,20 +4930,11 @@ snapshots: emoji-regex@9.2.2: {} - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - enhanced-resolve@5.18.3: dependencies: graceful-fs: 4.2.11 tapable: 2.2.3 - enquirer@2.4.1: - dependencies: - ansi-colors: 4.1.3 - strip-ansi: 6.0.1 - entities@4.5.0: {} environment@1.1.0: {} @@ -5363,6 +4984,8 @@ snapshots: '@esbuild/win32-ia32': 0.25.10 '@esbuild/win32-x64': 0.25.10 + escalade@3.1.2: {} + escalade@3.2.0: {} escape-string-regexp@1.0.5: {} @@ -5374,12 +4997,12 @@ snapshots: eslint-compat-utils@0.5.1(eslint@9.36.0(jiti@2.6.0)): dependencies: eslint: 9.36.0(jiti@2.6.0) - semver: 7.7.2 + semver: 7.6.3 eslint-compat-utils@0.6.5(eslint@9.36.0(jiti@2.6.0)): dependencies: eslint: 9.36.0(jiti@2.6.0) - semver: 7.7.2 + semver: 7.6.3 eslint-config-flat-gitignore@2.1.0(eslint@9.36.0(jiti@2.6.0)): dependencies: @@ -5399,7 +5022,7 @@ snapshots: eslint-import-resolver-node@0.3.9: dependencies: - debug: 3.2.7(supports-color@8.1.1) + debug: 3.2.7 is-core-module: 2.13.1 resolve: 1.22.8 transitivePeerDependencies: @@ -5425,11 +5048,6 @@ snapshots: '@es-joy/jsdoccomment': 0.50.2 eslint: 9.36.0(jiti@2.6.0) - eslint-plugin-cypress@5.1.1(eslint@9.36.0(jiti@2.6.0)): - dependencies: - eslint: 9.36.0(jiti@2.6.0) - globals: 16.4.0 - eslint-plugin-es-x@7.8.0(eslint@9.36.0(jiti@2.6.0)): dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0(jiti@2.6.0)) @@ -5441,7 +5059,7 @@ snapshots: dependencies: '@typescript-eslint/types': 8.44.1 comment-parser: 1.4.1 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 eslint: 9.36.0(jiti@2.6.0) eslint-import-context: 0.1.9(unrs-resolver@1.11.1) is-glob: 4.0.3 @@ -5460,7 +5078,7 @@ snapshots: '@es-joy/jsdoccomment': 0.50.2 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint: 9.36.0(jiti@2.6.0) espree: 10.4.0 @@ -5477,7 +5095,7 @@ snapshots: eslint: 9.36.0(jiti@2.6.0) eslint-compat-utils: 0.6.5(eslint@9.36.0(jiti@2.6.0)) eslint-json-compat-utils: 0.2.1(eslint@9.36.0(jiti@2.6.0))(jsonc-eslint-parser@2.4.0) - espree: 10.4.0 + espree: 9.6.1 graphemer: 1.4.0 jsonc-eslint-parser: 2.4.0 natural-compare: 1.4.0 @@ -5495,7 +5113,7 @@ snapshots: globals: 15.15.0 globrex: 0.1.2 ignore: 5.3.2 - semver: 7.7.2 + semver: 7.6.3 ts-declaration-location: 1.0.7(typescript@5.9.2) transitivePeerDependencies: - typescript @@ -5524,18 +5142,18 @@ snapshots: eslint-plugin-regexp@2.10.0(eslint@9.36.0(jiti@2.6.0)): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0(jiti@2.6.0)) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.36.0(jiti@2.6.0)) '@eslint-community/regexpp': 4.12.1 comment-parser: 1.4.1 eslint: 9.36.0(jiti@2.6.0) - jsdoc-type-pratt-parser: 4.1.0 + jsdoc-type-pratt-parser: 4.0.0 refa: 0.12.1 regexp-ast-analysis: 0.7.1 scslre: 0.3.0 eslint-plugin-toml@0.12.0(eslint@9.36.0(jiti@2.6.0)): dependencies: - debug: 4.4.3(supports-color@8.1.1) + debug: 4.3.6 eslint: 9.36.0(jiti@2.6.0) eslint-compat-utils: 0.6.5(eslint@9.36.0(jiti@2.6.0)) lodash: 4.17.21 @@ -5571,12 +5189,12 @@ snapshots: eslint-plugin-vue@10.5.0(@stylistic/eslint-plugin@4.4.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint@9.36.0(jiti@2.6.0))(vue-eslint-parser@10.2.0(eslint@9.36.0(jiti@2.6.0))): dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0(jiti@2.6.0)) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.36.0(jiti@2.6.0)) eslint: 9.36.0(jiti@2.6.0) natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.1 - semver: 7.7.2 + semver: 7.6.3 vue-eslint-parser: 10.2.0(eslint@9.36.0(jiti@2.6.0)) xml-name-validator: 4.0.0 optionalDependencies: @@ -5585,17 +5203,16 @@ snapshots: eslint-plugin-vuejs-accessibility@2.4.1(eslint@9.36.0(jiti@2.6.0)): dependencies: - aria-query: 5.3.2 + aria-query: 5.3.0 emoji-regex: 10.5.0 eslint: 9.36.0(jiti@2.6.0) vue-eslint-parser: 9.4.3(eslint@9.36.0(jiti@2.6.0)) transitivePeerDependencies: - supports-color - optional: true eslint-plugin-yml@1.18.0(eslint@9.36.0(jiti@2.6.0)): dependencies: - debug: 4.4.3(supports-color@8.1.1) + debug: 4.3.6 escape-string-regexp: 4.0.0 eslint: 9.36.0(jiti@2.6.0) eslint-compat-utils: 0.6.5(eslint@9.36.0(jiti@2.6.0)) @@ -5613,7 +5230,6 @@ snapshots: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 - optional: true eslint-scope@8.4.0: dependencies: @@ -5642,7 +5258,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.3.6 escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -5653,7 +5269,7 @@ snapshots: file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - ignore: 5.3.2 + ignore: 5.3.1 imurmurhash: 0.1.4 is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 @@ -5674,8 +5290,8 @@ snapshots: espree@9.6.1: dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) eslint-visitor-keys: 3.4.3 esquery@1.6.0: @@ -5692,50 +5308,18 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.5 esutils@2.0.3: {} eta@4.0.1: {} - eventemitter2@6.4.7: {} - eventemitter3@5.0.1: {} - execa@4.1.0: - dependencies: - cross-spawn: 7.0.3 - get-stream: 5.2.0 - human-signals: 1.1.1 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - executable@4.1.1: - dependencies: - pify: 2.3.0 - expect-type@1.2.2: {} exsolve@1.0.7: {} - extend@3.0.2: {} - - extract-zip@2.0.1(supports-color@8.1.1): - dependencies: - debug: 4.4.3(supports-color@8.1.1) - get-stream: 5.2.0 - yauzl: 2.10.0 - optionalDependencies: - '@types/yauzl': 2.10.3 - transitivePeerDependencies: - - supports-color - - extsprintf@1.3.0: {} - fast-deep-equal@3.1.3: {} fast-glob@3.3.2: @@ -5760,18 +5344,10 @@ snapshots: dependencies: format: 0.2.2 - fd-slicer@1.1.0: - dependencies: - pend: 1.2.0 - fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 - figures@3.2.0: - dependencies: - escape-string-regexp: 1.0.5 - file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -5802,25 +5378,18 @@ snapshots: foreground-child@3.1.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 signal-exit: 4.1.0 - forever-agent@0.6.1: {} - - form-data@2.3.3: + foreground-child@3.3.1: dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 + cross-spawn: 7.0.6 + signal-exit: 4.1.0 format@0.2.2: {} - fs-extra@9.1.0: - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 + fsevents@2.3.2: + optional: true fsevents@2.3.3: optional: true @@ -5829,6 +5398,8 @@ snapshots: functions-have-names@1.2.3: {} + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} get-east-asian-width@1.2.0: {} @@ -5844,22 +5415,10 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.0 - get-stream@5.2.0: - dependencies: - pump: 3.0.0 - get-tsconfig@4.10.1: dependencies: resolve-pkg-maps: 1.0.0 - getos@3.2.1: - dependencies: - async: 3.2.5 - - getpass@0.1.7: - dependencies: - assert-plus: 1.0.0 - giget@2.0.0: dependencies: citty: 0.1.6 @@ -5896,10 +5455,6 @@ snapshots: package-json-from-dist: 1.0.0 path-scurry: 1.11.1 - global-dirs@3.0.1: - dependencies: - ini: 2.0.0 - globals@14.0.0: {} globals@15.15.0: {} @@ -5960,17 +5515,9 @@ snapshots: html-escaper@2.0.2: {} - http-signature@1.3.6: - dependencies: - assert-plus: 1.0.0 - jsprim: 2.0.2 - sshpk: 1.18.0 - http2-client@1.3.5: {} - human-signals@1.1.1: {} - - ieee754@1.2.1: {} + ignore@5.3.1: {} ignore@5.3.2: {} @@ -5983,16 +5530,12 @@ snapshots: imurmurhash@0.1.4: {} - indent-string@4.0.0: {} - indent-string@5.0.0: {} index-to-position@1.2.0: {} ini@1.3.8: {} - ini@2.0.0: {} - insane@2.6.2: dependencies: assignment: 2.0.0 @@ -6030,10 +5573,6 @@ snapshots: is-callable@1.2.7: {} - is-ci@3.0.1: - dependencies: - ci-info: 3.9.0 - is-core-module@2.13.1: dependencies: hasown: 2.0.0 @@ -6055,11 +5594,6 @@ snapshots: dependencies: is-extglob: 2.1.1 - is-installed-globally@0.4.0: - dependencies: - global-dirs: 3.0.1 - is-path-inside: 3.0.3 - is-map@2.0.2: {} is-node-process@1.2.0: {} @@ -6070,8 +5604,6 @@ snapshots: is-number@7.0.0: {} - is-path-inside@3.0.3: {} - is-regex@1.1.4: dependencies: call-bind: 1.0.5 @@ -6083,8 +5615,6 @@ snapshots: dependencies: call-bind: 1.0.5 - is-stream@2.0.1: {} - is-string@1.0.7: dependencies: has-tostringtag: 1.0.0 @@ -6097,10 +5627,6 @@ snapshots: dependencies: which-typed-array: 1.1.13 - is-typedarray@1.0.0: {} - - is-unicode-supported@0.1.0: {} - is-weakmap@2.0.1: {} is-weakset@2.0.2: @@ -6114,10 +5640,18 @@ snapshots: isexe@2.0.0: {} - isstream@0.1.2: {} - istanbul-lib-coverage@3.2.2: {} + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.28.4 + '@babel/parser': 7.28.4 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + istanbul-lib-report@3.0.1: dependencies: istanbul-lib-coverage: 3.2.2 @@ -6127,7 +5661,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -6137,6 +5671,11 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + jackspeak@2.3.6: dependencies: '@isaacs/cliui': 8.0.2 @@ -6166,7 +5705,7 @@ snapshots: dependencies: argparse: 2.0.1 - jsbn@0.1.1: {} + jsdoc-type-pratt-parser@4.0.0: {} jsdoc-type-pratt-parser@4.1.0: {} @@ -6178,38 +5717,21 @@ snapshots: json-schema-traverse@0.4.1: {} - json-schema@0.4.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} - json-stringify-safe@5.0.1: {} + json5@2.2.3: {} jsonc-eslint-parser@2.4.0: dependencies: - acorn: 8.15.0 + acorn: 8.12.1 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - semver: 7.7.2 - - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - jsprim@2.0.2: - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 + semver: 7.6.3 keyv@4.5.4: dependencies: json-buffer: 3.0.1 - lazy-ass@1.6.0: {} - levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -6225,19 +5747,6 @@ snapshots: string-argv: 0.3.2 yaml: 2.8.1 - listr2@3.14.0(enquirer@2.4.1): - dependencies: - cli-truncate: 2.1.0 - colorette: 2.0.20 - log-update: 4.0.0 - p-map: 4.0.0 - rfdc: 1.3.0 - rxjs: 7.8.1 - through: 2.3.8 - wrap-ansi: 7.0.0 - optionalDependencies: - enquirer: 2.4.1 - listr2@9.0.4: dependencies: cli-truncate: 5.1.0 @@ -6261,22 +5770,8 @@ snapshots: lodash.merge@4.6.2: {} - lodash.once@4.1.1: {} - lodash@4.17.21: {} - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - - log-update@4.0.0: - dependencies: - ansi-escapes: 4.3.2 - cli-cursor: 3.1.0 - slice-ansi: 4.0.0 - wrap-ansi: 6.2.0 - log-update@6.1.0: dependencies: ansi-escapes: 7.0.0 @@ -6297,8 +5792,14 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + lz-string@1.5.0: {} + lz-utils@2.1.0: {} + magic-string@0.30.19: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -6311,7 +5812,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.7.2 + semver: 7.6.3 markdown-table@3.0.4: {} @@ -6430,8 +5931,6 @@ snapshots: dependencies: '@types/mdast': 4.0.4 - merge-stream@2.0.0: {} - merge2@1.4.1: {} micromark-core-commonmark@2.0.3: @@ -6613,7 +6112,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.3.6 decode-named-character-reference: 1.2.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -6642,14 +6141,6 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mimic-fn@2.1.0: {} - mimic-function@5.0.1: {} min-indent@1.0.1: {} @@ -6666,8 +6157,6 @@ snapshots: dependencies: brace-expansion: 2.0.1 - minimist@1.2.8: {} - minipass@7.0.4: {} minipass@7.1.2: {} @@ -6681,15 +6170,32 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.1 + monocart-coverage-reports@2.12.9: + dependencies: + acorn: 8.15.0 + acorn-loose: 8.5.2 + acorn-walk: 8.3.4 + commander: 14.0.1 + console-grid: 2.2.3 + eight-colors: 1.3.1 + foreground-child: 3.3.1 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + lz-utils: 2.1.0 + monocart-locator: 1.0.2 + + monocart-locator@1.0.2: {} + ms@2.1.2: {} ms@2.1.3: {} - msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2): + msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2): dependencies: '@bundled-es-modules/cookie': 2.0.1 '@bundled-es-modules/statuses': 1.0.1 - '@inquirer/confirm': 5.1.18(@types/node@20.19.17) + '@inquirer/confirm': 5.1.18(@types/node@24.5.2) '@mswjs/interceptors': 0.39.6 '@open-draft/deferred-promise': 2.2.0 '@types/cookie': 0.6.0 @@ -6755,10 +6261,6 @@ snapshots: semver: 7.7.2 validate-npm-package-license: 3.0.4 - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - nth-check@2.1.1: dependencies: boolbase: 1.0.0 @@ -6820,14 +6322,6 @@ snapshots: ohash@2.0.11: {} - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - onetime@7.0.0: dependencies: mimic-function: 5.0.1 @@ -6843,8 +6337,6 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - ospath@1.2.2: {} - outvariant@1.4.3: {} p-limit@3.1.0: @@ -6855,10 +6347,6 @@ snapshots: dependencies: p-limit: 3.1.0 - p-map@4.0.0: - dependencies: - aggregate-error: 3.1.0 - package-json-from-dist@1.0.0: {} package-manager-detector@1.3.0: {} @@ -6906,14 +6394,10 @@ snapshots: pathval@2.0.0: {} - pend@1.2.0: {} - perfect-debounce@1.0.0: {} perfect-debounce@2.0.0: {} - performance-now@2.1.0: {} - picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -6924,8 +6408,6 @@ snapshots: pidtree@0.6.0: {} - pify@2.3.0: {} - pinia@3.0.3(typescript@5.9.2)(vue@3.5.22(typescript@5.9.2)): dependencies: '@vue/devtools-api': 7.7.7 @@ -6945,6 +6427,14 @@ snapshots: exsolve: 1.0.7 pathe: 2.0.3 + playwright-core@1.55.1: {} + + playwright@1.55.1: + dependencies: + playwright-core: 1.55.1 + optionalDependencies: + fsevents: 2.3.2 + pluralize@8.0.0: {} pnpm-workspace-yaml@0.3.1: @@ -6964,37 +6454,18 @@ snapshots: prelude-ls@1.2.1: {} - pretty-bytes@5.6.0: {} - pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 ansi-styles: 5.2.0 react-is: 17.0.2 - process@0.11.10: {} - proto-list@1.2.4: {} - proxy-from-env@1.0.0: {} - - psl@1.9.0: {} - - pump@3.0.0: - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - punycode@2.3.1: {} - qs@6.10.4: - dependencies: - side-channel: 1.0.4 - quansync@0.2.11: {} - querystringify@2.2.0: {} - queue-microtask@1.2.3: {} rc9@2.1.2: @@ -7050,14 +6521,8 @@ snapshots: dependencies: jsesc: 3.0.2 - request-progress@3.0.0: - dependencies: - throttleit: 1.0.1 - require-directory@2.1.1: {} - requires-port@1.0.0: {} - resolve-from@4.0.0: {} resolve-pkg-maps@1.0.0: {} @@ -7069,11 +6534,6 @@ snapshots: supports-preserve-symlinks-flag: 1.0.0 optional: true - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - restore-cursor@5.1.0: dependencies: onetime: 7.0.0 @@ -7083,8 +6543,6 @@ snapshots: reusify@1.0.4: {} - rfdc@1.3.0: {} - rfdc@1.4.1: {} rollup-plugin-analyzer@4.0.0: {} @@ -7121,24 +6579,14 @@ snapshots: dependencies: queue-microtask: 1.2.3 - rxjs@7.8.1: - dependencies: - tslib: 2.6.2 - - rxjs@7.8.2: - dependencies: - tslib: 2.6.2 - - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} - scslre@0.3.0: dependencies: '@eslint-community/regexpp': 4.12.1 refa: 0.12.1 regexp-ast-analysis: 0.7.1 + semver@6.3.1: {} + semver@7.6.3: {} semver@7.7.2: {} @@ -7162,8 +6610,6 @@ snapshots: shebang-regex@3.0.0: {} - shell-quote@1.8.3: {} - should-equal@2.0.0: dependencies: should-type: 1.4.0 @@ -7198,26 +6644,12 @@ snapshots: siginfo@2.0.0: {} - signal-exit@3.0.7: {} - signal-exit@4.1.0: {} simple-git-hooks@2.13.1: {} sisteransi@1.0.5: {} - slice-ansi@3.0.0: - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - - slice-ansi@4.0.0: - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - slice-ansi@7.1.0: dependencies: ansi-styles: 6.2.1 @@ -7246,18 +6678,6 @@ snapshots: speakingurl@14.0.1: {} - sshpk@1.18.0: - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - stable-hash-x@0.2.0: {} stackback@0.0.2: {} @@ -7305,8 +6725,6 @@ snapshots: dependencies: ansi-regex: 6.0.1 - strip-final-newline@2.0.0: {} - strip-indent@4.0.0: dependencies: min-indent: 1.0.1 @@ -7329,10 +6747,6 @@ snapshots: dependencies: has-flag: 4.0.0 - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: optional: true @@ -7389,10 +6803,6 @@ snapshots: glob: 10.4.5 minimatch: 9.0.5 - throttleit@1.0.1: {} - - through@2.3.8: {} - tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -7416,8 +6826,6 @@ snapshots: dependencies: tldts-core: 7.0.16 - tmp@0.2.3: {} - to-fast-properties@2.0.0: {} to-regex-range@5.0.1: @@ -7428,21 +6836,12 @@ snapshots: dependencies: eslint-visitor-keys: 3.4.3 - tough-cookie@4.1.4: - dependencies: - psl: 1.9.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 - tough-cookie@6.0.0: dependencies: tldts: 7.0.16 tr46@0.0.3: {} - tree-kill@1.2.2: {} - ts-api-utils@2.1.0(typescript@5.9.2): dependencies: typescript: 5.9.2 @@ -7454,18 +6853,17 @@ snapshots: tslib@2.6.2: {} - tunnel-agent@0.6.0: + tsx@4.20.6: dependencies: - safe-buffer: 5.2.1 - - tweetnacl@0.14.5: {} + esbuild: 0.25.10 + get-tsconfig: 4.10.1 + optionalDependencies: + fsevents: 2.3.3 type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - type-fest@0.21.3: {} - type-fest@4.24.0: {} type-fest@4.41.0: {} @@ -7474,11 +6872,10 @@ snapshots: ufo@1.6.1: {} - undici-types@6.13.0: - optional: true - undici-types@6.21.0: {} + undici-types@7.12.0: {} + unicorn-magic@0.1.0: {} unist-util-is@6.0.0: @@ -7500,10 +6897,6 @@ snapshots: unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - universalify@0.2.0: {} - - universalify@2.0.1: {} - unrs-resolver@1.11.1: dependencies: napi-postinstall: 0.3.3 @@ -7530,8 +6923,6 @@ snapshots: until-async@3.0.2: {} - untildify@4.0.0: {} - update-browserslist-db@1.1.3(browserslist@4.26.2): dependencies: browserslist: 4.26.2 @@ -7542,33 +6933,20 @@ snapshots: dependencies: punycode: 2.3.1 - url-parse@1.5.10: - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - util-deprecate@1.0.2: {} - uuid@8.3.2: {} - validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - verror@1.10.0: - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - - vite-node@3.2.4(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1): + vite-node@3.2.4(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: cac: 6.7.14 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.7(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -7583,7 +6961,7 @@ snapshots: - tsx - yaml - vite@7.1.7(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1): + vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) @@ -7592,12 +6970,13 @@ snapshots: rollup: 4.52.2 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 20.19.17 + '@types/node': 24.5.2 fsevents: 2.3.3 jiti: 2.6.0 + tsx: 4.20.6 yaml: 2.8.1 - vitest-dom@0.1.1(vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1)): + vitest-dom@0.1.1(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1)): dependencies: aria-query: 5.3.0 chalk: 5.3.0 @@ -7605,36 +6984,46 @@ snapshots: dom-accessibility-api: 0.6.3 lodash-es: 4.17.21 redent: 4.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1) + + vitest-monocart-coverage@3.0.2(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1)): + dependencies: + '@vitest/coverage-istanbul': 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1)) + '@vitest/coverage-v8': 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1)) + monocart-coverage-reports: 2.12.9 + transitivePeerDependencies: + - '@vitest/browser' + - supports-color + - vitest - vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.17)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.2)(happy-dom@18.0.1)(jiti@2.6.0)(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(tsx@4.20.6)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(msw@2.11.3(@types/node@20.19.17)(typescript@5.9.2))(vite@7.1.7(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(msw@2.11.3(@types/node@24.5.2)(typescript@5.9.2))(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 chai: 5.3.3 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 expect-type: 1.2.2 magic-string: 0.30.19 pathe: 2.0.3 - picomatch: 4.0.3 + picomatch: 4.0.2 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.7(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@20.19.17)(jiti@2.6.0)(yaml@2.8.1) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 20.19.17 + '@types/node': 24.5.2 happy-dom: 18.0.1 transitivePeerDependencies: - jiti @@ -7656,19 +7045,19 @@ snapshots: vue-eslint-parser@10.2.0(eslint@9.36.0(jiti@2.6.0)): dependencies: - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 eslint: 9.36.0(jiti@2.6.0) eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 esquery: 1.6.0 - semver: 7.7.2 + semver: 7.6.3 transitivePeerDependencies: - supports-color vue-eslint-parser@9.4.3(eslint@9.36.0(jiti@2.6.0)): dependencies: - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 eslint: 9.36.0(jiti@2.6.0) eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 @@ -7678,7 +7067,6 @@ snapshots: semver: 7.7.2 transitivePeerDependencies: - supports-color - optional: true vue-router@4.5.1(vue@3.5.22(typescript@5.9.2)): dependencies: @@ -7766,12 +7154,12 @@ snapshots: string-width: 7.0.0 strip-ansi: 7.1.0 - wrappy@1.0.2: {} - xml-name-validator@4.0.0: {} y18n@5.0.8: {} + yallist@3.1.1: {} + yaml-eslint-parser@1.3.0: dependencies: eslint-visitor-keys: 3.4.3 @@ -7788,18 +7176,13 @@ snapshots: yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.2.0 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - yauzl@2.10.0: - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - yocto-queue@0.1.0: {} yoctocolors-cjs@2.1.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..eb37b315 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,7 @@ +ignoredBuiltDependencies: + - msw + - unrs-resolver + +onlyBuiltDependencies: + - esbuild + - simple-git-hooks diff --git a/scripts/merge-coverage.ts b/scripts/merge-coverage.ts new file mode 100644 index 00000000..3ec3c5d3 --- /dev/null +++ b/scripts/merge-coverage.ts @@ -0,0 +1,38 @@ +/* eslint-disable unicorn/prefer-top-level-await */ + +import path from 'node:path' +import type { CoverageReportOptions } from 'monocart-coverage-reports' +import { CoverageReport } from 'monocart-coverage-reports' +import baseConfig from '../config/mcr.base.config' + +const inputDir = [ + path.join(import.meta.dirname, '../coverage/unit/raw'), + path.join(import.meta.dirname, '../coverage/e2e/raw'), +] + +const coverageOptions: CoverageReportOptions = { + ...baseConfig, + + name: 'Merged Coverage Report', + inputDir, + outputDir: './coverage/merged', + reports: [ + 'v8', + 'v8-json', + 'console-details', + ], + + // onEnd: () => { + // remove the raw files if it useless + // inputDir.forEach((p) => { + // fs.rmSync(p, { + // recursive: true, + // force: true + // }); + // }); + // }, +} + +void new CoverageReport(coverageOptions).generate().then(() => { + console.log('Merged coverage report generated successfully') +}) diff --git a/src/components/AppPagination.vue b/src/components/AppPagination.vue index c4e22423..3f20c6d4 100644 --- a/src/components/AppPagination.vue +++ b/src/components/AppPagination.vue @@ -1,5 +1,5 @@