diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 0000000..0704363 --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,37 @@ +name: Playwright Tests +on: + push: + branches: [ main, develop, feature/e2e ] + pull_request: + branches: [ main, develop, feature/e2e ] +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install pnpm + uses: pnpm/action-setup@v4.0.0 + + - name: Install dependencies + run: pnpm install + + - name: Build vitepress-openapi + run: pnpm build + + - name: Install Playwright Browsers + run: pnpm exec playwright install --with-deps + + - name: Run Playwright tests + run: pnpm exec playwright test + + - uses: actions/upload-artifact@v4 + if: always() + with: + name: playwright-report + path: | + playwright-report/ + test-results/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index fd80a1f..ab6e3f1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,9 @@ docs/.vitepress/cache docs/.vitepress/.temp types .idea + +# Playwright +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/e2e/dev/.gitignore b/e2e/dev/.gitignore new file mode 100644 index 0000000..131cc58 --- /dev/null +++ b/e2e/dev/.gitignore @@ -0,0 +1,6 @@ +node_modules +dist +.temp +cache +.idea +.vscode diff --git a/e2e/dev/docs/.vitepress/config.ts b/e2e/dev/docs/.vitepress/config.ts new file mode 100644 index 0000000..bdce816 --- /dev/null +++ b/e2e/dev/docs/.vitepress/config.ts @@ -0,0 +1,67 @@ +import { fileURLToPath } from 'node:url' +import { defineConfig } from 'vitepress' +import { useSidebar } from 'vitepress-openapi' +import spec from '../../public/openapi.json' + +const sidebar = useSidebar({ + spec, + // Optionally, you can specify a link prefix for all generated sidebar items. + linkPrefix: '/operations/', +}) + +// refer https://vitepress.dev/reference/site-config for details +export default defineConfig({ + lang: 'en-US', + title: 'VitePress OpenAPI', + description: 'Generate documentation from OpenAPI specifications.', + + themeConfig: { + nav: [{ text: 'API Reference', link: '/introduction' }], + + sidebar: [ + { + text: 'By Tags', + items: [ + { + text: 'Introduction', + link: '/introduction', + }, + ...sidebar.itemsByTags(), + ], + }, + { + text: 'By Operations', + items: [ + ...sidebar.generateSidebarGroups(), + ], + }, + { + text: 'By Paths', + items: [ + ...sidebar.itemsByPaths(), + ], + }, + { + text: 'One Page', + items: [ + { text: 'One Page', link: '/one-page' }, + { text: 'Without Sidebar', link: '/without-sidebar' }, + ], + }, + ], + }, + + vite: { + resolve: { + alias: { + ...(process.env.NODE_ENV === 'production' + ? {} + : { + 'vitepress-openapi/client': fileURLToPath(new URL('../../../../src/client', import.meta.url)), + 'vitepress-openapi/dist/style.css': fileURLToPath(new URL('../../../../dist/style.css', import.meta.url)), + 'vitepress-openapi': fileURLToPath(new URL('../../../../src/index', import.meta.url)), + }), + }, + }, + }, +}) diff --git a/e2e/dev/docs/.vitepress/theme/index.ts b/e2e/dev/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..89c2ed9 --- /dev/null +++ b/e2e/dev/docs/.vitepress/theme/index.ts @@ -0,0 +1,18 @@ +import DefaultTheme from 'vitepress/theme'; +import type { Theme } from 'vitepress'; + +import { theme, useOpenapi } from 'vitepress-openapi/client'; +import 'vitepress-openapi/dist/style.css'; +import spec from '../../../public/openapi.json' + +export default { + ...DefaultTheme, + async enhanceApp({ app, router, siteData }) { + const openapi = useOpenapi({ + spec, + config: {}, + }); + + theme.enhanceApp({ app, openapi }); + }, +} satisfies Theme; diff --git a/e2e/dev/docs/index.md b/e2e/dev/docs/index.md new file mode 100644 index 0000000..49a15d9 --- /dev/null +++ b/e2e/dev/docs/index.md @@ -0,0 +1,14 @@ +--- +layout: home + +hero: + name: "VitePress OpenAPI" + tagline: "Generate documentation from OpenAPI specifications." + actions: + - theme: brand + text: API Reference + link: /introduction + - theme: alt + text: Documentation + link: https://vitepress-openapi.vercel.app/ +--- diff --git a/e2e/dev/docs/introduction.md b/e2e/dev/docs/introduction.md new file mode 100644 index 0000000..6794c17 --- /dev/null +++ b/e2e/dev/docs/introduction.md @@ -0,0 +1,7 @@ +--- +title: vitepress-openapi +--- + + + + diff --git a/e2e/dev/docs/one-page.md b/e2e/dev/docs/one-page.md new file mode 100644 index 0000000..2dbfac0 --- /dev/null +++ b/e2e/dev/docs/one-page.md @@ -0,0 +1,12 @@ +--- +aside: false +title: vitepress-openapi +--- + + + + diff --git a/e2e/dev/docs/operations/[operationId].md b/e2e/dev/docs/operations/[operationId].md new file mode 100644 index 0000000..428b256 --- /dev/null +++ b/e2e/dev/docs/operations/[operationId].md @@ -0,0 +1,17 @@ +--- +aside: false +outline: false +title: vitepress-openapi +--- + + + + diff --git a/e2e/dev/docs/operations/[operationId].paths.js b/e2e/dev/docs/operations/[operationId].paths.js new file mode 100644 index 0000000..7bdf784 --- /dev/null +++ b/e2e/dev/docs/operations/[operationId].paths.js @@ -0,0 +1,17 @@ +import { usePaths } from 'vitepress-openapi' +import spec from '../../public/openapi.json' + +export default { + paths() { + return usePaths({ spec }) + .getPathsByVerbs() + .map(({ operationId, summary }) => { + return { + params: { + operationId, + pageTitle: `${summary} - vitepress-openapi`, + }, + } + }) + }, +} diff --git a/e2e/dev/docs/tags/[tag].md b/e2e/dev/docs/tags/[tag].md new file mode 100644 index 0000000..d8f6641 --- /dev/null +++ b/e2e/dev/docs/tags/[tag].md @@ -0,0 +1,17 @@ +--- +aside: false +outline: false +title: vitepress-openapi +--- + + + + diff --git a/e2e/dev/docs/tags/[tag].paths.js b/e2e/dev/docs/tags/[tag].paths.js new file mode 100644 index 0000000..6c4e6b2 --- /dev/null +++ b/e2e/dev/docs/tags/[tag].paths.js @@ -0,0 +1,17 @@ +import { usePaths } from 'vitepress-openapi' +import spec from '../../public/openapi.json' + +export default { + paths() { + return usePaths({ spec }) + .getTags() + .map(({ name }) => { + return { + params: { + tag: name, + pageTitle: `${name} - vitepress-openapi`, + }, + } + }) + }, +} diff --git a/e2e/dev/docs/without-sidebar.md b/e2e/dev/docs/without-sidebar.md new file mode 100644 index 0000000..b42bc8e --- /dev/null +++ b/e2e/dev/docs/without-sidebar.md @@ -0,0 +1,14 @@ +--- +sidebar: false +aside: true +outline: [1, 2] +title: vitepress-openapi +--- + + + + diff --git a/e2e/dev/package.json b/e2e/dev/package.json new file mode 100644 index 0000000..ecedc30 --- /dev/null +++ b/e2e/dev/package.json @@ -0,0 +1,14 @@ +{ + "private": true, + "type": "module", + "scripts": { + "dev": "vitepress dev docs", + "build": "vitepress build docs", + "preview": "vitepress preview docs", + "start": "vitepress dev docs" + }, + "devDependencies": { + "vitepress": "^1.6.3", + "vitepress-openapi": "workspace:*" + } +} diff --git a/e2e/dev/public/openapi.json b/e2e/dev/public/openapi.json new file mode 100644 index 0000000..2cb8cd4 --- /dev/null +++ b/e2e/dev/public/openapi.json @@ -0,0 +1,732 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Argentine Rock Legends", + "description": "The Argentine Rock Legends is an example OpenAPI specification to test OpenAPI tools and libraries. Get all the data for [all artists](#getAllArtists).\n\n>Inspired by [Scalar Galaxy](https://galaxy.scalar.com/)\n\n## Resources\n\n* https://github.com/enzonotario/vitepress-openapi\n* https://github.com/OAI/OpenAPI-Specification\n\n## Markdown Support\n\nAll descriptions *can* contain ~~tons of text~~ **Markdown**. [If GitHub supports the syntax](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax), chances are we’re supporting it, too. You can even create [internal links to reference endpoints](#createArtist).\n\n
\n Examples\n\n **Blockquotes**\n\n > I love Argentine Rock. <3\n\n **Tables**\n\n | Feature | Availability |\n | ---------------- | ------------ |\n | Markdown Support | ✓ |\n\n **Accordion**\n\n ```html\n
\n Using Details Tags\n

HTML Example

\n
\n ```\n\n **Images**\n\n Yes, there’s support for images, too!\n\n ![Placeholder image](https://images.placeholders.dev/?width=1280&height=720)\n\n
\n", + "version": "1.0.0", + "contact": { + "name": "Enzo Notario", + "url": "https://enzonotario.me", + "email": "hi@enzonotario.me" + } + }, + "servers": [ + { + "url": "https://stoplight.io/mocks/enzonotario/argentine-rock/122547792", + "description": "Mock Server" + } + ], + "security": [ + { + "bearerAuth": [] + }, + { + "apiKeyHeader": [] + } + ], + "tags": [ + { + "name": "Authentication", + "description": "Some endpoints are public, but some require authentication. We provide all the required endpoints to create an account and authorize yourself." + }, + { + "name": "Artists", + "description": "Everything about Argentine Rock artists" + } + ], + "paths": { + "/api/v1/artists": { + "get": { + "tags": [ + "Artists" + ], + "summary": "Get all artists", + "description": "Get a list of all legendary Argentine Rock artists and explore their contributions to the music scene.", + "operationId": "getAllArtists", + "security": [ + {} + ], + "parameters": [ + { + "$ref": "#/components/parameters/limit" + }, + { + "$ref": "#/components/parameters/offset" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Artist" + } + } + } + }, + { + "$ref": "#/components/schemas/PaginatedResource" + } + ] + } + } + } + } + } + }, + "post": { + "tags": [ + "Artists" + ], + "summary": "Add a new artist", + "description": "Add a new legendary Argentine Rock artist. Make sure they truly deserve the title!", + "operationId": "createArtist", + "requestBody": { + "description": "Artist data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Artist" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Artist" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/artists/{artistId}": { + "get": { + "tags": [ + "Artists" + ], + "summary": "Get an artist", + "description": "Learn more about a specific Argentine Rock artist and their legacy.", + "operationId": "getArtist", + "security": [ + {} + ], + "parameters": [ + { + "$ref": "#/components/parameters/artistId" + } + ], + "responses": { + "200": { + "description": "Artist Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Artist" + } + } + } + }, + "404": { + "description": "Artist Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "put": { + "tags": [ + "Artists" + ], + "summary": "Update an artist", + "description": "Update the information of a legendary Argentine Rock artist. Make sure to provide accurate data.", + "operationId": "updateArtist", + "parameters": [ + { + "$ref": "#/components/parameters/artistId" + } + ], + "requestBody": { + "description": "Artist data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Artist" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Artist" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "delete": { + "tags": [ + "Artists" + ], + "summary": "Delete an artist", + "operationId": "deleteArtist", + "description": "This endpoint was used to delete artists. Unfortunately, that caused a lot of controversy. So, this endpoint is now deprecated and should not be used anymore.", + "deprecated": true, + "parameters": [ + { + "$ref": "#/components/parameters/artistId" + } + ], + "responses": { + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/artists/{artistId}/albums": { + "get": { + "tags": [ + "Artists" + ], + "summary": "Get all albums", + "description": "Get a list of all albums from a legendary Argentine Rock artist.", + "operationId": "getAllAlbums", + "security": [ + {} + ], + "parameters": [ + { + "$ref": "#/components/parameters/artistId" + }, + { + "$ref": "#/components/parameters/limit" + }, + { + "$ref": "#/components/parameters/offset" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Album" + } + } + } + }, + { + "$ref": "#/components/schemas/PaginatedResource" + } + ] + } + } + } + } + } + }, + "post": { + "tags": [ + "Artists" + ], + "summary": "Add a new album", + "description": "Add a new album to a legendary Argentine Rock artist. Make sure it’s a masterpiece!", + "operationId": "createAlbum", + "parameters": [ + { + "$ref": "#/components/parameters/artistId" + } + ], + "requestBody": { + "description": "Album data", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Album" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Album" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/api/v1/user/signup": { + "post": { + "tags": [ + "Authentication" + ], + "summary": "Create a user", + "description": "Create a user account to access exclusive content about Argentine Rock legends.", + "operationId": "createUser", + "security": [ + {} + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewUser" + }, + "examples": { + "Carlos": { + "value": { + "name": "Carlos", + "email": "carlos@rock-legends.com", + "password": "i-love-rock" + } + }, + "Maria": { + "value": { + "name": "Maria", + "email": "maria@rock-legends.com", + "password": "rock-n-roll" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + } + }, + "components": { + "securitySchemes": { + "bearerAuth": { + "type": "http", + "scheme": "bearer" + }, + "apiKeyHeader": { + "type": "apiKey", + "in": "header", + "name": "X-API-Key" + } + }, + "parameters": { + "artistId": { + "name": "artistId", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int64", + "examples": [ + 1 + ] + } + }, + "limit": { + "name": "limit", + "in": "query", + "description": "The number of items to return", + "required": false, + "schema": { + "type": "integer", + "format": "int64", + "default": 10 + } + }, + "offset": { + "name": "offset", + "in": "query", + "description": "The number of items to skip before starting to collect the result set", + "required": false, + "schema": { + "type": "integer", + "format": "int64", + "default": 0 + } + } + }, + "responses": { + "BadRequest": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "Forbidden": { + "description": "Forbidden", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "NotFound": { + "description": "NotFound", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "schemas": { + "NewUser": { + "type": "object", + "required": [ + "name", + "email", + "password" + ], + "properties": { + "name": { + "type": "string", + "examples": [ + "Carlos", + "Maria" + ] + }, + "email": { + "type": "string", + "format": "email", + "examples": [ + "carlos@rock-legends.com", + "maria@rock-legends.com" + ] + }, + "password": { + "type": "string", + "minLength": 8, + "examples": [ + "i-love-rock", + "rock-n-roll" + ] + } + } + }, + "User": { + "type": "object", + "required": [ + "id", + "name", + "email" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "examples": [ + 1 + ] + }, + "name": { + "type": "string", + "examples": [ + "Carlos" + ] + }, + "email": { + "type": "string", + "format": "email", + "examples": [ + "carlos@rock-legends.com" + ] + } + } + }, + "Artist": { + "type": "object", + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "examples": [ + 1 + ], + "x-variable": "artistId" + }, + "name": { + "type": "string", + "examples": [ + "Charly García" + ] + }, + "description": { + "type": [ + "string", + "null" + ], + "examples": [ + "One of the most influential rock musicians in Argentine history." + ] + }, + "image": { + "type": "string", + "nullable": true, + "examples": [ + "https://cdn.rock-legends.com/photos/charly.jpg" + ] + }, + "band": { + "type": "string", + "examples": [ + "Sui Generis" + ] + } + } + }, + "Album": { + "type": "object", + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "examples": [ + 1 + ] + }, + "name": { + "type": "string", + "examples": [ + "La Máquina de Hacer Pájaros" + ] + }, + "year": { + "type": "integer", + "format": "int64", + "examples": [ + 1976 + ] + }, + "image": { + "type": "string", + "nullable": true, + "examples": [ + "https://cdn.rock-legends.com/photos/la-maquina.jpg" + ] + } + } + }, + "PaginatedResource": { + "type": "object", + "properties": { + "meta": { + "type": "object", + "properties": { + "limit": { + "type": "integer", + "format": "int64", + "examples": [ + 10 + ] + }, + "offset": { + "type": "integer", + "format": "int64", + "examples": [ + 0 + ] + }, + "total": { + "type": "integer", + "format": "int64", + "examples": [ + 100 + ] + }, + "next": { + "type": [ + "string", + "null" + ], + "examples": [ + "/artists?limit=10&offset=10" + ] + } + } + } + } + }, + "Error": { + "type": "object", + "description": "RFC 7807 (https://datatracker.ietf.org/doc/html/rfc7807)", + "properties": { + "type": { + "type": "string", + "examples": [ + "https://example.com/errors/generic-error" + ] + }, + "title": { + "type": "string", + "examples": [ + "Something went wrong here." + ] + }, + "status": { + "type": "integer", + "format": "int64", + "examples": [ + 403 + ] + }, + "detail": { + "type": "string", + "examples": [ + "Unfortunately, we can’t provide further information." + ] + } + } + } + } + } +} diff --git a/e2e/home.spec.ts b/e2e/home.spec.ts new file mode 100644 index 0000000..cbad247 --- /dev/null +++ b/e2e/home.spec.ts @@ -0,0 +1,10 @@ +import { expect, test } from '@playwright/test' + +test('home', async ({ page }) => { + await page.goto('/') + + await expect(page).toHaveTitle(/VitePress OpenAPI/) + await expect(page).toHaveScreenshot({ + fullPage: true, + }) +}) diff --git a/e2e/home.spec.ts-snapshots/home-1-chromium-linux.png b/e2e/home.spec.ts-snapshots/home-1-chromium-linux.png new file mode 100644 index 0000000..39dd2c7 Binary files /dev/null and b/e2e/home.spec.ts-snapshots/home-1-chromium-linux.png differ diff --git a/e2e/home.spec.ts-snapshots/home-1-firefox-linux.png b/e2e/home.spec.ts-snapshots/home-1-firefox-linux.png new file mode 100644 index 0000000..200b871 Binary files /dev/null and b/e2e/home.spec.ts-snapshots/home-1-firefox-linux.png differ diff --git a/e2e/one-page.spec.ts b/e2e/one-page.spec.ts new file mode 100644 index 0000000..98f9579 --- /dev/null +++ b/e2e/one-page.spec.ts @@ -0,0 +1,9 @@ +import { expect, test } from '@playwright/test' + +test('one-page', async ({ page }) => { + await page.goto('/one-page') + + await expect(page).toHaveScreenshot({ + fullPage: true, + }) +}) diff --git a/e2e/one-page.spec.ts-snapshots/one-page-1-chromium-linux.png b/e2e/one-page.spec.ts-snapshots/one-page-1-chromium-linux.png new file mode 100644 index 0000000..c42ec80 Binary files /dev/null and b/e2e/one-page.spec.ts-snapshots/one-page-1-chromium-linux.png differ diff --git a/e2e/one-page.spec.ts-snapshots/one-page-1-firefox-linux.png b/e2e/one-page.spec.ts-snapshots/one-page-1-firefox-linux.png new file mode 100644 index 0000000..011855d Binary files /dev/null and b/e2e/one-page.spec.ts-snapshots/one-page-1-firefox-linux.png differ diff --git a/package.json b/package.json index aa23d70..16b15c9 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,8 @@ "docs:build": "pnpm run build && cd docs && pnpm run build", "test": "vitest", "test:run": "vitest --run", - "typecheck": "vue-tsc --noEmit" + "typecheck": "vue-tsc --noEmit", + "e2e:dev": "cd e2e/dev && pnpm run dev" }, "peerDependencies": { "vitepress": ">=1.0.0", @@ -61,6 +62,7 @@ }, "devDependencies": { "@antfu/eslint-config": "^4.1.0", + "@playwright/test": "^1.50.0", "@scalar/openapi-types": "^0.1.6", "@sindresorhus/slugify": "^2.2.1", "@trojs/openapi-dereference": "^1.0.1", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..1788b01 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,72 @@ +import { defineConfig, devices } from '@playwright/test' + +const port = 4173 + +const url = `http://localhost:${port}` + +export default defineConfig({ + testDir: './e2e', + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* 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: url, + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + + // { + // name: 'webkit', + // use: { ...devices['Desktop Safari'] }, + // }, + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + // { + // name: 'Google Chrome', + // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: `cd e2e/dev && vitepress dev docs --port ${port}`, + port, + reuseExistingServer: !process.env.CI, + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a728b43..aaee78d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,7 +25,7 @@ importers: version: 0.474.0(vue@3.5.13(typescript@5.7.3)) radix-vue: specifier: ^1.9.12 - version: 1.9.12(vue@3.5.13(typescript@5.7.3)) + version: 1.9.13(vue@3.5.13(typescript@5.7.3)) tailwind-merge: specifier: ^2.6.0 version: 2.6.0 @@ -35,7 +35,10 @@ importers: devDependencies: '@antfu/eslint-config': specifier: ^4.1.0 - version: 4.1.0(@typescript-eslint/utils@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(@vue/compiler-sfc@3.5.13)(eslint-plugin-format@1.0.1(eslint@9.19.0(jiti@1.21.7)))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0)) + version: 4.1.0(@typescript-eslint/utils@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(@vue/compiler-sfc@3.5.13)(eslint-plugin-format@1.0.1(eslint@9.19.0(jiti@1.21.7)))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0)) + '@playwright/test': + specifier: ^1.50.0 + version: 1.50.0 '@scalar/openapi-types': specifier: ^0.1.6 version: 0.1.6 @@ -47,10 +50,10 @@ importers: version: 1.0.1 '@types/node': specifier: ^22.10.10 - version: 22.10.10 + version: 22.12.0 '@vitejs/plugin-vue': specifier: ^5.2.1 - version: 5.2.1(vite@6.0.11(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3)) + version: 5.2.1(vite@6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3)) allof-merge: specifier: ^0.6.6 version: 0.6.6 @@ -104,13 +107,13 @@ importers: version: 5.7.3 vite: specifier: ^6.0.11 - version: 6.0.11(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0) + version: 6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0) vitepress: specifier: ^1.6.3 - version: 1.6.3(@algolia/client-search@5.20.0)(@types/node@22.10.10)(postcss@8.5.1)(search-insights@2.17.3)(typescript@5.7.3) + version: 1.6.3(@algolia/client-search@5.20.0)(@types/node@22.12.0)(postcss@8.5.1)(search-insights@2.17.3)(typescript@5.7.3) vitest: specifier: ^3.0.4 - version: 3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0) + version: 3.0.4(@types/debug@4.1.12)(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0) vue: specifier: ^3.5.13 version: 3.5.13(typescript@5.7.3) @@ -146,11 +149,20 @@ importers: version: 3.4.17 vitepress: specifier: ^1.6.3 - version: 1.6.3(@algolia/client-search@5.20.0)(@types/node@22.10.10)(postcss@8.5.1)(search-insights@2.17.3)(typescript@5.7.3) + version: 1.6.3(@algolia/client-search@5.20.0)(@types/node@22.12.0)(postcss@8.5.1)(search-insights@2.17.3)(typescript@5.7.3) vitepress-openapi: specifier: workspace:* version: link:.. + e2e/dev: + devDependencies: + vitepress: + specifier: ^1.6.3 + version: 1.6.3(@algolia/client-search@5.20.0)(@types/node@22.12.0)(postcss@8.5.1)(search-insights@2.17.3)(typescript@5.7.3) + vitepress-openapi: + specifier: workspace:* + version: link:../.. + packages: '@algolia/autocomplete-core@1.17.7': @@ -761,8 +773,8 @@ packages: resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} engines: {node: '>=18.18'} - '@iconify-json/simple-icons@1.2.21': - resolution: {integrity: sha512-aqbIuVshMZ2fNEhm25//9DoKudboXF3CpoEQJJlHl9gVSVNOTr4cgaCIZvgSEYmys2HHEfmhcpoZIhoEFZS8SQ==} + '@iconify-json/simple-icons@1.2.22': + resolution: {integrity: sha512-0UzThRMwHuOJfgpp+tyV/y2uEBLjFVrxC4igv9iWjSEQEBK4tNjWZNTRCBCYyv/FwWVYyKAsA8tZQ8vUYzvFnw==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -863,6 +875,11 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@playwright/test@1.50.0': + resolution: {integrity: sha512-ZGNXbt+d65EGjBORQHuYKj+XhCewlwpnSd/EDuLPZGSiEWmgOJB5RmMCCYGy5aMfTs9wx61RivfDKi8H/hcMvw==} + engines: {node: '>=18'} + hasBin: true + '@replit/codemirror-indentation-markers@6.5.3': resolution: {integrity: sha512-hL5Sfvw3C1vgg7GolLe/uxX5T3tmgOA3ZzqlMv47zjU1ON51pzNWiVbS22oh6crYhtVhv8b3gdXwoYp++2ilHw==} peerDependencies: @@ -870,98 +887,98 @@ packages: '@codemirror/state': ^6.0.0 '@codemirror/view': ^6.0.0 - '@rollup/rollup-android-arm-eabi@4.32.0': - resolution: {integrity: sha512-G2fUQQANtBPsNwiVFg4zKiPQyjVKZCUdQUol53R8E71J7AsheRMV/Yv/nB8giOcOVqP7//eB5xPqieBYZe9bGg==} + '@rollup/rollup-android-arm-eabi@4.32.1': + resolution: {integrity: sha512-/pqA4DmqyCm8u5YIDzIdlLcEmuvxb0v8fZdFhVMszSpDTgbQKdw3/mB3eMUHIbubtJ6F9j+LtmyCnHTEqIHyzA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.32.0': - resolution: {integrity: sha512-qhFwQ+ljoymC+j5lXRv8DlaJYY/+8vyvYmVx074zrLsu5ZGWYsJNLjPPVJJjhZQpyAKUGPydOq9hRLLNvh1s3A==} + '@rollup/rollup-android-arm64@4.32.1': + resolution: {integrity: sha512-If3PDskT77q7zgqVqYuj7WG3WC08G1kwXGVFi9Jr8nY6eHucREHkfpX79c0ACAjLj3QIWKPJR7w4i+f5EdLH5Q==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.32.0': - resolution: {integrity: sha512-44n/X3lAlWsEY6vF8CzgCx+LQaoqWGN7TzUfbJDiTIOjJm4+L2Yq+r5a8ytQRGyPqgJDs3Rgyo8eVL7n9iW6AQ==} + '@rollup/rollup-darwin-arm64@4.32.1': + resolution: {integrity: sha512-zCpKHioQ9KgZToFp5Wvz6zaWbMzYQ2LJHQ+QixDKq52KKrF65ueu6Af4hLlLWHjX1Wf/0G5kSJM9PySW9IrvHA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.32.0': - resolution: {integrity: sha512-F9ct0+ZX5Np6+ZDztxiGCIvlCaW87HBdHcozUfsHnj1WCUTBUubAoanhHUfnUHZABlElyRikI0mgcw/qdEm2VQ==} + '@rollup/rollup-darwin-x64@4.32.1': + resolution: {integrity: sha512-sFvF+t2+TyUo/ZQqUcifrJIgznx58oFZbdHS9TvHq3xhPVL9nOp+yZ6LKrO9GWTP+6DbFtoyLDbjTpR62Mbr3Q==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.32.0': - resolution: {integrity: sha512-JpsGxLBB2EFXBsTLHfkZDsXSpSmKD3VxXCgBQtlPcuAqB8TlqtLcbeMhxXQkCDv1avgwNjF8uEIbq5p+Cee0PA==} + '@rollup/rollup-freebsd-arm64@4.32.1': + resolution: {integrity: sha512-NbOa+7InvMWRcY9RG+B6kKIMD/FsnQPH0MWUvDlQB1iXnF/UcKSudCXZtv4lW+C276g3w5AxPbfry5rSYvyeYA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.32.0': - resolution: {integrity: sha512-wegiyBT6rawdpvnD9lmbOpx5Sph+yVZKHbhnSP9MqUEDX08G4UzMU+D87jrazGE7lRSyTRs6NEYHtzfkJ3FjjQ==} + '@rollup/rollup-freebsd-x64@4.32.1': + resolution: {integrity: sha512-JRBRmwvHPXR881j2xjry8HZ86wIPK2CcDw0EXchE1UgU0ubWp9nvlT7cZYKc6bkypBt745b4bglf3+xJ7hXWWw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.32.0': - resolution: {integrity: sha512-3pA7xecItbgOs1A5H58dDvOUEboG5UfpTq3WzAdF54acBbUM+olDJAPkgj1GRJ4ZqE12DZ9/hNS2QZk166v92A==} + '@rollup/rollup-linux-arm-gnueabihf@4.32.1': + resolution: {integrity: sha512-PKvszb+9o/vVdUzCCjL0sKHukEQV39tD3fepXxYrHE3sTKrRdCydI7uldRLbjLmDA3TFDmh418XH19NOsDRH8g==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.32.0': - resolution: {integrity: sha512-Y7XUZEVISGyge51QbYyYAEHwpGgmRrAxQXO3siyYo2kmaj72USSG8LtlQQgAtlGfxYiOwu+2BdbPjzEpcOpRmQ==} + '@rollup/rollup-linux-arm-musleabihf@4.32.1': + resolution: {integrity: sha512-9WHEMV6Y89eL606ReYowXuGF1Yb2vwfKWKdD1A5h+OYnPZSJvxbEjxTRKPgi7tkP2DSnW0YLab1ooy+i/FQp/Q==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.32.0': - resolution: {integrity: sha512-r7/OTF5MqeBrZo5omPXcTnjvv1GsrdH8a8RerARvDFiDwFpDVDnJyByYM/nX+mvks8XXsgPUxkwe/ltaX2VH7w==} + '@rollup/rollup-linux-arm64-gnu@4.32.1': + resolution: {integrity: sha512-tZWc9iEt5fGJ1CL2LRPw8OttkCBDs+D8D3oEM8mH8S1ICZCtFJhD7DZ3XMGM8kpqHvhGUTvNUYVDnmkj4BDXnw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.32.0': - resolution: {integrity: sha512-HJbifC9vex9NqnlodV2BHVFNuzKL5OnsV2dvTw6e1dpZKkNjPG6WUq+nhEYV6Hv2Bv++BXkwcyoGlXnPrjAKXw==} + '@rollup/rollup-linux-arm64-musl@4.32.1': + resolution: {integrity: sha512-FTYc2YoTWUsBz5GTTgGkRYYJ5NGJIi/rCY4oK/I8aKowx1ToXeoVVbIE4LGAjsauvlhjfl0MYacxClLld1VrOw==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.32.0': - resolution: {integrity: sha512-VAEzZTD63YglFlWwRj3taofmkV1V3xhebDXffon7msNz4b14xKsz7utO6F8F4cqt8K/ktTl9rm88yryvDpsfOw==} + '@rollup/rollup-linux-loongarch64-gnu@4.32.1': + resolution: {integrity: sha512-F51qLdOtpS6P1zJVRzYM0v6MrBNypyPEN1GfMiz0gPu9jN8ScGaEFIZQwteSsGKg799oR5EaP7+B2jHgL+d+Kw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.32.0': - resolution: {integrity: sha512-Sts5DST1jXAc9YH/iik1C9QRsLcCoOScf3dfbY5i4kH9RJpKxiTBXqm7qU5O6zTXBTEZry69bGszr3SMgYmMcQ==} + '@rollup/rollup-linux-powerpc64le-gnu@4.32.1': + resolution: {integrity: sha512-wO0WkfSppfX4YFm5KhdCCpnpGbtgQNj/tgvYzrVYFKDpven8w2N6Gg5nB6w+wAMO3AIfSTWeTjfVe+uZ23zAlg==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.32.0': - resolution: {integrity: sha512-qhlXeV9AqxIyY9/R1h1hBD6eMvQCO34ZmdYvry/K+/MBs6d1nRFLm6BOiITLVI+nFAAB9kUB6sdJRKyVHXnqZw==} + '@rollup/rollup-linux-riscv64-gnu@4.32.1': + resolution: {integrity: sha512-iWswS9cIXfJO1MFYtI/4jjlrGb/V58oMu4dYJIKnR5UIwbkzR0PJ09O0PDZT0oJ3LYWXBSWahNf/Mjo6i1E5/g==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.32.0': - resolution: {integrity: sha512-8ZGN7ExnV0qjXa155Rsfi6H8M4iBBwNLBM9lcVS+4NcSzOFaNqmt7djlox8pN1lWrRPMRRQ8NeDlozIGx3Omsw==} + '@rollup/rollup-linux-s390x-gnu@4.32.1': + resolution: {integrity: sha512-RKt8NI9tebzmEthMnfVgG3i/XeECkMPS+ibVZjZ6mNekpbbUmkNWuIN2yHsb/mBPyZke4nlI4YqIdFPgKuoyQQ==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.32.0': - resolution: {integrity: sha512-VDzNHtLLI5s7xd/VubyS10mq6TxvZBp+4NRWoW+Hi3tgV05RtVm4qK99+dClwTN1McA6PHwob6DEJ6PlXbY83A==} + '@rollup/rollup-linux-x64-gnu@4.32.1': + resolution: {integrity: sha512-WQFLZ9c42ECqEjwg/GHHsouij3pzLXkFdz0UxHa/0OM12LzvX7DzedlY0SIEly2v18YZLRhCRoHZDxbBSWoGYg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.32.0': - resolution: {integrity: sha512-qcb9qYDlkxz9DxJo7SDhWxTWV1gFuwznjbTiov289pASxlfGbaOD54mgbs9+z94VwrXtKTu+2RqwlSTbiOqxGg==} + '@rollup/rollup-linux-x64-musl@4.32.1': + resolution: {integrity: sha512-BLoiyHDOWoS3uccNSADMza6V6vCNiphi94tQlVIL5de+r6r/CCQuNnerf+1g2mnk2b6edp5dk0nhdZ7aEjOBsA==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.32.0': - resolution: {integrity: sha512-pFDdotFDMXW2AXVbfdUEfidPAk/OtwE/Hd4eYMTNVVaCQ6Yl8et0meDaKNL63L44Haxv4UExpv9ydSf3aSayDg==} + '@rollup/rollup-win32-arm64-msvc@4.32.1': + resolution: {integrity: sha512-w2l3UnlgYTNNU+Z6wOR8YdaioqfEnwPjIsJ66KxKAf0p+AuL2FHeTX6qvM+p/Ue3XPBVNyVSfCrfZiQh7vZHLQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.32.0': - resolution: {integrity: sha512-/TG7WfrCAjeRNDvI4+0AAMoHxea/USWhAzf9PVDFHbcqrQ7hMMKp4jZIy4VEjk72AAfN5k4TiSMRXRKf/0akSw==} + '@rollup/rollup-win32-ia32-msvc@4.32.1': + resolution: {integrity: sha512-Am9H+TGLomPGkBnaPWie4F3x+yQ2rr4Bk2jpwy+iV+Gel9jLAu/KqT8k3X4jxFPW6Zf8OMnehyutsd+eHoq1WQ==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.32.0': - resolution: {integrity: sha512-5hqO5S3PTEO2E5VjCePxv40gIgyS2KvO7E7/vvC/NbIW4SIRamkMr1hqj+5Y67fbBWv/bQLB6KelBQmXlyCjWA==} + '@rollup/rollup-win32-x64-msvc@4.32.1': + resolution: {integrity: sha512-ar80GhdZb4DgmW3myIS9nRFYcpJRSME8iqWgzH2i44u+IdrzmiXVxeFnExQ5v4JYUSpg94bWjevMG8JHf1Da5Q==} cpu: [x64] os: [win32] @@ -1013,11 +1030,11 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@tanstack/virtual-core@3.11.2': - resolution: {integrity: sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw==} + '@tanstack/virtual-core@3.11.3': + resolution: {integrity: sha512-v2mrNSnMwnPJtcVqNvV0c5roGCBqeogN8jDtgtuHCphdwBasOZ17x8UV8qpHUh+u0MLfX43c0uUHKje0s+Zb0w==} - '@tanstack/vue-virtual@3.11.2': - resolution: {integrity: sha512-y0b1p1FTlzxcSt/ZdGWY1AZ52ddwSU69pvFRYAELUSdLLxV8QOPe9dyT/KATO43UCb3DAwiyzi96h2IoYstBOQ==} + '@tanstack/vue-virtual@3.11.3': + resolution: {integrity: sha512-BVZ00i5XBucetRj2doVd32jOPtJthvZSVJvx9GL4gSQsyngliSCtzlP1Op7TFrEtmebRKT8QUQE1tRhOQzWecQ==} peerDependencies: vue: ^2.7.0 || ^3.0.0 @@ -1058,8 +1075,8 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@22.10.10': - resolution: {integrity: sha512-X47y/mPNzxviAGY5TcYPtYL8JsY3kAq2n8fMmKoRCxq/c4v4pyGNCzM2R6+M5/umG4ZfHuT+sgqDYqWc9rJ6ww==} + '@types/node@22.12.0': + resolution: {integrity: sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -1070,51 +1087,51 @@ packages: '@types/web-bluetooth@0.0.20': resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} - '@typescript-eslint/eslint-plugin@8.21.0': - resolution: {integrity: sha512-eTH+UOR4I7WbdQnG4Z48ebIA6Bgi7WO8HvFEneeYBxG8qCOYgTOFPSg6ek9ITIDvGjDQzWHcoWHCDO2biByNzA==} + '@typescript-eslint/eslint-plugin@8.22.0': + resolution: {integrity: sha512-4Uta6REnz/xEJMvwf72wdUnC3rr4jAQf5jnTkeRQ9b6soxLxhDEbS/pfMPoJLDfFPNVRdryqWUIV/2GZzDJFZw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/parser@8.21.0': - resolution: {integrity: sha512-Wy+/sdEH9kI3w9civgACwabHbKl+qIOu0uFZ9IMKzX3Jpv9og0ZBJrZExGrPpFAY7rWsXuxs5e7CPPP17A4eYA==} + '@typescript-eslint/parser@8.22.0': + resolution: {integrity: sha512-MqtmbdNEdoNxTPzpWiWnqNac54h8JDAmkWtJExBVVnSrSmi9z+sZUt0LfKqk9rjqmKOIeRhO4fHHJ1nQIjduIQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/scope-manager@8.21.0': - resolution: {integrity: sha512-G3IBKz0/0IPfdeGRMbp+4rbjfSSdnGkXsM/pFZA8zM9t9klXDnB/YnKOBQ0GoPmoROa4bCq2NeHgJa5ydsQ4mA==} + '@typescript-eslint/scope-manager@8.22.0': + resolution: {integrity: sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.21.0': - resolution: {integrity: sha512-95OsL6J2BtzoBxHicoXHxgk3z+9P3BEcQTpBKriqiYzLKnM2DeSqs+sndMKdamU8FosiadQFT3D+BSL9EKnAJQ==} + '@typescript-eslint/type-utils@8.22.0': + resolution: {integrity: sha512-NzE3aB62fDEaGjaAYZE4LH7I1MUwHooQ98Byq0G0y3kkibPJQIXVUspzlFOmOfHhiDLwKzMlWxaNv+/qcZurJA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/types@8.21.0': - resolution: {integrity: sha512-PAL6LUuQwotLW2a8VsySDBwYMm129vFm4tMVlylzdoTybTHaAi0oBp7Ac6LhSrHHOdLM3efH+nAR6hAWoMF89A==} + '@typescript-eslint/types@8.22.0': + resolution: {integrity: sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.21.0': - resolution: {integrity: sha512-x+aeKh/AjAArSauz0GiQZsjT8ciadNMHdkUSwBB9Z6PrKc/4knM4g3UfHml6oDJmKC88a6//cdxnO/+P2LkMcg==} + '@typescript-eslint/typescript-estree@8.22.0': + resolution: {integrity: sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/utils@8.21.0': - resolution: {integrity: sha512-xcXBfcq0Kaxgj7dwejMbFyq7IOHgpNMtVuDveK7w3ZGwG9owKzhALVwKpTF2yrZmEwl9SWdetf3fxNzJQaVuxw==} + '@typescript-eslint/utils@8.22.0': + resolution: {integrity: sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/visitor-keys@8.21.0': - resolution: {integrity: sha512-BkLMNpdV6prozk8LlyK/SOoWLmUFi+ZD+pcqti9ILCbVvHGk1ui1g4jJOc2WDLaeExz2qWwojxlPce5PljcT3w==} + '@typescript-eslint/visitor-keys@8.22.0': + resolution: {integrity: sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -1647,8 +1664,8 @@ packages: peerDependencies: eslint: '>=6.0.0' - eslint-config-flat-gitignore@1.0.0: - resolution: {integrity: sha512-EWpSLrAP80IdcYK5sIhq/qAY0pmUdBnbzqzpE3QAn6H6wLBN26cMRoMNU9Di8upTzUSL6TXeYRxWhTYuz8+UQA==} + eslint-config-flat-gitignore@1.0.1: + resolution: {integrity: sha512-wjBmJ8TAb67G2or/gBp/H62uCIkDCjpCmlGPSG41/7QagUjMgh+iegVB3gY8eNYhTAmecjKtclT4wGAjHz5yWA==} peerDependencies: eslint: ^9.5.0 @@ -1883,10 +1900,6 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - find-up-simple@1.0.0: - resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==} - engines: {node: '>=18'} - find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -1912,6 +1925,11 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + 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==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -2170,8 +2188,8 @@ packages: longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - loupe@3.1.2: - resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -2505,6 +2523,16 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + playwright-core@1.50.0: + resolution: {integrity: sha512-CXkSSlr4JaZs2tZHI40DsZUN/NIwgaUPsyLuOAaIZp2CyF2sN5MM5NJsyB188lFSSozFxQ5fPT4qM+f0tH/6wQ==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.50.0: + resolution: {integrity: sha512-+GinGfGTrd2IfX1TA4N2gNmeIksSb+IAe589ZH+FlmpV3MYTx6+buChGIuDLQwrGNCw2lWibqV50fU510N7S+w==} + engines: {node: '>=18'} + hasBin: true + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -2580,8 +2608,8 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - radix-vue@1.9.12: - resolution: {integrity: sha512-zkr66Jqxbej4+oR6O/pZRzyM/VZi66ndbyIBZQjJKAXa1lIoYReZJse6W1EEDZKXknD7rXhpS+jM9Sr23lIqfg==} + radix-vue@1.9.13: + resolution: {integrity: sha512-wk0G69vRDU5TDmhYHZv5Y4j905CLfnvcsFB+CXAbXRuQIl5fUCmOWSOukKhj0MT9YRsW5ujZUjtDF0Ou/hg+8Q==} peerDependencies: vue: '>= 3.2.0' @@ -2652,8 +2680,8 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rollup@4.32.0: - resolution: {integrity: sha512-JmrhfQR31Q4AuNBjjAX4s+a/Pu/Q8Q9iwjWBsjRH1q52SPFE2NqRMK6fUZKKnvKO6id+h7JIRf0oYsph53eATg==} + rollup@4.32.1: + resolution: {integrity: sha512-z+aeEsOeEa3mEbS1Tjl6sAZ8NE3+AalQz1RJGj81M+fizusbdDMoEJwdJNHfaB40Scr4qNu+welOfes7maKonA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2785,8 +2813,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte@5.19.3: - resolution: {integrity: sha512-rb/bkYG9jq67OCWikMvaPnfOobyGn0JizVDwHpdeBtLiNXPMcoA9GTFC3BhptP7xGNquUU8J5GiS7PlGlfDAFA==} + svelte@5.19.4: + resolution: {integrity: sha512-pzWvFQdvfEfT4Ll/JriAtcG7qmWjcL+x/NSl9Q+FPje5SXukYNp9kcufZ27ydauLLE/dwYMz9XRC8kiwTZmfDA==} engines: {node: '>=18'} synckit@0.6.2: @@ -3283,18 +3311,18 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - '@antfu/eslint-config@4.1.0(@typescript-eslint/utils@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(@vue/compiler-sfc@3.5.13)(eslint-plugin-format@1.0.1(eslint@9.19.0(jiti@1.21.7)))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0))': + '@antfu/eslint-config@4.1.0(@typescript-eslint/utils@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(@vue/compiler-sfc@3.5.13)(eslint-plugin-format@1.0.1(eslint@9.19.0(jiti@1.21.7)))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0))': dependencies: '@antfu/install-pkg': 1.0.0 '@clack/prompts': 0.9.1 '@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.19.0(jiti@1.21.7)) '@eslint/markdown': 6.2.2 '@stylistic/eslint-plugin': 3.0.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) - '@typescript-eslint/eslint-plugin': 8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) - '@typescript-eslint/parser': 8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) - '@vitest/eslint-plugin': 1.1.25(@typescript-eslint/utils@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0)) + '@typescript-eslint/eslint-plugin': 8.22.0(@typescript-eslint/parser@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/parser': 8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@vitest/eslint-plugin': 1.1.25(@typescript-eslint/utils@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0)) eslint: 9.19.0(jiti@1.21.7) - eslint-config-flat-gitignore: 1.0.0(eslint@9.19.0(jiti@1.21.7)) + eslint-config-flat-gitignore: 1.0.1(eslint@9.19.0(jiti@1.21.7)) eslint-flat-config-utils: 2.0.0 eslint-merge-processors: 1.0.0(eslint@9.19.0(jiti@1.21.7)) eslint-plugin-antfu: 3.0.0(eslint@9.19.0(jiti@1.21.7)) @@ -3308,7 +3336,7 @@ snapshots: eslint-plugin-regexp: 2.7.0(eslint@9.19.0(jiti@1.21.7)) eslint-plugin-toml: 0.12.0(eslint@9.19.0(jiti@1.21.7)) eslint-plugin-unicorn: 56.0.1(eslint@9.19.0(jiti@1.21.7)) - eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7)) + eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7)) eslint-plugin-vue: 9.32.0(eslint@9.19.0(jiti@1.21.7)) eslint-plugin-yml: 1.16.0(eslint@9.19.0(jiti@1.21.7)) eslint-processor-vue-blocks: 1.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.19.0(jiti@1.21.7)) @@ -3456,7 +3484,7 @@ snapshots: dependencies: '@types/eslint': 9.6.1 '@types/estree': 1.0.6 - '@typescript-eslint/types': 8.21.0 + '@typescript-eslint/types': 8.22.0 comment-parser: 1.4.1 esquery: 1.6.0 jsdoc-type-pratt-parser: 4.1.0 @@ -3710,7 +3738,7 @@ snapshots: '@humanwhocodes/retry@0.4.1': {} - '@iconify-json/simple-icons@1.2.21': + '@iconify-json/simple-icons@1.2.22': dependencies: '@iconify/types': 2.0.0 @@ -3812,67 +3840,71 @@ snapshots: '@pkgr/core@0.1.1': {} + '@playwright/test@1.50.0': + dependencies: + playwright: 1.50.0 + '@replit/codemirror-indentation-markers@6.5.3(@codemirror/language@6.10.8)(@codemirror/state@6.5.1)(@codemirror/view@6.36.2)': dependencies: '@codemirror/language': 6.10.8 '@codemirror/state': 6.5.1 '@codemirror/view': 6.36.2 - '@rollup/rollup-android-arm-eabi@4.32.0': + '@rollup/rollup-android-arm-eabi@4.32.1': optional: true - '@rollup/rollup-android-arm64@4.32.0': + '@rollup/rollup-android-arm64@4.32.1': optional: true - '@rollup/rollup-darwin-arm64@4.32.0': + '@rollup/rollup-darwin-arm64@4.32.1': optional: true - '@rollup/rollup-darwin-x64@4.32.0': + '@rollup/rollup-darwin-x64@4.32.1': optional: true - '@rollup/rollup-freebsd-arm64@4.32.0': + '@rollup/rollup-freebsd-arm64@4.32.1': optional: true - '@rollup/rollup-freebsd-x64@4.32.0': + '@rollup/rollup-freebsd-x64@4.32.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.32.0': + '@rollup/rollup-linux-arm-gnueabihf@4.32.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.32.0': + '@rollup/rollup-linux-arm-musleabihf@4.32.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.32.0': + '@rollup/rollup-linux-arm64-gnu@4.32.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.32.0': + '@rollup/rollup-linux-arm64-musl@4.32.1': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.32.0': + '@rollup/rollup-linux-loongarch64-gnu@4.32.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.32.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.32.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.32.0': + '@rollup/rollup-linux-riscv64-gnu@4.32.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.32.0': + '@rollup/rollup-linux-s390x-gnu@4.32.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.32.0': + '@rollup/rollup-linux-x64-gnu@4.32.1': optional: true - '@rollup/rollup-linux-x64-musl@4.32.0': + '@rollup/rollup-linux-x64-musl@4.32.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.32.0': + '@rollup/rollup-win32-arm64-msvc@4.32.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.32.0': + '@rollup/rollup-win32-ia32-msvc@4.32.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.32.0': + '@rollup/rollup-win32-x64-msvc@4.32.1': optional: true '@scalar/openapi-types@0.1.6': {} @@ -3930,7 +3962,7 @@ snapshots: '@stylistic/eslint-plugin@3.0.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)': dependencies: - '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/utils': 8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) eslint: 9.19.0(jiti@1.21.7) eslint-visitor-keys: 4.2.0 espree: 10.3.0 @@ -3944,11 +3976,11 @@ snapshots: dependencies: tslib: 2.8.1 - '@tanstack/virtual-core@3.11.2': {} + '@tanstack/virtual-core@3.11.3': {} - '@tanstack/vue-virtual@3.11.2(vue@3.5.13(typescript@5.7.3))': + '@tanstack/vue-virtual@3.11.3(vue@3.5.13(typescript@5.7.3))': dependencies: - '@tanstack/virtual-core': 3.11.2 + '@tanstack/virtual-core': 3.11.3 vue: 3.5.13(typescript@5.7.3) '@trojs/openapi-dereference@1.0.1': {} @@ -3987,7 +4019,7 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@22.10.10': + '@types/node@22.12.0': dependencies: undici-types: 6.20.0 @@ -3997,14 +4029,14 @@ snapshots: '@types/web-bluetooth@0.0.20': {} - '@typescript-eslint/eslint-plugin@8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)': + '@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) - '@typescript-eslint/scope-manager': 8.21.0 - '@typescript-eslint/type-utils': 8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) - '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) - '@typescript-eslint/visitor-keys': 8.21.0 + '@typescript-eslint/parser': 8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/scope-manager': 8.22.0 + '@typescript-eslint/type-utils': 8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/utils': 8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/visitor-keys': 8.22.0 eslint: 9.19.0(jiti@1.21.7) graphemer: 1.4.0 ignore: 5.3.2 @@ -4014,27 +4046,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)': + '@typescript-eslint/parser@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)': dependencies: - '@typescript-eslint/scope-manager': 8.21.0 - '@typescript-eslint/types': 8.21.0 - '@typescript-eslint/typescript-estree': 8.21.0(typescript@5.7.3) - '@typescript-eslint/visitor-keys': 8.21.0 + '@typescript-eslint/scope-manager': 8.22.0 + '@typescript-eslint/types': 8.22.0 + '@typescript-eslint/typescript-estree': 8.22.0(typescript@5.7.3) + '@typescript-eslint/visitor-keys': 8.22.0 debug: 4.4.0 eslint: 9.19.0(jiti@1.21.7) typescript: 5.7.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.21.0': + '@typescript-eslint/scope-manager@8.22.0': dependencies: - '@typescript-eslint/types': 8.21.0 - '@typescript-eslint/visitor-keys': 8.21.0 + '@typescript-eslint/types': 8.22.0 + '@typescript-eslint/visitor-keys': 8.22.0 - '@typescript-eslint/type-utils@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)': + '@typescript-eslint/type-utils@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.21.0(typescript@5.7.3) - '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/typescript-estree': 8.22.0(typescript@5.7.3) + '@typescript-eslint/utils': 8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) debug: 4.4.0 eslint: 9.19.0(jiti@1.21.7) ts-api-utils: 2.0.0(typescript@5.7.3) @@ -4042,12 +4074,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.21.0': {} + '@typescript-eslint/types@8.22.0': {} - '@typescript-eslint/typescript-estree@8.21.0(typescript@5.7.3)': + '@typescript-eslint/typescript-estree@8.22.0(typescript@5.7.3)': dependencies: - '@typescript-eslint/types': 8.21.0 - '@typescript-eslint/visitor-keys': 8.21.0 + '@typescript-eslint/types': 8.22.0 + '@typescript-eslint/visitor-keys': 8.22.0 debug: 4.4.0 fast-glob: 3.3.3 is-glob: 4.0.3 @@ -4058,41 +4090,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)': + '@typescript-eslint/utils@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@1.21.7)) - '@typescript-eslint/scope-manager': 8.21.0 - '@typescript-eslint/types': 8.21.0 - '@typescript-eslint/typescript-estree': 8.21.0(typescript@5.7.3) + '@typescript-eslint/scope-manager': 8.22.0 + '@typescript-eslint/types': 8.22.0 + '@typescript-eslint/typescript-estree': 8.22.0(typescript@5.7.3) eslint: 9.19.0(jiti@1.21.7) typescript: 5.7.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.21.0': + '@typescript-eslint/visitor-keys@8.22.0': dependencies: - '@typescript-eslint/types': 8.21.0 + '@typescript-eslint/types': 8.22.0 eslint-visitor-keys: 4.2.0 '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@5.2.1(vite@5.4.14(@types/node@22.10.10))(vue@3.5.13(typescript@5.7.3))': + '@vitejs/plugin-vue@5.2.1(vite@5.4.14(@types/node@22.12.0))(vue@3.5.13(typescript@5.7.3))': dependencies: - vite: 5.4.14(@types/node@22.10.10) + vite: 5.4.14(@types/node@22.12.0) vue: 3.5.13(typescript@5.7.3) - '@vitejs/plugin-vue@5.2.1(vite@6.0.11(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))': + '@vitejs/plugin-vue@5.2.1(vite@6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))': dependencies: - vite: 6.0.11(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0) + vite: 6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0) vue: 3.5.13(typescript@5.7.3) - '@vitest/eslint-plugin@1.1.25(@typescript-eslint/utils@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0))': + '@vitest/eslint-plugin@1.1.25(@typescript-eslint/utils@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3)(vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0))': dependencies: - '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/utils': 8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) eslint: 9.19.0(jiti@1.21.7) optionalDependencies: typescript: 5.7.3 - vitest: 3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0) + vitest: 3.0.4(@types/debug@4.1.12)(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0) '@vitest/expect@3.0.4': dependencies: @@ -4101,13 +4133,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 2.0.0 - '@vitest/mocker@3.0.4(vite@6.0.11(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0))': + '@vitest/mocker@3.0.4(vite@6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0))': dependencies: '@vitest/spy': 3.0.4 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.0.11(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0) + vite: 6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0) '@vitest/pretty-format@3.0.4': dependencies: @@ -4131,7 +4163,7 @@ snapshots: '@vitest/utils@3.0.4': dependencies: '@vitest/pretty-format': 3.0.4 - loupe: 3.1.2 + loupe: 3.1.3 tinyrainbow: 2.0.0 '@volar/language-core@2.4.11': @@ -4418,7 +4450,7 @@ snapshots: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.2 + loupe: 3.1.3 pathval: 2.0.0 chalk@4.1.2: @@ -4639,11 +4671,10 @@ snapshots: eslint: 9.19.0(jiti@1.21.7) semver: 7.6.3 - eslint-config-flat-gitignore@1.0.0(eslint@9.19.0(jiti@1.21.7)): + eslint-config-flat-gitignore@1.0.1(eslint@9.19.0(jiti@1.21.7)): dependencies: '@eslint/compat': 1.2.5(eslint@9.19.0(jiti@1.21.7)) eslint: 9.19.0(jiti@1.21.7) - find-up-simple: 1.0.0 eslint-flat-config-utils@2.0.0: dependencies: @@ -4709,8 +4740,8 @@ snapshots: eslint-plugin-import-x@4.6.1(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3): dependencies: '@types/doctrine': 0.0.9 - '@typescript-eslint/scope-manager': 8.21.0 - '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/scope-manager': 8.22.0 + '@typescript-eslint/utils': 8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) debug: 4.4.0 doctrine: 3.0.0 enhanced-resolve: 5.18.0 @@ -4773,8 +4804,8 @@ snapshots: eslint-plugin-perfectionist@4.7.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3): dependencies: - '@typescript-eslint/types': 8.21.0 - '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/types': 8.22.0 + '@typescript-eslint/utils': 8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) eslint: 9.19.0(jiti@1.21.7) natural-orderby: 5.0.0 transitivePeerDependencies: @@ -4822,11 +4853,11 @@ snapshots: semver: 7.6.3 strip-indent: 3.0.0 - eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7)): + eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7)): dependencies: eslint: 9.19.0(jiti@1.21.7) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) + '@typescript-eslint/eslint-plugin': 8.22.0(@typescript-eslint/parser@8.22.0(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.19.0(jiti@1.21.7))(typescript@5.7.3) eslint-plugin-vue@9.32.0(eslint@9.19.0(jiti@1.21.7)): dependencies: @@ -4981,8 +5012,6 @@ snapshots: dependencies: to-regex-range: 5.0.1 - find-up-simple@1.0.0: {} - find-up@4.1.0: dependencies: locate-path: 5.0.0 @@ -5011,6 +5040,9 @@ snapshots: fraction.js@4.3.7: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -5229,7 +5261,7 @@ snapshots: longest-streak@3.1.0: {} - loupe@3.1.2: {} + loupe@3.1.3: {} lru-cache@10.4.3: {} @@ -5724,6 +5756,14 @@ snapshots: mlly: 1.7.4 pathe: 2.0.2 + playwright-core@1.50.0: {} + + playwright@1.50.0: + dependencies: + playwright-core: 1.50.0 + optionalDependencies: + fsevents: 2.3.2 + pluralize@8.0.0: {} postcss-import@15.1.0(postcss@8.5.1): @@ -5781,13 +5821,13 @@ snapshots: queue-microtask@1.2.3: {} - radix-vue@1.9.12(vue@3.5.13(typescript@5.7.3)): + radix-vue@1.9.13(vue@3.5.13(typescript@5.7.3)): dependencies: '@floating-ui/dom': 1.6.13 '@floating-ui/vue': 1.1.6(vue@3.5.13(typescript@5.7.3)) '@internationalized/date': 3.7.0 '@internationalized/number': 3.6.0 - '@tanstack/vue-virtual': 3.11.2(vue@3.5.13(typescript@5.7.3)) + '@tanstack/vue-virtual': 3.11.3(vue@3.5.13(typescript@5.7.3)) '@vueuse/core': 10.11.1(vue@3.5.13(typescript@5.7.3)) '@vueuse/shared': 10.11.1(vue@3.5.13(typescript@5.7.3)) aria-hidden: 1.2.4 @@ -5863,29 +5903,29 @@ snapshots: rfdc@1.4.1: {} - rollup@4.32.0: + rollup@4.32.1: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.32.0 - '@rollup/rollup-android-arm64': 4.32.0 - '@rollup/rollup-darwin-arm64': 4.32.0 - '@rollup/rollup-darwin-x64': 4.32.0 - '@rollup/rollup-freebsd-arm64': 4.32.0 - '@rollup/rollup-freebsd-x64': 4.32.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.32.0 - '@rollup/rollup-linux-arm-musleabihf': 4.32.0 - '@rollup/rollup-linux-arm64-gnu': 4.32.0 - '@rollup/rollup-linux-arm64-musl': 4.32.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.32.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.32.0 - '@rollup/rollup-linux-riscv64-gnu': 4.32.0 - '@rollup/rollup-linux-s390x-gnu': 4.32.0 - '@rollup/rollup-linux-x64-gnu': 4.32.0 - '@rollup/rollup-linux-x64-musl': 4.32.0 - '@rollup/rollup-win32-arm64-msvc': 4.32.0 - '@rollup/rollup-win32-ia32-msvc': 4.32.0 - '@rollup/rollup-win32-x64-msvc': 4.32.0 + '@rollup/rollup-android-arm-eabi': 4.32.1 + '@rollup/rollup-android-arm64': 4.32.1 + '@rollup/rollup-darwin-arm64': 4.32.1 + '@rollup/rollup-darwin-x64': 4.32.1 + '@rollup/rollup-freebsd-arm64': 4.32.1 + '@rollup/rollup-freebsd-x64': 4.32.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.32.1 + '@rollup/rollup-linux-arm-musleabihf': 4.32.1 + '@rollup/rollup-linux-arm64-gnu': 4.32.1 + '@rollup/rollup-linux-arm64-musl': 4.32.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.32.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.32.1 + '@rollup/rollup-linux-riscv64-gnu': 4.32.1 + '@rollup/rollup-linux-s390x-gnu': 4.32.1 + '@rollup/rollup-linux-x64-gnu': 4.32.1 + '@rollup/rollup-linux-x64-musl': 4.32.1 + '@rollup/rollup-win32-arm64-msvc': 4.32.1 + '@rollup/rollup-win32-ia32-msvc': 4.32.1 + '@rollup/rollup-win32-x64-msvc': 4.32.1 fsevents: 2.3.3 run-parallel@1.2.0: @@ -6015,7 +6055,7 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte@5.19.3: + svelte@5.19.4: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 @@ -6198,7 +6238,7 @@ snapshots: lodash-es: 4.17.21 memoize-one: 6.0.0 natural-compare-lite: 1.4.0 - svelte: 5.19.3 + svelte: 5.19.4 vanilla-picker: 2.12.3 vanilla-picker@2.12.3: @@ -6215,13 +6255,13 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-node@3.0.4(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0): + vite-node@3.0.4(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 2.0.2 - vite: 6.0.11(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0) + vite: 6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - jiti @@ -6236,36 +6276,36 @@ snapshots: - tsx - yaml - vite@5.4.14(@types/node@22.10.10): + vite@5.4.14(@types/node@22.12.0): dependencies: esbuild: 0.21.5 postcss: 8.5.1 - rollup: 4.32.0 + rollup: 4.32.1 optionalDependencies: - '@types/node': 22.10.10 + '@types/node': 22.12.0 fsevents: 2.3.3 - vite@6.0.11(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0): + vite@6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0): dependencies: esbuild: 0.24.2 postcss: 8.5.1 - rollup: 4.32.0 + rollup: 4.32.1 optionalDependencies: - '@types/node': 22.10.10 + '@types/node': 22.12.0 fsevents: 2.3.3 jiti: 1.21.7 yaml: 2.7.0 - vitepress@1.6.3(@algolia/client-search@5.20.0)(@types/node@22.10.10)(postcss@8.5.1)(search-insights@2.17.3)(typescript@5.7.3): + vitepress@1.6.3(@algolia/client-search@5.20.0)(@types/node@22.12.0)(postcss@8.5.1)(search-insights@2.17.3)(typescript@5.7.3): dependencies: '@docsearch/css': 3.8.2 '@docsearch/js': 3.8.2(@algolia/client-search@5.20.0)(search-insights@2.17.3) - '@iconify-json/simple-icons': 1.2.21 + '@iconify-json/simple-icons': 1.2.22 '@shikijs/core': 2.1.0 '@shikijs/transformers': 2.1.0 '@shikijs/types': 2.1.0 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.2.1(vite@5.4.14(@types/node@22.10.10))(vue@3.5.13(typescript@5.7.3)) + '@vitejs/plugin-vue': 5.2.1(vite@5.4.14(@types/node@22.12.0))(vue@3.5.13(typescript@5.7.3)) '@vue/devtools-api': 7.7.1 '@vue/shared': 3.5.13 '@vueuse/core': 12.5.0(typescript@5.7.3) @@ -6274,7 +6314,7 @@ snapshots: mark.js: 8.11.1 minisearch: 7.1.1 shiki: 2.1.0 - vite: 5.4.14(@types/node@22.10.10) + vite: 5.4.14(@types/node@22.12.0) vue: 3.5.13(typescript@5.7.3) optionalDependencies: postcss: 8.5.1 @@ -6305,10 +6345,10 @@ snapshots: - typescript - universal-cookie - vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0): + vitest@3.0.4(@types/debug@4.1.12)(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0): dependencies: '@vitest/expect': 3.0.4 - '@vitest/mocker': 3.0.4(vite@6.0.11(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0)) + '@vitest/mocker': 3.0.4(vite@6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0)) '@vitest/pretty-format': 3.0.4 '@vitest/runner': 3.0.4 '@vitest/snapshot': 3.0.4 @@ -6324,12 +6364,12 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.0.11(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0) - vite-node: 3.0.4(@types/node@22.10.10)(jiti@1.21.7)(yaml@2.7.0) + vite: 6.0.11(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0) + vite-node: 3.0.4(@types/node@22.12.0)(jiti@1.21.7)(yaml@2.7.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 22.10.10 + '@types/node': 22.12.0 transitivePeerDependencies: - jiti - less diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 28756fa..2f0aa75 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - docs + - e2e/dev diff --git a/vite.config.ts b/vite.config.ts index 7fdeffe..916da10 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,6 @@ import { resolve } from 'node:path' -import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' +import { defineConfig } from 'vite' export default defineConfig({ plugins: [ diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..578eaeb --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + include: ['test/**/*.test.{ts,js}'], + }, +})