diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml new file mode 100644 index 000000000..d6cf95c2a --- /dev/null +++ b/.github/workflows/integration-tests.yaml @@ -0,0 +1,56 @@ +name: Integration Tests + +on: + workflow_dispatch: + push: + tags: + - "!**" + branches: + - "**" + pull_request: + +env: + HUSKY: 0 + NX_REJECT_UNKNOWN_LOCAL_CACHE: 0 + +jobs: + prepare-docker: + runs-on: ubuntu-latest + steps: + - name: Set up Docker cache + id: cache-docker-image + uses: actions/cache@v4 + with: + path: /tmp/specmatic.tar + key: ${{ runner.os }}-docker-specmatic-2.23.4 + + - name: Pull and save Docker image to cache + if: steps.cache-docker-image.outputs.cache-hit != 'true' + run: | + echo "Cache miss. Pulling image and saving to cache..." + docker pull specmatic/specmatic:2.23.4 + docker save specmatic/specmatic:2.23.4 --output /tmp/specmatic.tar + + integration-test: + runs-on: ubuntu-latest + needs: [prepare-docker] + steps: + - uses: actions/checkout@v4 + + - uses: ./.github/actions/setup-node + + - name: Restore Docker image from cache + uses: actions/cache@v4 + with: + path: /tmp/specmatic.tar + key: ${{ runner.os }}-docker-specmatic-2.23.4 + + - name: Load Docker image + run: docker load --input /tmp/specmatic.tar + + # TODO only run affected + - name: Build + run: pnpm nx run-many --target=build --parallel=3 -p="tag:npm:public" + + - name: Run integration tests + run: pnpm nx test:integration storyblok-js-client diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 000000000..7482cfab4 --- /dev/null +++ b/docs/testing.md @@ -0,0 +1,195 @@ +# Testing + +- We use Vitest for running unit and integration tests of regular packages. + - For playground applications, we use Playwright for integration testing. +- Prefer explicit imports of `it`, `expect`, and other test functions from `@storyblok/test-utils/vitest` or `@storyblok/test-utils/playwright`. +- Tests begin with `it("should ...")` + - `it` (the function, component, or system under test) `should` (behave in the following way). + +## Unit tests + +- We use unit tests to test business logic. +- We avoid mocking dependencies and structure our code in a way that makes mocking unnecessary. +- We use mocking to avoid side effects like writing to the file system or making requests to HTTP endpoints. + +## Integration tests + +- We use integration tests to ensure specific features work as expected in the same scenarios a user would use them. +- We avoid mocking as much as possible (even for side effects) but may sometimes decide to mock, for example, the file system. +- For testing functionality that triggers requests to HTTP endpoints, we use an OpenAPI specification-driven stub server. + +### Specmatic stub server + +- [Specmatic](https://specmatic.io) allows us to quickly spin up a stub server based on OpenAPI specifications of our CAPI and MAPI endpoints. +- We use an abstraction pattern we call `Preconditions` to configure particular responses from the stub server. + +**Configuration with `specmatic.json`:** + +To tell the stub server which OpenAPI specifications to use, we must create a `specmatic.json` file in the root directory of our package. We must also install the `@storyblok/openapi` package as a dev dependency: + +```json +{ + "version": 2, + "contracts": [ + { + "consumes": [ + "./node_modules/@storyblok/openapi/dist/mapi/stories.yaml" + ] + } + ] +} +``` + +**Examples:** + +```ts +import type { Story } from "@storyblok/management-api-client/resources/stories"; +import type { ExampleStore } from "../utils/stub-server.ts"; +import { makeStory } from "./stories.ts"; + +export const hasStory = + ({ story = makeStory() }: { story?: Story } = {}) => + ({ store }: { store: ExampleStore }) => + // The example store holds request/response examples for the stub server. + store.add({ + // Given a request like this... + request: { + method: "GET", + path: `/v1/cdn/stories/${story.slug}`, + }, + // ...the stub server will respond with this. + response: { + status: 200, + body: { story }, + }, + // Match this example even if the request is only a partial match + // (e.g., additional query parameters are sent). + partial: true, + }); +``` + +### Integration tests with Vitest + +- We use Vitest to power integration tests for regular packages. + +**Examples:** + +```ts +import StoryblokClient from 'storyblok-js-client'; +import { describe, expect, it } from '@storyblok/test-utils/vitest'; +import { hasStories } from '@storyblok/test-utils/preconditions/stories-mapi'; +import { makeStory } from '@storyblok/test-utils/preconditions/stories'; + +const makeMapi = ({ baseURL }: { baseURL: string }) => new StoryblokClient({ + oauthToken: 'Bearer super-valid-token', + endpoint: `${baseURL}/v1`, +}); + +describe('getAll()', () => { + it('should return a list of stories', async ({ prepare, stubServer }) => { + // Create a MAPI client instance using the stub server's baseURL. + const mapi = makeMapi(stubServer); + // Use the `makeStory` precondition helper to create a new story with a + // particular name, using default values for all other attributes. + const story = makeStory({ name: 'foo bar' }); + // Use the `prepare` helper to send the `hasStories` precondition to the + // stub server. + await prepare(hasStories({ spaceId: '123', stories: [story] })); + + // The MAPI client is configured to make a request to the stub server... + const result = await mapi.getAll( + `spaces/123/stories`, + ); + + // ...which should return the result we prepared above. + expect(result[0].name).toBe('foo bar'); + expect(result).toEqual([story]); + }); +}); +``` + +```ts +import { expect, it, vi } from '@storyblok/test-utils/vitest'; +import { canNotUpdateStory, hasStory } from '@storyblok/test-utils/preconditions/stories-mapi'; +import { makeBlok, makeStory } from '@storyblok/test-utils/preconditions/stories'; +import '../index'; +import { migrationsCommand } from '../command'; +import { konsola } from '../../../utils'; + +process.env.STORYBLOK_LOGIN = 'foo'; +process.env.STORYBLOK_TOKEN = 'Bearer foo.bar.baz'; +process.env.STORYBLOK_REGION = 'eu'; +// We can configure the CLI `baseUrl` via an environment variable. +process.env.STORYBLOK_BASE_URL = 'http://localhost:9000'; + +it('should handle dry run mode correctly', async ({ prepare, stubServer }) => { + // We configure the environment variable to use the current + // `stubServer.baseURL`. + process.env.STORYBLOK_BASE_URL = stubServer.baseURL; + const story = makeStory({ + content: makeBlok({ + field: 'original', + component: 'migration-component', + }), + }); + const spaceId = '12345'; + await prepare([ + hasStory({ spaceId, story }), + // If the update endpoint is called while the `dry-run` flag is enabled, + // the request will fail and the console output will mention the failed + // update. + canNotUpdateStory({ spaceId, storyId: story.id }), + ]); + using konsolaWarnSpy = vi.spyOn(konsola, 'warn'); + using konsolaInfoSpy = vi.spyOn(konsola, 'info'); + + // Run the command with the --dry-run flag. + await migrationsCommand.parseAsync(['node', 'test', 'run', '--space', spaceId, '--dry-run', '--path', './src/commands/migrations/run/__data__']); + + expect(konsolaWarnSpy).toHaveBeenCalledWith( + expect.stringContaining('DRY RUN MODE ENABLED: No changes will be made.'), + ); + expect(konsolaInfoSpy).toHaveBeenCalledWith( + expect.stringContaining('Migration Results: 1 stories updated, 0 stories skipped.'), + ); + expect(konsolaInfoSpy).toHaveBeenCalledWith( + expect.stringContaining('Update Results: 1 stories updated.'), + ); +}); +``` + +### Integration tests with Playwright + +- We use Playwright to run integration tests for playground applications. + +**Examples:** + +```ts +import { it, expect } from '@storyblok/test-utils/playwright'; +import { hasStory } from '@storyblok/test-utils/preconditions/stories-capi'; +import { makeStory, makeBlok } from "@storyblok/test-utils/preconditions/stories"; + +it('should render the emoji randomizer', async ({ page, startApp }) => { + // The `startApp` command injects the `STORYBLOK_API_ENDPOINT` environment + // variable, pointing to the current stub server instance. It also accepts + // an array of preconditions to configure the server's responses. + await startApp('pnpm start', [hasStory({ + story: makeStory({ + slug: 'react', + content: makeBlok({ + component: "page", + body: [ + makeBlok({ + label: "Randomize Emoji", + component: "emoji-randomizer", + }) + ] + }) + }) + })]); + + await page.goto('/'); + + await expect(page.getByRole('button', { name: "Randomize Emoji" })).toBeVisible(); +}); +``` diff --git a/packages/cli/__mocks__/fs.cjs b/packages/cli/__mocks__/fs.cjs index abd6f2b2a..db26fd62c 100644 --- a/packages/cli/__mocks__/fs.cjs +++ b/packages/cli/__mocks__/fs.cjs @@ -1,6 +1,3 @@ -// we can also use `import`, but then -// every export should be explicitly defined - const { fs } = require('memfs'); module.exports = fs; diff --git a/packages/cli/__mocks__/fs/promises.cjs b/packages/cli/__mocks__/fs/promises.cjs index 591b52824..bccdebb93 100644 --- a/packages/cli/__mocks__/fs/promises.cjs +++ b/packages/cli/__mocks__/fs/promises.cjs @@ -1,6 +1,3 @@ -// we can also use `import`, but then -// every export should be explicitly defined - const { fs } = require('memfs'); module.exports = fs.promises; diff --git a/packages/cli/package.json b/packages/cli/package.json index 92223d23b..cab6ca949 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -35,6 +35,7 @@ "test:types": "tsc --noEmit --skipLibCheck", "test:ci": "vitest run", "test:ui": "vitest --ui", + "test:integration": "vitest run --project integration", "coverage": "vitest run --coverage" }, "dependencies": { @@ -61,13 +62,14 @@ "devDependencies": { "@release-it/conventional-changelog": "10.0.0", "@storyblok/eslint-config": "workspace:*", + "@storyblok/openapi": "workspace:*", "@types/cli-progress": "^3.11.6", "@types/inquirer": "^9.0.8", "@types/node": "^22.15.18", "@vitest/coverage-v8": "^3.1.3", "@vitest/ui": "^3.1.3", "eslint": "^9.26.0", - "memfs": "^4.17.1", + "memfs": "^4.17.2", "msw": "^2.8.2", "release-it": "^18.1.2", "typescript": "5.8.3", diff --git a/packages/cli/specmatic.json b/packages/cli/specmatic.json new file mode 100644 index 000000000..a6fb482f5 --- /dev/null +++ b/packages/cli/specmatic.json @@ -0,0 +1,10 @@ +{ + "version": 2, + "contracts": [ + { + "consumes": [ + "./node_modules/@storyblok/openapi/dist/mapi/stories.yaml" + ] + } + ] +} diff --git a/packages/cli/src/commands/components/pull/actions.test.ts b/packages/cli/src/commands/components/pull/actions.test.ts index 0871aa2fe..85a8795dc 100644 --- a/packages/cli/src/commands/components/pull/actions.test.ts +++ b/packages/cli/src/commands/components/pull/actions.test.ts @@ -1,7 +1,7 @@ import { http, HttpResponse } from 'msw'; import { setupServer } from 'msw/node'; import { vol } from 'memfs'; -import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest'; import { fetchComponent, fetchComponents, saveComponentsToFiles } from './actions'; import { mapiClient } from '../../../api'; @@ -56,9 +56,6 @@ beforeAll(() => server.listen({ onUnhandledRequest: 'error' })); afterEach(() => server.resetHandlers()); afterAll(() => server.close()); -vi.mock('node:fs'); -vi.mock('node:fs/promises'); - describe('pull components actions', () => { beforeEach(() => { mapiClient({ diff --git a/packages/cli/src/commands/components/pull/index.ts b/packages/cli/src/commands/components/pull/index.ts index 2c138d150..086d44113 100644 --- a/packages/cli/src/commands/components/pull/index.ts +++ b/packages/cli/src/commands/components/pull/index.ts @@ -38,13 +38,14 @@ componentsCommand return; } - const { password, region } = state; + const { password, region, baseUrl } = state; mapiClient({ token: { accessToken: password, }, region, + baseUrl, }); const spinnerGroups = new Spinner({ diff --git a/packages/cli/src/commands/components/push/index.ts b/packages/cli/src/commands/components/push/index.ts index 830e989d7..b085ac036 100644 --- a/packages/cli/src/commands/components/push/index.ts +++ b/packages/cli/src/commands/components/push/index.ts @@ -53,7 +53,7 @@ componentsCommand konsola.info(`Attempting to push components ${chalk.bold('from')} space ${chalk.hex(colorPalette.COMPONENTS)(options.from)} ${chalk.bold('to')} ${chalk.hex(colorPalette.COMPONENTS)(space)}`); konsola.br(); - const { password, region } = state; + const { password, region, baseUrl } = state; let requestCount = 0; @@ -62,6 +62,7 @@ componentsCommand accessToken: password, }, region, + baseUrl, }); client.interceptors.request.use((config) => { diff --git a/packages/cli/src/commands/create/actions.test.ts b/packages/cli/src/commands/create/actions.test.ts index ebd995eaf..b9d7c81d0 100644 --- a/packages/cli/src/commands/create/actions.test.ts +++ b/packages/cli/src/commands/create/actions.test.ts @@ -1,6 +1,5 @@ import { spawn } from 'node:child_process'; import fs from 'node:fs/promises'; -import { vol } from 'memfs'; import { beforeEach, describe, expect, it, type MockedFunction, vi } from 'vitest'; import open from 'open'; import { createEnvFile, extractPortFromTopics, fetchBlueprintRepositories, generateProject, generateSpaceUrl, openSpaceInBrowser, repositoryToTemplate } from './actions'; @@ -8,7 +7,6 @@ import * as filesystem from '../../utils/filesystem'; // Mock external dependencies vi.mock('node:child_process'); -vi.mock('node:fs'); vi.mock('node:fs/promises', () => ({ default: { access: vi.fn(), @@ -39,7 +37,6 @@ const mockedHandleAPIError = vi.mocked(handleAPIError); describe('create actions', () => { beforeEach(() => { vi.clearAllMocks(); - vol.reset(); }); describe('generateProject', () => { diff --git a/packages/cli/src/commands/create/index.ts b/packages/cli/src/commands/create/index.ts index 370fbfb6b..3abb0eeb6 100644 --- a/packages/cli/src/commands/create/index.ts +++ b/packages/cli/src/commands/create/index.ts @@ -47,13 +47,14 @@ export const createCommand = program return; } - const { password, region } = state; + const { password, region, baseUrl } = state; mapiClient({ token: { accessToken: password, }, region, + baseUrl, }); const spinnerBlueprints = new Spinner({ @@ -67,7 +68,7 @@ export const createCommand = program let userData: User; try { - const user = await getUser(password, region); + const user = await getUser(password, region, baseUrl); if (!user) { throw new Error('User data is undefined'); } diff --git a/packages/cli/src/commands/datasources/delete/index.ts b/packages/cli/src/commands/datasources/delete/index.ts index e05a8fb85..6d5b4145d 100644 --- a/packages/cli/src/commands/datasources/delete/index.ts +++ b/packages/cli/src/commands/datasources/delete/index.ts @@ -46,12 +46,13 @@ datasourcesCommand return; } - const { password, region } = state; + const { password, region, baseUrl } = state; mapiClient({ token: { accessToken: password, }, region, + baseUrl, }); const spinner = new Spinner({ diff --git a/packages/cli/src/commands/datasources/pull/actions.test.ts b/packages/cli/src/commands/datasources/pull/actions.test.ts index ed0796c68..36ffcabaf 100644 --- a/packages/cli/src/commands/datasources/pull/actions.test.ts +++ b/packages/cli/src/commands/datasources/pull/actions.test.ts @@ -1,6 +1,6 @@ import { http, HttpResponse } from 'msw'; import { setupServer } from 'msw/node'; -import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest'; import { fetchDatasources, saveDatasourcesToFiles } from './actions'; import { mapiClient } from '../../../api'; import type { SpaceDatasource, SpaceDatasourceEntry } from '../constants'; @@ -103,10 +103,6 @@ beforeAll(() => server.listen({ onUnhandledRequest: 'error' })); afterEach(() => server.resetHandlers()); afterAll(() => server.close()); -// Mock filesystem modules -vi.mock('node:fs'); -vi.mock('node:fs/promises'); - describe('pull datasources actions', () => { beforeEach(() => { mapiClient({ @@ -252,10 +248,6 @@ describe('pull datasources actions', () => { }); describe('saveDatasourcesToFiles', () => { - beforeEach(() => { - vol.reset(); - }); - it('should save datasources to a single consolidated file', async () => { vol.fromJSON({ '/mock/path/': null, diff --git a/packages/cli/src/commands/datasources/pull/index.ts b/packages/cli/src/commands/datasources/pull/index.ts index 697dd6ad4..f3a0b7d7d 100644 --- a/packages/cli/src/commands/datasources/pull/index.ts +++ b/packages/cli/src/commands/datasources/pull/index.ts @@ -39,13 +39,14 @@ datasourcesCommand return; } - const { password, region } = state; + const { password, region, baseUrl } = state; mapiClient({ token: { accessToken: password, }, region, + baseUrl, }); const spinnerDatasources = new Spinner({ diff --git a/packages/cli/src/commands/datasources/push/actions.test.ts b/packages/cli/src/commands/datasources/push/actions.test.ts index 87683bc2b..006b3ca34 100644 --- a/packages/cli/src/commands/datasources/push/actions.test.ts +++ b/packages/cli/src/commands/datasources/push/actions.test.ts @@ -1,13 +1,9 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { readDatasourcesFiles } from './actions'; import type { SpaceDatasource } from '../constants'; import { vol } from 'memfs'; import { FileSystemError } from '../../../utils'; -// Mock filesystem modules -vi.mock('node:fs'); -vi.mock('node:fs/promises'); - // Mock datasources data that matches the SpaceDatasource interface const mockDatasource1: SpaceDatasource = { id: 1, @@ -62,14 +58,6 @@ const mockDatasource2: SpaceDatasource = { }; describe('push datasources actions', () => { - beforeEach(() => { - vol.reset(); - }); - - afterEach(() => { - vol.reset(); - }); - describe('readDatasourcesFiles', () => { describe('error handling', () => { it('should throw FileSystemError when directory does not exist', async () => { diff --git a/packages/cli/src/commands/datasources/push/index.ts b/packages/cli/src/commands/datasources/push/index.ts index 930efe3f2..f08c78073 100644 --- a/packages/cli/src/commands/datasources/push/index.ts +++ b/packages/cli/src/commands/datasources/push/index.ts @@ -50,13 +50,14 @@ datasourcesCommand konsola.info(`Attempting to push datasources ${chalk.bold('from')} space ${chalk.hex(colorPalette.DATASOURCES)(options.from || space)} ${chalk.bold('to')} ${chalk.hex(colorPalette.DATASOURCES)(space)}`); konsola.br(); - const { password, region } = state; + const { password, region, baseUrl } = state; mapiClient({ token: { accessToken: password, }, region, + baseUrl, }); try { diff --git a/packages/cli/src/commands/languages/actions.test.ts b/packages/cli/src/commands/languages/actions.test.ts index 176feed7a..823d35ce1 100644 --- a/packages/cli/src/commands/languages/actions.test.ts +++ b/packages/cli/src/commands/languages/actions.test.ts @@ -36,9 +36,6 @@ beforeAll(() => server.listen({ onUnhandledRequest: 'error' })); afterEach(() => server.resetHandlers()); afterAll(() => server.close()); -vi.mock('node:fs'); -vi.mock('node:fs/promises'); - describe('pull languages actions', () => { beforeEach(() => { mapiClient({ @@ -48,7 +45,6 @@ describe('pull languages actions', () => { region: 'eu', }); vi.clearAllMocks(); - vol.reset(); }); describe('fetchLanguages', () => { diff --git a/packages/cli/src/commands/languages/index.ts b/packages/cli/src/commands/languages/index.ts index 35ff5ca7a..6d86b3b4e 100644 --- a/packages/cli/src/commands/languages/index.ts +++ b/packages/cli/src/commands/languages/index.ts @@ -43,13 +43,14 @@ languagesCommand return; } - const { password, region } = state; + const { password, region, baseUrl } = state; mapiClient({ token: { accessToken: password, }, region, + baseUrl, }); const spinner = new Spinner({ diff --git a/packages/cli/src/commands/login/actions.ts b/packages/cli/src/commands/login/actions.ts index ad4f19918..c39fa00c2 100644 --- a/packages/cli/src/commands/login/actions.ts +++ b/packages/cli/src/commands/login/actions.ts @@ -6,9 +6,9 @@ import { getStoryblokUrl } from '../../utils/api-routes'; import type { StoryblokLoginResponse, StoryblokLoginWithOtpResponse } from '../../types'; import { getUser } from '../user/actions'; -export const loginWithToken = async (token: string, region: RegionCode) => { +export const loginWithToken = async (token: string, region: RegionCode, baseUrl?: string) => { try { - return await getUser(token, region); + return await getUser(token, region, baseUrl); } catch (error) { // If getUser already threw an APIError, just re-throw it diff --git a/packages/cli/src/commands/login/index.ts b/packages/cli/src/commands/login/index.ts index eff731858..5ce611bee 100644 --- a/packages/cli/src/commands/login/index.ts +++ b/packages/cli/src/commands/login/index.ts @@ -76,7 +76,7 @@ export const loginCommand = program }); } spinner.start(`Logging in with token`); - const user = await loginWithToken(token, userRegion); + const user = await loginWithToken(token, userRegion, state.baseUrl); if (user) { updateSession(user.email, token, userRegion); @@ -124,7 +124,7 @@ export const loginCommand = program }); } spinner.start(`Logging in with token`); - const user = await loginWithToken(userToken, userRegion); + const user = await loginWithToken(userToken, userRegion, state.baseUrl); spinner.succeed(); if (user) { updateSession(user.email, userToken, userRegion); diff --git a/packages/cli/src/commands/migrations/generate/index.ts b/packages/cli/src/commands/migrations/generate/index.ts index a93481fb6..2042fc21d 100644 --- a/packages/cli/src/commands/migrations/generate/index.ts +++ b/packages/cli/src/commands/migrations/generate/index.ts @@ -43,13 +43,14 @@ migrationsCommand return; } - const { password, region } = state; + const { password, region, baseUrl } = state; mapiClient({ token: { accessToken: password, }, region, + baseUrl, }); const spinner = new Spinner({ diff --git a/packages/cli/src/commands/migrations/rollback/actions.test.ts b/packages/cli/src/commands/migrations/rollback/actions.test.ts index 43549d75f..62bb82f9b 100644 --- a/packages/cli/src/commands/migrations/rollback/actions.test.ts +++ b/packages/cli/src/commands/migrations/rollback/actions.test.ts @@ -3,10 +3,6 @@ import { readRollbackFile, saveRollbackData } from './actions'; import { CommandError } from '../../../utils'; import type { StoryContent } from '../../stories/constants'; -// Mock dependencies -vi.mock('node:fs'); -vi.mock('node:fs/promises'); - const mockStoryContent: StoryContent = { _uid: 'test-uid', component: 'test', @@ -14,10 +10,6 @@ const mockStoryContent: StoryContent = { }; describe('saveRollbackData', () => { - beforeEach(() => { - vol.reset(); - }); - it('should save rollback data successfully', async () => { const mockStory1 = { id: 1, @@ -86,10 +78,6 @@ describe('saveRollbackData', () => { }); describe('readRollbackFile', () => { - beforeEach(() => { - vol.reset(); - }); - it('should read rollback file successfully', async () => { const mockRollbackData = [ { diff --git a/packages/cli/src/commands/migrations/rollback/index.ts b/packages/cli/src/commands/migrations/rollback/index.ts index 0b2018854..75bdb8a74 100644 --- a/packages/cli/src/commands/migrations/rollback/index.ts +++ b/packages/cli/src/commands/migrations/rollback/index.ts @@ -33,12 +33,13 @@ migrationsCommand.command('rollback [migrationFile]') return; } - const { password, region } = state; + const { password, region, baseUrl } = state; mapiClient({ token: { accessToken: password, }, region, + baseUrl, }); try { diff --git a/packages/cli/src/commands/migrations/run/__data__/.gitignore b/packages/cli/src/commands/migrations/run/__data__/.gitignore new file mode 100644 index 000000000..32c4ed701 --- /dev/null +++ b/packages/cli/src/commands/migrations/run/__data__/.gitignore @@ -0,0 +1 @@ +migrations/*/rollbacks diff --git a/packages/cli/src/commands/migrations/run/__data__/migrations/12345/migration-component.js b/packages/cli/src/commands/migrations/run/__data__/migrations/12345/migration-component.js new file mode 100644 index 000000000..320732ba8 --- /dev/null +++ b/packages/cli/src/commands/migrations/run/__data__/migrations/12345/migration-component.js @@ -0,0 +1,4 @@ +export default function (blok) { + blok.field = 'modified'; + return blok; +}; diff --git a/packages/cli/src/commands/migrations/run/actions.test.ts b/packages/cli/src/commands/migrations/run/actions.test.ts index 66bd30689..6011da0a8 100644 --- a/packages/cli/src/commands/migrations/run/actions.test.ts +++ b/packages/cli/src/commands/migrations/run/actions.test.ts @@ -2,14 +2,7 @@ import { vol } from 'memfs'; import { getMigrationFunction, readJavascriptFile, readMigrationFiles } from './actions'; import { FileSystemError } from '../../../utils/error'; -vi.mock('node:fs'); -vi.mock('node:fs/promises'); - describe('readJavascriptFile', () => { - beforeEach(() => { - vol.reset(); - }); - it('should read javascript file successfully', async () => { vol.fromJSON({ '/path/to/migrations/12345/migration-1.js': 'export default function (block) { return block; }', @@ -131,7 +124,6 @@ describe('readMigrationFiles', () => { describe('getMigrationFunction', () => { beforeEach(() => { - vol.reset(); vi.resetModules(); }); diff --git a/packages/cli/src/commands/migrations/run/index.integration.spec.ts b/packages/cli/src/commands/migrations/run/index.integration.spec.ts new file mode 100644 index 000000000..9193ed1d2 --- /dev/null +++ b/packages/cli/src/commands/migrations/run/index.integration.spec.ts @@ -0,0 +1,45 @@ +// Import the main components module first to ensure proper initialization +import '../index'; +import { expect, it, vi } from '../../../../../test-utils/src/vitest/test-utils'; +import { migrationsCommand } from '../command'; +import { konsola } from '../../../utils'; +import { canNotUpdateStory, hasStory } from '../../../../../test-utils/src/preconditions/stories-mapi'; +import { makeBlok, makeStory } from '../../../../../test-utils/src/preconditions/stories'; + +process.env.STORYBLOK_LOGIN = 'foo'; +process.env.STORYBLOK_TOKEN = 'Bearer foo.bar.baz'; +process.env.STORYBLOK_REGION = 'eu'; +process.env.STORYBLOK_BASE_URL = 'http://localhost:9000'; + +it('should handle dry run mode correctly', async ({ prepare, stubServer }) => { + process.env.STORYBLOK_BASE_URL = stubServer.baseURL; + const story = makeStory({ + content: makeBlok({ + field: 'original', + component: 'migration-component', + }), + }); + const spaceId = '12345'; + await prepare([ + hasStory({ spaceId, story }), + // If the update endpoint is called while the `dry-run` flag is enabled, + // the request will fail and the console output will mention the failed + // update. + canNotUpdateStory({ spaceId, storyId: story.id }), + ]); + using konsolaWarnSpy = vi.spyOn(konsola, 'warn'); + using konsolaInfoSpy = vi.spyOn(konsola, 'info'); + + // Run the command with dry run + await migrationsCommand.parseAsync(['node', 'test', 'run', '--space', spaceId, '--dry-run', '--path', './src/commands/migrations/run/__data__']); + + expect(konsolaWarnSpy).toHaveBeenCalledWith( + expect.stringContaining('DRY RUN MODE ENABLED: No changes will be made.'), + ); + expect(konsolaInfoSpy).toHaveBeenCalledWith( + expect.stringContaining('Migration Results: 1 stories updated, 0 stories skipped.'), + ); + expect(konsolaInfoSpy).toHaveBeenCalledWith( + expect.stringContaining('Update Results: 1 stories updated.'), + ); +}); diff --git a/packages/cli/src/commands/migrations/run/index.test.ts b/packages/cli/src/commands/migrations/run/index.test.ts index 495645519..f256b08f7 100644 --- a/packages/cli/src/commands/migrations/run/index.test.ts +++ b/packages/cli/src/commands/migrations/run/index.test.ts @@ -162,7 +162,7 @@ describe('migrations run command - streaming approach', () => { expect(fetchStories).toHaveBeenCalledWith( '12345', expect.objectContaining({ - per_page: 500, + per_page: 100, page: 1, story_only: true, }), @@ -227,7 +227,7 @@ describe('migrations run command - streaming approach', () => { expect(fetchStories).toHaveBeenCalledWith( '12345', expect.objectContaining({ - per_page: 500, + per_page: 100, page: 1, story_only: true, }), @@ -297,7 +297,7 @@ describe('migrations run command - streaming approach', () => { expect(fetchStories).toHaveBeenCalledWith( '12345', expect.objectContaining({ - per_page: 500, + per_page: 100, page: 1, story_only: true, }), @@ -370,7 +370,7 @@ describe('migrations run command - streaming approach', () => { expect(fetchStories).toHaveBeenCalledWith( '12345', expect.objectContaining({ - per_page: 500, + per_page: 100, page: 1, contain_component: 'migration-component', story_only: true, diff --git a/packages/cli/src/commands/migrations/run/index.ts b/packages/cli/src/commands/migrations/run/index.ts index b0f61542c..9f08ea81c 100644 --- a/packages/cli/src/commands/migrations/run/index.ts +++ b/packages/cli/src/commands/migrations/run/index.ts @@ -48,13 +48,14 @@ migrationsCommand.command('run [componentName]') return; } - const { password, region } = state; + const { password, region, baseUrl } = state; mapiClient({ token: { accessToken: password, }, region, + baseUrl, }); try { diff --git a/packages/cli/src/commands/migrations/run/streams/stories-stream.ts b/packages/cli/src/commands/migrations/run/streams/stories-stream.ts index 7621c7240..0100e5865 100644 --- a/packages/cli/src/commands/migrations/run/streams/stories-stream.ts +++ b/packages/cli/src/commands/migrations/run/streams/stories-stream.ts @@ -14,7 +14,7 @@ export async function* storiesIterator( onTotal?: (total: number) => void, ) { try { - let perPage = 500; + let perPage = 100; // Apply the same parameter transformations as fetchAllStoriesByComponent const transformedParams: StoriesQueryParams = { diff --git a/packages/cli/src/commands/user/actions.ts b/packages/cli/src/commands/user/actions.ts index 7b33c45ae..904e76e1f 100644 --- a/packages/cli/src/commands/user/actions.ts +++ b/packages/cli/src/commands/user/actions.ts @@ -7,13 +7,14 @@ import type { RegionCode } from '../../constants'; export type User = Users.User; -export const getUser = async (token: string, region: RegionCode) => { +export const getUser = async (token: string, region: RegionCode, baseUrl?: string) => { try { const client = mapiClient({ token: { accessToken: token, }, region, + baseUrl, }); const { data } = await client.users.me({ diff --git a/packages/cli/src/commands/user/index.test.ts b/packages/cli/src/commands/user/index.test.ts index 8e86b7c95..5bf476546 100644 --- a/packages/cli/src/commands/user/index.test.ts +++ b/packages/cli/src/commands/user/index.test.ts @@ -57,7 +57,7 @@ describe('userCommand', () => { vi.mocked(getUser).mockResolvedValue(mockResponse); await userCommand.parseAsync(['node', 'test']); - expect(getUser).toHaveBeenCalledWith('valid-token', 'eu'); + expect(getUser).toHaveBeenCalledWith('valid-token', 'eu', undefined); expect(konsola.ok).toHaveBeenCalledWith( `Hi ${chalk.bold('John Doe')}, you are currently logged in with ${chalk.hex('#45bfb9')(mockResponse.email)} on ${chalk.bold('eu')} region`, true, diff --git a/packages/cli/src/commands/user/index.ts b/packages/cli/src/commands/user/index.ts index 3c99e6441..0fa509337 100644 --- a/packages/cli/src/commands/user/index.ts +++ b/packages/cli/src/commands/user/index.ts @@ -27,12 +27,12 @@ export const userCommand = program verbose: !isVitest, }).start(`Fetching user info`); try { - const { password, region } = state; + const { password, region, baseUrl } = state; if (!password || !region) { throw new Error('No password or region found'); } - const user = await getUser(password, region); + const user = await getUser(password, region, baseUrl); if (user) { if (verbose) { diff --git a/packages/cli/src/creds.test.ts b/packages/cli/src/creds.test.ts index 56dd35652..99023b415 100644 --- a/packages/cli/src/creds.test.ts +++ b/packages/cli/src/creds.test.ts @@ -1,15 +1,5 @@ import { addCredentials, getCredentials, removeAllCredentials } from './creds'; import { vol } from 'memfs'; -import type { StoryblokCredentials } from './types'; -// tell vitest to use fs mock from __mocks__ folder -// this can be done in a setup file if fs should always be mocked -vi.mock('node:fs'); -vi.mock('node:fs/promises'); - -beforeEach(() => { - // reset the state of in-memory fs - vol.reset(); -}); describe('creds', async () => { describe('getCredentials', () => { @@ -24,9 +14,9 @@ describe('creds', async () => { }), }, '/temp'); - const credentials = await getCredentials('/temp/test/credentials.json') as StoryblokCredentials; + const credentials = await getCredentials('/temp/test/credentials.json'); - expect(credentials['api.storyblok.com']).toEqual({ + expect(credentials).toEqual({ login: 'julio.iglesias@storyblok.com', password: 'my_access_token', region: 'eu', @@ -35,6 +25,7 @@ describe('creds', async () => { it('should create a credentials.json file if it does not exist', async () => { const credentials = await getCredentials('/temp/test/nonexistent.json'); expect(credentials).toEqual(null); + expect(await vol.promises.readFile('/temp/test/nonexistent.json', 'utf-8')).toEqual('{}'); }); }); diff --git a/packages/cli/src/creds.ts b/packages/cli/src/creds.ts index d42e46c33..b006b8558 100644 --- a/packages/cli/src/creds.ts +++ b/packages/cli/src/creds.ts @@ -3,8 +3,34 @@ import { join } from 'node:path'; import { FileSystemError, handleFileSystemError } from './utils'; import { getStoryblokGlobalPath, readFile, saveToFile } from './utils/filesystem'; import type { StoryblokCredentials } from './types'; +import { type RegionCode, regionCodes } from './constants'; -export const getCredentials = async (filePath = join(getStoryblokGlobalPath(), 'credentials.json')): Promise => { +function isRegionCode(value: unknown): value is RegionCode { + return regionCodes.includes(value as RegionCode); +} + +function toRegionCode(value: unknown) { + if (!value) { + return undefined; + } + + if (!isRegionCode(value)) { + throw new Error(`Invalid region "${value}", allowed regions: ${regionCodes.join(', ')}`); + } + + return value; +} + +function getEnvCredentials(): Partial { + return { + login: process.env.STORYBLOK_LOGIN || process.env.TRAVIS_STORYBLOK_LOGIN, + password: process.env.STORYBLOK_TOKEN || process.env.TRAVIS_STORYBLOK_TOKEN, + region: toRegionCode(process.env.STORYBLOK_REGION || process.env.TRAVIS_STORYBLOK_REGION), + baseUrl: process.env.STORYBLOK_BASE_URL || process.env.TRAVIS_STORYBLOK_BASE_URL, + }; +} + +const getConfigCredentials = async (filePath: string): Promise | null> => { try { await access(filePath); const content = await readFile(filePath); @@ -15,7 +41,7 @@ export const getCredentials = async (filePath = join(getStoryblokGlobalPath(), ' return null; } - return parsedContent; + return Object.values(parsedContent)[0] as Partial; } catch (error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') { @@ -28,6 +54,30 @@ export const getCredentials = async (filePath = join(getStoryblokGlobalPath(), ' } }; +function isLoggedIn(credentials: Partial | null) { + return Boolean(credentials && credentials.login && credentials.password && credentials.region); +} + +export function isEnvLogin() { + return isLoggedIn(getEnvCredentials()); +} + +export const getCredentials = async (filePath = join(getStoryblokGlobalPath(), 'credentials.json')): Promise => { + const credentialsEnv = getEnvCredentials(); + const credentialsConfig = await getConfigCredentials(filePath); + const credentials = { + login: credentialsEnv.login || credentialsConfig?.login, + password: credentialsEnv.password || credentialsConfig?.password, + region: toRegionCode(credentialsEnv.region || credentialsConfig?.region), + baseUrl: credentialsEnv.baseUrl || credentialsConfig?.baseUrl, + }; + if (!credentials.login || !credentials.password || !isRegionCode(credentials.region)) { + return null; + } + + return credentials as StoryblokCredentials; +}; + export const addCredentials = async ({ filePath = join(getStoryblokGlobalPath(), 'credentials.json'), machineName, @@ -36,7 +86,7 @@ export const addCredentials = async ({ region, }: Record) => { const credentials = { - ...await getCredentials(filePath), + ...await getConfigCredentials(filePath), [machineName]: { login, password, diff --git a/packages/cli/src/session.test.ts b/packages/cli/src/session.test.ts index 29846ee31..ede82e6e7 100644 --- a/packages/cli/src/session.test.ts +++ b/packages/cli/src/session.test.ts @@ -1,35 +1,30 @@ -// session.test.ts +import { vol } from 'memfs'; +import { beforeEach, describe, expect, it } from 'vitest'; +import { join } from 'node:path'; import { session } from './session'; - -import { getCredentials } from './creds'; -import type { Mock } from 'vitest'; - -vi.mock('./creds', () => ({ - getCredentials: vi.fn(), -})); - -const mockedGetCredentials = getCredentials as Mock; +import { getStoryblokGlobalPath } from './utils/filesystem'; describe('session', () => { - beforeEach(() => { - vi.resetAllMocks(); - vi.clearAllMocks(); - }); describe('session initialization with json', () => { it('should initialize session with json credentials', async () => { - mockedGetCredentials.mockReturnValue({ - 'api.storyblok.com': { - login: 'test_login', - password: 'test_token', - region: 'test_region', + vol.fromJSON( + { + [join(getStoryblokGlobalPath(), 'credentials.json')]: JSON.stringify({ + 'mapi.storyblok.com': { + login: 'test_login', + password: 'test_token', + region: 'eu', + }, + }), }, - }); + ); + const userSession = session(); await userSession.initializeSession(); expect(userSession.state.isLoggedIn).toBe(true); expect(userSession.state.login).toBe('test_login'); expect(userSession.state.password).toBe('test_token'); - expect(userSession.state.region).toBe('test_region'); + expect(userSession.state.region).toBe('eu'); }); }); describe('session initialization with environment variables', () => { @@ -46,27 +41,27 @@ describe('session', () => { it('should initialize session from STORYBLOK_ environment variables', async () => { process.env.STORYBLOK_LOGIN = 'test_login'; process.env.STORYBLOK_TOKEN = 'test_token'; - process.env.STORYBLOK_REGION = 'test_region'; + process.env.STORYBLOK_REGION = 'eu'; const userSession = session(); await userSession.initializeSession(); expect(userSession.state.isLoggedIn).toBe(true); expect(userSession.state.login).toBe('test_login'); expect(userSession.state.password).toBe('test_token'); - expect(userSession.state.region).toBe('test_region'); + expect(userSession.state.region).toBe('eu'); }); it('should initialize session from TRAVIS_STORYBLOK_ environment variables', async () => { process.env.TRAVIS_STORYBLOK_LOGIN = 'test_login'; process.env.TRAVIS_STORYBLOK_TOKEN = 'test_token'; - process.env.TRAVIS_STORYBLOK_REGION = 'test_region'; + process.env.TRAVIS_STORYBLOK_REGION = 'eu'; const userSession = session(); await userSession.initializeSession(); expect(userSession.state.isLoggedIn).toBe(true); expect(userSession.state.login).toBe('test_login'); expect(userSession.state.password).toBe('test_token'); - expect(userSession.state.region).toBe('test_region'); + expect(userSession.state.region).toBe('eu'); }); }); }); diff --git a/packages/cli/src/session.ts b/packages/cli/src/session.ts index 583253998..5fb87f32d 100644 --- a/packages/cli/src/session.ts +++ b/packages/cli/src/session.ts @@ -1,13 +1,14 @@ // session.ts import { type RegionCode, regionsDomain } from './constants'; -import { addCredentials, getCredentials } from './creds'; +import { addCredentials, getCredentials, isEnvLogin } from './creds'; export interface SessionState { isLoggedIn: boolean; login?: string; password?: string; region?: RegionCode; - envLogin?: boolean; + baseUrl?: string; + envLogin: boolean; } let sessionInstance: ReturnType | null = null; @@ -15,59 +16,23 @@ let sessionInstance: ReturnType | null = null; function createSession() { const state: SessionState = { isLoggedIn: false, + envLogin: false, }; async function initializeSession() { - // First, check for environment variables - const envCredentials = getEnvCredentials(); - if (envCredentials) { - state.isLoggedIn = true; - state.login = envCredentials.login; - state.password = envCredentials.password; - state.region = envCredentials.region as RegionCode; - state.envLogin = true; - return; - } - - // If no environment variables, fall back to .storyblok/credentials.json const credentials = await getCredentials(); - if (credentials) { - // Todo: evaluate this in future when we want to support multiple regions - const creds = Object.values(credentials)[0]; - state.isLoggedIn = true; - state.login = creds.login; - state.password = creds.password; - state.region = creds.region as RegionCode; - } - else { - // No credentials found; set state to logged out - state.isLoggedIn = false; - state.login = undefined; - state.password = undefined; - state.region = undefined; - } - state.envLogin = false; - } - - function getEnvCredentials() { - const envLogin = process.env.STORYBLOK_LOGIN || process.env.TRAVIS_STORYBLOK_LOGIN; - const envPassword = process.env.STORYBLOK_TOKEN || process.env.TRAVIS_STORYBLOK_TOKEN; - const envRegion = process.env.STORYBLOK_REGION || process.env.TRAVIS_STORYBLOK_REGION; - - if (envLogin && envPassword && envRegion) { - return { - login: envLogin, - password: envPassword, - region: envRegion, - }; - } - return null; + state.isLoggedIn = Boolean(credentials); + state.envLogin = isEnvLogin(); + state.login = credentials?.login; + state.password = credentials?.password; + state.region = credentials?.region; + state.baseUrl = credentials?.baseUrl; } async function persistCredentials(region: RegionCode) { if (state.isLoggedIn && state.login && state.password && state.region) { await addCredentials({ - machineName: regionsDomain[region] || 'mapi.storyblok.com', + machineName: regionsDomain[region], login: state.login, password: state.password, region: state.region, diff --git a/packages/cli/src/types/index.ts b/packages/cli/src/types/index.ts index d9b4ea868..91379f0fe 100644 --- a/packages/cli/src/types/index.ts +++ b/packages/cli/src/types/index.ts @@ -66,4 +66,5 @@ export interface StoryblokCredentials { login: string; password: string; region: RegionCode; + baseUrl?: string; } diff --git a/packages/cli/src/utils/filesystem.test.ts b/packages/cli/src/utils/filesystem.test.ts index ded290522..a6a7520c1 100644 --- a/packages/cli/src/utils/filesystem.test.ts +++ b/packages/cli/src/utils/filesystem.test.ts @@ -3,15 +3,8 @@ import { vol } from 'memfs'; import { appendToFile, getComponentNameFromFilename, getStoryblokGlobalPath, resolvePath, sanitizeFilename, saveToFile } from './filesystem'; import { join, resolve } from 'node:path'; -// tell vitest to use fs mock from __mocks__ folder -// this can be done in a setup file if fs should always be mocked -vi.mock('node:fs'); -vi.mock('node:fs/promises'); - beforeEach(() => { vi.clearAllMocks(); - // reset the state of in-memory fs - vol.reset(); }); describe('filesystem utils', async () => { diff --git a/packages/cli/test/setup.ts b/packages/cli/test/setup.ts new file mode 100644 index 000000000..cb055b631 --- /dev/null +++ b/packages/cli/test/setup.ts @@ -0,0 +1,9 @@ +import { beforeEach, vi } from 'vitest'; +import { vol } from 'memfs'; + +vi.mock('node:fs'); +vi.mock('node:fs/promises'); + +beforeEach(() => { + vol.reset(); +}); diff --git a/packages/cli/vitest.config.ts b/packages/cli/vitest.config.ts index cc8a690d7..973ed3e68 100644 --- a/packages/cli/vitest.config.ts +++ b/packages/cli/vitest.config.ts @@ -3,8 +3,6 @@ import { defineConfig } from 'vite'; export default defineConfig({ test: { - globals: true, - // ... Specify options here. coverage: { reporter: ['text', 'json', 'html'], }, @@ -12,5 +10,25 @@ export default defineConfig({ NO_COLOR: '1', FORCE_COLOR: '0', }, + teardownTimeout: 45_000, + projects: [ + { + test: { + globals: true, + setupFiles: ['./test/setup.ts'], + include: ['**/*.{spec,test}.ts', '!**/*.integration.spec.ts'], + name: 'unit', + environment: 'node', + }, + }, + { + test: { + include: ['**/*.integration.spec.ts'], + name: 'integration', + environment: 'node', + testTimeout: 30_000, + }, + }, + ], }, }); diff --git a/packages/js-client/package.json b/packages/js-client/package.json index 68de0ecce..0f12f5f2e 100644 --- a/packages/js-client/package.json +++ b/packages/js-client/package.json @@ -47,6 +47,7 @@ "test:unit:ci": "vitest run", "test:unit:ui": "vitest --ui", "test:e2e": "vitest run -c vitest.config.e2e.ts", + "test:integration": "vitest run --project integration", "lint": "eslint .", "lint:fix": "eslint . --fix", "playground": "pnpm run --filter ./playground/vanilla dev", @@ -58,6 +59,8 @@ "devDependencies": { "@arethetypeswrong/core": "^0.18.2", "@storyblok/eslint-config": "workspace:*", + "@storyblok/openapi": "workspace:*", + "@storyblok/test-utils": "workspace:*", "@tsconfig/recommended": "^1.0.8", "@vitest/coverage-v8": "^3.1.3", "@vitest/ui": "^3.1.3", diff --git a/packages/js-client/specmatic.json b/packages/js-client/specmatic.json new file mode 100644 index 000000000..ade52632e --- /dev/null +++ b/packages/js-client/specmatic.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "contracts": [ + { + "consumes": [ + "./node_modules/@storyblok/openapi/dist/mapi/stories.yaml", + "./node_modules/@storyblok/openapi/dist/mapi/users.yaml" + ] + } + ] +} diff --git a/packages/js-client/test/specs/mapi.integration.spec.ts b/packages/js-client/test/specs/mapi.integration.spec.ts new file mode 100644 index 000000000..610b980fb --- /dev/null +++ b/packages/js-client/test/specs/mapi.integration.spec.ts @@ -0,0 +1,177 @@ +import StoryblokClient from 'storyblok-js-client'; +// TODO package +import { describe, expect, it } from '../../../test-utils/src/vitest/test-utils'; +import { hasStories } from '../../../test-utils/src/preconditions/stories-mapi'; +import { makeStory } from '../../../test-utils/src/preconditions/stories'; + +const makeMapi = ({ baseURL }: { baseURL: string }) => new StoryblokClient({ + oauthToken: 'Bearer super-valid-token', + endpoint: `${baseURL}/v1`, +}); + +describe('getAll()', () => { + it('should return a list of stories', async ({ prepare, stubServer }) => { + const mapi = makeMapi(stubServer); + await prepare(hasStories({ spaceId: '123', stories: [] })); + const resultEmpty = await mapi.getAll( + `spaces/123/stories`, + ); + expect(resultEmpty.length).toBe(0); + + const story = makeStory({ name: 'foo bar' }); + await prepare(hasStories({ spaceId: '123', stories: [story] })); + const result = await mapi.getAll( + `spaces/123/stories`, + ); + expect(result).toEqual([story]); + }); +}); + +// TODO +// import StoryblokClient from 'storyblok-js-client'; +// import { beforeEach, describe, expect, it } from 'vitest'; + +// describe('StoryblokClient', () => { +// let client: StoryblokClient; + +// beforeEach(() => { +// // Setup default mocks +// client = new StoryblokClient({ +// accessToken: process.env.VITE_ACCESS_TOKEN, +// cache: { type: 'memory', clear: 'auto' }, +// }); +// }); +// // TODO: Uncomment when we have a valid token +// /* if (process.env.VITE_OAUTH_TOKEN) { +// describe('management API', () => { +// const spaceId = process.env.VITE_SPACE_ID +// describe('should return all spaces', async () => { +// const StoryblokManagement = new StoryblokClient({ +// oauthToken: process.env.VITE_OAUTH_TOKEN, +// }) +// const result = await StoryblokManagement.getAll( +// `spaces/${spaceId}/stories` +// ) +// expect(result.length).toBeGreaterThan(0) +// }) +// }) +// } */ + +// describe('get function', () => { +// it('get(\'cdn/spaces/me\') should return the space information', async () => { +// const { data } = await client.get('cdn/spaces/me'); +// expect(data.space.id).toBe(Number(process.env.VITE_SPACE_ID)); +// }); + +// it('get(\'cdn/stories\') should return all stories', async () => { +// const { data } = await client.get('cdn/stories'); +// expect(data.stories.length).toBeGreaterThan(0); +// }); + +// it('get(\'cdn/stories/testcontent-0\' should return the specific story', async () => { +// const { data } = await client.get('cdn/stories/testcontent-0'); +// expect(data.story.slug).toBe('testcontent-0'); +// }); + +// it('get(\'cdn/stories\' { starts_with: testcontent-0 } should return the specific story', async () => { +// const { data } = await client.get('cdn/stories', { +// starts_with: 'testcontent-0', +// }); +// expect(data.stories.length).toBe(1); +// }); + +// it('get(\'cdn/stories/testcontent-draft\', { version: \'draft\' }) should return the specific story draft', async () => { +// const { data } = await client.get('cdn/stories/testcontent-draft', { +// version: 'draft', +// }); +// expect(data.story.slug).toBe('testcontent-draft'); +// }); + +// it('get(\'cdn/stories/testcontent-0\', { version: \'published\' }) should return the specific story published', async () => { +// const { data } = await client.get('cdn/stories/testcontent-0', { +// version: 'published', +// }); +// expect(data.story.slug).toBe('testcontent-0'); +// }); + +// it('cdn/stories/testcontent-0 should resolve author relations', async () => { +// const { data } = await client.get('cdn/stories/testcontent-0', { +// resolve_relations: 'root.author', +// }); + +// expect(data.story.content.author[0].slug).toBe('edgar-allan-poe'); +// }); + +// it('get(\'cdn/stories\', { by_slugs: \'folder/*\' }) should return the specific story', async () => { +// const { data } = await client.get('cdn/stories', { +// by_slugs: 'folder/*', +// }); +// expect(data.stories.length).toBeGreaterThan(0); +// }); +// }); + +// describe('getAll function', () => { +// it('getAll(\'cdn/stories\') should return all stories', async () => { +// const result = await client.getAll('cdn/stories', {}); +// expect(result.length).toBeGreaterThan(0); +// }); + +// it('getAll(\'cdn/stories\') should return all stories with filtered results', async () => { +// const result = await client.getAll('cdn/stories', { +// starts_with: 'testcontent-0', +// }); +// expect(result.length).toBe(1); +// }); + +// it('getAll(\'cdn/stories\', filter_query: { __or: [{ category: { any_in_array: \'Category 1\' } }, { category: { any_in_array: \'Category 2\' } }]}) should return all stories with the specific filter applied', async () => { +// const result = await client.getAll('cdn/stories', { +// filter_query: { +// __or: [ +// { category: { any_in_array: 'Category 1' } }, +// { category: { any_in_array: 'Category 2' } }, +// ], +// }, +// }); +// expect(result.length).toBeGreaterThan(0); +// }); + +// it('getAll(\'cdn/stories\', {by_slugs: \'folder/*\'}) should return all stories with the specific filter applied', async () => { +// const result = await client.getAll('cdn/stories', { +// by_slugs: 'folder/*', +// }); +// expect(result.length).toBeGreaterThan(0); +// }); + +// it('getAll(\'cdn/links\') should return all links', async () => { +// const result = await client.getAll('cdn/links', {}); +// expect(result.length).toBeGreaterThan(0); +// }); +// }); + +// describe('caching', () => { +// it('get(\'cdn/spaces/me\') should not be cached', async () => { +// const provider = client.cacheProvider(); +// await provider.flush(); +// await client.get('cdn/spaces/me'); +// expect(Object.values(provider.getAll()).length).toBe(0); +// }); + +// it('get(\'cdn/stories\') should be cached when is a published version', async () => { +// const cacheVersion = client.cacheVersion(); + +// await client.get('cdn/stories'); + +// expect(cacheVersion).not.toBe(undefined); + +// const newCacheVersion = client.cacheVersion(); + +// await client.get('cdn/stories'); + +// expect(newCacheVersion).toBe(client.cacheVersion()); + +// await client.get('cdn/stories'); + +// expect(newCacheVersion).toBe(client.cacheVersion()); +// }); +// }); +// }); diff --git a/packages/js-client/tests/utils.ts b/packages/js-client/test/utils.ts similarity index 100% rename from packages/js-client/tests/utils.ts rename to packages/js-client/test/utils.ts diff --git a/packages/js-client/tests/api/index.e2e.ts b/packages/js-client/tests/api/index.e2e.ts deleted file mode 100644 index 347358f55..000000000 --- a/packages/js-client/tests/api/index.e2e.ts +++ /dev/null @@ -1,147 +0,0 @@ -import StoryblokClient from 'storyblok-js-client'; -import { beforeEach, describe, expect, it } from 'vitest'; - -describe('StoryblokClient', () => { - let client: StoryblokClient; - - beforeEach(() => { - // Setup default mocks - client = new StoryblokClient({ - accessToken: process.env.VITE_ACCESS_TOKEN, - cache: { type: 'memory', clear: 'auto' }, - }); - }); - // TODO: Uncomment when we have a valid token - /* if (process.env.VITE_OAUTH_TOKEN) { - describe('management API', () => { - const spaceId = process.env.VITE_SPACE_ID - describe('should return all spaces', async () => { - const StoryblokManagement = new StoryblokClient({ - oauthToken: process.env.VITE_OAUTH_TOKEN, - }) - const result = await StoryblokManagement.getAll( - `spaces/${spaceId}/stories` - ) - expect(result.length).toBeGreaterThan(0) - }) - }) - } */ - - describe('get function', () => { - it('get(\'cdn/spaces/me\') should return the space information', async () => { - const { data } = await client.get('cdn/spaces/me'); - expect(data.space.id).toBe(Number(process.env.VITE_SPACE_ID)); - }); - - it('get(\'cdn/stories\') should return all stories', async () => { - const { data } = await client.get('cdn/stories'); - expect(data.stories.length).toBeGreaterThan(0); - }); - - it('get(\'cdn/stories/testcontent-0\' should return the specific story', async () => { - const { data } = await client.get('cdn/stories/testcontent-0'); - expect(data.story.slug).toBe('testcontent-0'); - }); - - it('get(\'cdn/stories\' { starts_with: testcontent-0 } should return the specific story', async () => { - const { data } = await client.get('cdn/stories', { - starts_with: 'testcontent-0', - }); - expect(data.stories.length).toBe(1); - }); - - it('get(\'cdn/stories/testcontent-draft\', { version: \'draft\' }) should return the specific story draft', async () => { - const { data } = await client.get('cdn/stories/testcontent-draft', { - version: 'draft', - }); - expect(data.story.slug).toBe('testcontent-draft'); - }); - - it('get(\'cdn/stories/testcontent-0\', { version: \'published\' }) should return the specific story published', async () => { - const { data } = await client.get('cdn/stories/testcontent-0', { - version: 'published', - }); - expect(data.story.slug).toBe('testcontent-0'); - }); - - it('cdn/stories/testcontent-0 should resolve author relations', async () => { - const { data } = await client.get('cdn/stories/testcontent-0', { - resolve_relations: 'root.author', - }); - - expect(data.story.content.author[0].slug).toBe('edgar-allan-poe'); - }); - - it('get(\'cdn/stories\', { by_slugs: \'folder/*\' }) should return the specific story', async () => { - const { data } = await client.get('cdn/stories', { - by_slugs: 'folder/*', - }); - expect(data.stories.length).toBeGreaterThan(0); - }); - }); - - describe('getAll function', () => { - it('getAll(\'cdn/stories\') should return all stories', async () => { - const result = await client.getAll('cdn/stories', {}); - expect(result.length).toBeGreaterThan(0); - }); - - it('getAll(\'cdn/stories\') should return all stories with filtered results', async () => { - const result = await client.getAll('cdn/stories', { - starts_with: 'testcontent-0', - }); - expect(result.length).toBe(1); - }); - - it('getAll(\'cdn/stories\', filter_query: { __or: [{ category: { any_in_array: \'Category 1\' } }, { category: { any_in_array: \'Category 2\' } }]}) should return all stories with the specific filter applied', async () => { - const result = await client.getAll('cdn/stories', { - filter_query: { - __or: [ - { category: { any_in_array: 'Category 1' } }, - { category: { any_in_array: 'Category 2' } }, - ], - }, - }); - expect(result.length).toBeGreaterThan(0); - }); - - it('getAll(\'cdn/stories\', {by_slugs: \'folder/*\'}) should return all stories with the specific filter applied', async () => { - const result = await client.getAll('cdn/stories', { - by_slugs: 'folder/*', - }); - expect(result.length).toBeGreaterThan(0); - }); - - it('getAll(\'cdn/links\') should return all links', async () => { - const result = await client.getAll('cdn/links', {}); - expect(result.length).toBeGreaterThan(0); - }); - }); - - describe('caching', () => { - it('get(\'cdn/spaces/me\') should not be cached', async () => { - const provider = client.cacheProvider(); - await provider.flush(); - await client.get('cdn/spaces/me'); - expect(Object.values(provider.getAll()).length).toBe(0); - }); - - it('get(\'cdn/stories\') should be cached when is a published version', async () => { - const cacheVersion = client.cacheVersion(); - - await client.get('cdn/stories'); - - expect(cacheVersion).not.toBe(undefined); - - const newCacheVersion = client.cacheVersion(); - - await client.get('cdn/stories'); - - expect(newCacheVersion).toBe(client.cacheVersion()); - - await client.get('cdn/stories'); - - expect(newCacheVersion).toBe(client.cacheVersion()); - }); - }); -}); diff --git a/packages/js-client/vitest.config.e2e.ts b/packages/js-client/vitest.config.e2e.ts deleted file mode 100644 index bb66a111a..000000000 --- a/packages/js-client/vitest.config.e2e.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { defineConfig } from 'vite'; -import path from 'node:path'; - -export default defineConfig({ - test: { - include: ['./tests/**/*.e2e.ts'], - }, - resolve: { - alias: { - 'storyblok-js-client': path.resolve(__dirname, 'dist'), - }, - }, -}); diff --git a/packages/js-client/vitest.config.ts b/packages/js-client/vitest.config.ts new file mode 100644 index 000000000..8d72ae9e2 --- /dev/null +++ b/packages/js-client/vitest.config.ts @@ -0,0 +1,30 @@ +import { defineConfig } from 'vitest/config'; +import path from 'node:path'; + +export default defineConfig({ + test: { + teardownTimeout: 45_000, + projects: [ + { + test: { + include: ['**/*.spec.ts', '!**/*.integration.spec.ts'], + name: 'unit', + environment: 'node', + }, + }, + { + test: { + include: ['**/*.integration.spec.ts'], + name: 'integration', + environment: 'node', + testTimeout: 30_000, + }, + }, + ], + }, + resolve: { + alias: { + 'storyblok-js-client': path.resolve(__dirname, 'dist'), + }, + }, +}); diff --git a/packages/mapi-client/src/client/client.ts b/packages/mapi-client/src/client/client.ts index 326c8d2cf..33bd67aef 100644 --- a/packages/mapi-client/src/client/client.ts +++ b/packages/mapi-client/src/client/client.ts @@ -37,7 +37,7 @@ export const createClient = (config: Config): Client => { ..._config, ...options, fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, - headers: mergeHeaders(_config.headers, options.headers), + headers: options.headers ? mergeHeaders(_config.headers, options.headers) : _config.headers, }; // If the baseUrl is not set and we have a space_id, we can attempt to infer the region diff --git a/packages/mapi-client/src/index.ts b/packages/mapi-client/src/index.ts index 183175cec..d5e71dae4 100644 --- a/packages/mapi-client/src/index.ts +++ b/packages/mapi-client/src/index.ts @@ -1,7 +1,7 @@ // Import generated SDKs with shared client support import { createClient } from './client'; import type { Client } from './client/types'; -import { getManagementBaseUrl, type Region } from '@storyblok/region-helper'; +import { type Region } from '@storyblok/region-helper'; import { sdkRegistry, SdkRegistryInstance } from './sdk-registry.generated'; type PersonalAccessToken = { @@ -96,7 +96,7 @@ function createClientInstance( config: ManagementApiClientConfig ): Client { const { token, region = "eu", baseUrl, headers = {}, throwOnError = false } = config; - + return createClient({ baseUrl, region, diff --git a/packages/openapi/redocly.yaml b/packages/openapi/redocly.yaml index 5ad4294d1..c92fd5ef4 100644 --- a/packages/openapi/redocly.yaml +++ b/packages/openapi/redocly.yaml @@ -45,6 +45,10 @@ apis: root: resources/mapi/users/main.yaml output: ./dist/mapi/users.yaml title: Users + stories-capi: + root: resources/capi/stories/main.yaml + output: ./dist/capi/stories.yaml + title: Stories # Linting rules diff --git a/packages/openapi/resources/capi/shared/security-schemes.yaml b/packages/openapi/resources/capi/shared/security-schemes.yaml new file mode 100644 index 000000000..a37391f5b --- /dev/null +++ b/packages/openapi/resources/capi/shared/security-schemes.yaml @@ -0,0 +1,10 @@ +# Storyblok Management API Security Schemes +# Based on: https://www.storyblok.com/docs/api/management/getting-started/authentication + +securitySchemes: + # Personal Access Token - obtained from Storyblok UI + # Used without "Bearer" keyword in Authorization header + PersonalAccessToken: + type: apiKey + in: query + name: token diff --git a/packages/openapi/resources/capi/shared/security.yaml b/packages/openapi/resources/capi/shared/security.yaml new file mode 100644 index 000000000..6426a3b3a --- /dev/null +++ b/packages/openapi/resources/capi/shared/security.yaml @@ -0,0 +1,5 @@ +# Storyblok Content Delivery API Security Schemes +# Based on: https://www.storyblok.com/docs/api/content-delivery/v2/getting-started/authentication + +# Personal Access Token - used without "Bearer" keyword +- PersonalAccessToken: [] diff --git a/packages/openapi/resources/capi/shared/servers.yaml b/packages/openapi/resources/capi/shared/servers.yaml new file mode 100644 index 000000000..56750129c --- /dev/null +++ b/packages/openapi/resources/capi/shared/servers.yaml @@ -0,0 +1,10 @@ +- url: https://api.storyblok.com + description: Base URL for spaces created in the EU +- url: https://api-us.storyblok.com + description: Base URL for spaces created in the US +- url: https://api-ca.storyblok.com + description: Base URL for spaces created in Canada +- url: https://api-ap.storyblok.com + description: Base URL for spaces created in Australia +- url: https://app.storyblok.cn + description: Base URL for spaces created in China diff --git a/packages/openapi/resources/capi/stories/main.yaml b/packages/openapi/resources/capi/stories/main.yaml new file mode 100644 index 000000000..164e95222 --- /dev/null +++ b/packages/openapi/resources/capi/stories/main.yaml @@ -0,0 +1,53 @@ +openapi: 3.0.0 +info: + title: Storyblok Stories API + version: 1.0.0 + description: API for delivering Storyblok stories +servers: + $ref: ../shared/servers.yaml +security: + $ref: ../shared/security.yaml +paths: + /v1/cdn/stories/{slug}: + get: + operationId: get + summary: Retrieve One Story + parameters: + - name: slug + in: path + required: true + schema: + type: string + - name: version + in: query + required: false + schema: + type: string + enum: + - published + - draft + default: published + responses: + '200': + description: Story details + content: + application/json: + schema: + type: object + properties: + story: + $ref: '#/components/schemas/story' + '400': + description: Bad request + '401': + description: Unauthorized + '404': + description: Story not found +components: + securitySchemes: + $ref: ../shared/security-schemes.yaml#/securitySchemes + schemas: + story: + $ref: ./schemas/story.yaml + blok: + $ref: ./schemas/blok.yaml diff --git a/packages/openapi/resources/capi/stories/schemas/blok.yaml b/packages/openapi/resources/capi/stories/schemas/blok.yaml new file mode 100644 index 000000000..760a90e12 --- /dev/null +++ b/packages/openapi/resources/capi/stories/schemas/blok.yaml @@ -0,0 +1,27 @@ + +type: object +description: Generic component content structure that can be extended for specific component types. Supports deeply nested components in arrays and objects. Additional fields can be strings, numbers, booleans, objects, or arrays. +required: + - _uid + - component +properties: + _uid: + type: string + format: uuid + description: Unique identifier for the content + component: + type: string + description: The story type's technical name (e.g., 'page', 'teaser', 'grid', 'feature', etc.) + _editable: + type: string + description: Storyblok editor markup for inline editing +additionalProperties: + oneOf: + - type: string + - type: number + - type: boolean + - type: array + items: + - $ref: '#' + - type: object + additionalProperties: true diff --git a/packages/openapi/resources/capi/stories/schemas/story.yaml b/packages/openapi/resources/capi/stories/schemas/story.yaml new file mode 100644 index 000000000..2c13eee2a --- /dev/null +++ b/packages/openapi/resources/capi/stories/schemas/story.yaml @@ -0,0 +1,284 @@ + + type: object + description: A Storyblok story object representing a content entry + required: + - id + properties: + id: + type: integer + description: Numeric id of the story + readOnly: true + name: + type: string + description: The complete name provided for the story + parent_id: + type: integer + description: ID of the parent folder + group_id: + type: string + format: uuid + description: Group ID (UUID string), shared between stories defined as alternates + alternates: + type: array + description: An array containing objects that provide basic data of the stories defined as alternates of the current story + items: + type: object + properties: + id: + type: integer + description: The numeric ID + name: + type: string + description: The complete name provided for the story + slug: + type: string + description: The slug specific for the story + published: + type: boolean + description: true if a story is currently published, even if it has unpublished changes + full_slug: + type: string + description: The full slug of the story, combining the parent folder(s) and the designated story slug + is_folder: + type: boolean + description: true if the instance constitutes a folder + created_at: + type: string + format: date-time + description: Creation date yyyy-MM-dd'T'HH:mm:ssZ + deleted_at: + type: string + format: date-time + nullable: true + description: Deleted date YYYY-mm-dd HH:MM + sort_by_date: + type: string + format: date + nullable: true + description: Date defined in the story's entry configuration YYYY-mm-dd + tag_list: + type: array + description: Array of tag names + items: + type: string + updated_at: + type: string + format: date-time + description: Latest update date yyyy-MM-dd'T'HH:mm:ssZ + published_at: + type: string + format: date-time + description: Latest publishing date yyyy-MM-dd'T'HH:mm:ssZ + nullable: true + uuid: + type: string + format: uuid + description: Generated UUID string + readOnly: true + is_folder: + type: boolean + description: true if the instance constitutes a folder + content: + $ref: ./blok.yaml + description: An object containing the field data associated with the specific story type's specific content structure. Can contain deeply nested components in arrays and objects. Also includes a component property with the story type's technical name. + published: + type: boolean + description: true if a story is currently published, even if it has unpublished changes + slug: + type: string + description: The slug specific for the story + path: + type: string + nullable: true + description: Value of the real path defined in the story's entry configuration (usually, this value is only required for Storyblok's Visual Editor) + full_slug: + type: string + description: The full slug of the story, combining the parent folder(s) and the designated story slug + default_full_slug: + type: string + nullable: true + default_root: + type: string + nullable: true + description: Component name which will be used as default content type for this folders entries + disable_fe_editor: + type: boolean + description: Is side by side editor disabled for all entries in folder + parent: + type: object + description: Essential parent information as object (resolved from parent_id) + additionalProperties: true + is_startpage: + type: boolean + description: true if the story is defined as root for the folder + unpublished_changes: + type: boolean + description: Story has unpublished changes; saved but not published + meta_data: + type: object + nullable: true + description: Object to store non-editable data that is exclusively maintained with the Management API + imported_at: + type: string + format: date-time + nullable: true + description: Latest import date YYYY-mm-dd HH:MM + preview_token: + type: object + description: Preview token + properties: + token: + type: string + description: The token passed to the editor as preview parameter to allow edit mode verification + timestamp: + type: string + description: Timestamp passed to the editor as preview parameter to allow edit mode verification + pinned: + type: boolean + description: To pin the story in the toolbar + breadcrumbs: + type: array + description: Array of resolved subset of link objects (one per path segment / parent) + items: + type: object + properties: + id: + type: integer + description: Story ID + name: + type: string + description: The complete name provided for the story + parent_id: + type: integer + description: ID of the parent folder + disable_fe_editor: + type: boolean + description: Is side by side editor disabled for all entries in folder + path: + type: string + description: Value of the real path defined in the story's entry configuration + slug: + type: string + description: The slug specific for the story + translated_slugs: + type: array + description: Array of translated slug objects (if the app Translatable Slugs is installed) + nullable: true + items: + type: object + properties: + story_id: + type: integer + description: ID of the story + lang: + type: string + description: Language code of the current language + slug: + type: string + description: The slug specific for the story + name: + type: string + description: The complete name provided for the story + published: + type: boolean + description: true if a story is currently published, even if it has unpublished changes + first_published_at: + type: string + format: date-time + description: First publishing date yyyy-MM-dd'T'HH:mm:ssZ + nullable: true + last_author: + type: object + description: Last author + properties: + id: + type: integer + description: Last author user object numeric id + userid: + type: string + description: Last author userid/username + friendly_name: + type: string + description: Friendly name of last author + last_author_id: + type: integer + description: Id of the last Author + translated_slugs: + type: array + description: Array of translated slug objects (if the app Translatable Slugs is installed) + items: + type: object + properties: + story_id: + type: integer + description: ID of the story + lang: + type: string + description: Language code of the current language + slug: + type: string + description: The slug specific for the story + name: + type: string + description: The complete name provided for the story + published: + type: boolean + description: true if a story is currently published, even if it has unpublished changes + translated_slugs_attributes: + type: array + description: Array of translated slug attributes objects (if the app Translatable Slugs is installed) to change translated slugs when creating or updating a story + items: + type: object + properties: + id: + type: integer + description: The numeric ID + lang: + type: string + description: Language code of the current language + slug: + type: string + description: The slug specific for the story + name: + type: string + description: The complete name provided for the story + published: + type: boolean + description: true if a story is currently published, even if it has unpublished changes + localized_paths: + type: array + description: An array of translated path objects + items: + type: object + properties: + path: + type: string + description: Value of the real path defined in the story's entry configuration + name: + type: string + description: The complete name provided for the story + lang: + type: string + description: Language code of the current language + published: + type: boolean + description: true if a story is currently published, even if it has unpublished changes + position: + type: integer + description: Numeric representation of the story's position in the folder + release_id: + type: integer + description: ID of the current release (can be requested with the from_release API parameter) + nullable: true + scheduled_dates: + type: string + format: date-time + description: Scheduled publishing date YYYY-mm-dd HH:MM + favourite_for_user_ids: + type: array + description: Array of user IDs who have added the story in their favorites + items: + type: integer + lang: + type: string + default: "default" diff --git a/packages/openapi/resources/mapi/assets/main.yaml b/packages/openapi/resources/mapi/assets/main.yaml index fc7e2f34a..beb395a30 100644 --- a/packages/openapi/resources/mapi/assets/main.yaml +++ b/packages/openapi/resources/mapi/assets/main.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.1 +openapi: 3.0.0 info: title: Storyblok Assets API version: 1.0.0 @@ -23,8 +23,8 @@ paths: summary: Retrieve Multiple Assets description: Returns an array of asset objects. This endpoint is paginated. parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/pagination.yaml#/page + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/pagination.yaml#/page - name: per_page in: query required: false @@ -106,7 +106,7 @@ paths: summary: Upload Asset description: Step 1 of the upload process. Get a signed response object for uploading assets. This is the first step in a three-step upload process. parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -150,8 +150,8 @@ paths: summary: Retrieve One Asset description: Returns a single asset object by providing a specific numeric id. parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/asset_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/asset_id responses: '200': description: Asset details @@ -173,8 +173,8 @@ paths: summary: Update Asset description: Update an asset using the numeric ID of the asset. parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/asset_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/asset_id requestBody: required: true content: @@ -244,8 +244,8 @@ paths: summary: Delete an Asset description: Delete an asset by using its numeric id. parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/asset_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/asset_id responses: '200': description: Asset deleted @@ -268,7 +268,7 @@ paths: summary: Finish Asset Upload description: Step 3 of the upload process. Finalize the upload process after the file has been uploaded to S3. This is the final step in a three-step upload process. parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: signed_response_object_id in: path required: true @@ -299,7 +299,7 @@ paths: summary: Delete Multiple Assets description: Delete multiple assets by using their numeric IDs. parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -338,7 +338,7 @@ paths: summary: Bulk Moving of Assets description: This endpoint allows moving multiple assets using their IDs to a specific folder. parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -381,7 +381,7 @@ paths: summary: Bulk Restoration of Deleted Assets description: To bulk restoration of deleted assets, pass bulk_restore after assets in the endpoint. Inside of the array from the payload should contain the asset IDs that you want to restore. parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: diff --git a/packages/openapi/resources/mapi/component_folders/main.yaml b/packages/openapi/resources/mapi/component_folders/main.yaml index 27f604168..3879887c4 100644 --- a/packages/openapi/resources/mapi/component_folders/main.yaml +++ b/packages/openapi/resources/mapi/component_folders/main.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.1 +openapi: 3.0.0 info: title: Storyblok Component Folders API version: 1.0.0 @@ -14,7 +14,7 @@ paths: operationId: list summary: Retrieve Multiple Component Folders parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: search in: query required: false @@ -49,7 +49,7 @@ paths: operationId: create summary: Create a Component Folder parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -81,8 +81,8 @@ paths: operationId: get summary: Retrieve a Single Component Folder parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/component_group_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/component_group_id responses: '200': description: Component folder details @@ -103,8 +103,8 @@ paths: operationId: update summary: Update a Component Folder parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/component_group_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/component_group_id requestBody: required: true content: @@ -134,8 +134,8 @@ paths: operationId: delete summary: Delete a Component Folder parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/component_group_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/component_group_id responses: '204': description: Component folder deleted successfully diff --git a/packages/openapi/resources/mapi/components/main.yaml b/packages/openapi/resources/mapi/components/main.yaml index 40739a274..e336acde6 100644 --- a/packages/openapi/resources/mapi/components/main.yaml +++ b/packages/openapi/resources/mapi/components/main.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.1 +openapi: 3.0.0 info: title: Storyblok Components API version: 1.0.0 @@ -14,8 +14,8 @@ paths: operationId: list summary: Retrieve Multiple Components parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/pagination.yaml#/page + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/pagination.yaml#/page - name: per_page in: query required: false @@ -95,7 +95,7 @@ paths: operationId: create summary: Create a Component parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -127,8 +127,8 @@ paths: operationId: get summary: Retrieve One Component parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/component_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/component_id responses: '200': description: Component details @@ -149,8 +149,8 @@ paths: operationId: update summary: Update a Component parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/component_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/component_id requestBody: required: true content: @@ -183,8 +183,8 @@ paths: operationId: deleteComponent summary: Delete a Component parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/component_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/component_id responses: '200': description: Component deleted @@ -207,8 +207,8 @@ paths: summary: Rename Component Attribute description: Rename an attribute within a component's schema parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/component_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/component_id - name: old_name in: query required: true @@ -242,8 +242,8 @@ paths: summary: Restore Component description: Restore a component from its last version parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/component_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/component_id responses: '200': description: Component restored @@ -266,7 +266,7 @@ paths: summary: Bulk Move Components description: Update multiple components' group assignment parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -313,7 +313,7 @@ paths: operationId: versions summary: Retrieve Component Versions parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: page in: query required: false @@ -389,8 +389,8 @@ paths: operationId: version summary: Retrieve a Single Component Version parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/component_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/component_id - name: version_id in: path required: true @@ -423,7 +423,7 @@ paths: operationId: restoreVersion summary: Restore a Component Version parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: version_id in: path required: true diff --git a/packages/openapi/resources/mapi/datasource_entries/main.yaml b/packages/openapi/resources/mapi/datasource_entries/main.yaml index cca2ad54b..be11d7625 100644 --- a/packages/openapi/resources/mapi/datasource_entries/main.yaml +++ b/packages/openapi/resources/mapi/datasource_entries/main.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.1 +openapi: 3.0.0 info: title: Storyblok Datasource Entries API version: 1.0.0 @@ -13,8 +13,8 @@ paths: operationId: list summary: Retrieve Multiple Datasource Entries parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/pagination.yaml#/page + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/pagination.yaml#/page - name: per_page in: query required: false @@ -64,7 +64,7 @@ paths: operationId: create summary: Create a Datasource Entry parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -95,7 +95,7 @@ paths: operationId: get summary: Retrieve a Single Datasource Entry parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: datasource_entry_id in: path required: true @@ -122,7 +122,7 @@ paths: operationId: updateDatasourceEntry summary: Update a Datasource Entry parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: datasource_entry_id in: path required: true @@ -158,7 +158,7 @@ paths: operationId: delete summary: Delete a Datasource Entry parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: datasource_entry_id in: path required: true @@ -200,4 +200,4 @@ components: description: The numeric ID of the datasource dimension_value: type: string - description: Given value in the requested dimension \ No newline at end of file + description: Given value in the requested dimension diff --git a/packages/openapi/resources/mapi/datasources/main.yaml b/packages/openapi/resources/mapi/datasources/main.yaml index 47ee6ed8c..3a94b2537 100644 --- a/packages/openapi/resources/mapi/datasources/main.yaml +++ b/packages/openapi/resources/mapi/datasources/main.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.1 +openapi: 3.0.0 info: title: Storyblok Datasources API version: 1.0.0 @@ -13,7 +13,7 @@ paths: operationId: list summary: Retrieve Multiple Datasources parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: search in: query required: false @@ -48,7 +48,7 @@ paths: operationId: create summary: Create a Datasource parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -79,7 +79,7 @@ paths: operationId: get summary: Retrieve One Datasource parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: datasource_id in: path required: true @@ -106,7 +106,7 @@ paths: operationId: update summary: Update a Datasource parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: datasource_id in: path required: true @@ -142,7 +142,7 @@ paths: operationId: delete summary: Delete a Datasource parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: datasource_id in: path required: true @@ -214,4 +214,4 @@ components: updated_at: type: string format: date-time - description: Latest update date \ No newline at end of file + description: Latest update date diff --git a/packages/openapi/resources/mapi/internal_tags/main.yaml b/packages/openapi/resources/mapi/internal_tags/main.yaml index 3e15d04ed..058ca92d5 100644 --- a/packages/openapi/resources/mapi/internal_tags/main.yaml +++ b/packages/openapi/resources/mapi/internal_tags/main.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.1 +openapi: 3.0.0 info: title: Storyblok Internal Tags API version: 1.0.0 @@ -13,8 +13,8 @@ paths: operationId: list summary: Retrieve Multiple Internal Tags parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/pagination.yaml#/page + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/pagination.yaml#/page - name: per_page in: query required: false @@ -41,7 +41,7 @@ paths: '200': description: List of internal tags headers: - $ref: ../shared/pagination.yaml#/pagination_headers + $ref: ../../shared/pagination.yaml#/pagination_headers content: application/json: schema: @@ -61,7 +61,7 @@ paths: operationId: create summary: Create an Internal Tag parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -89,7 +89,7 @@ paths: operationId: update summary: Update an Internal Tag parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: internal_tag_id in: path required: true @@ -123,7 +123,7 @@ paths: operationId: delete summary: Delete an Internal Tag parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: internal_tag_id in: path required: true diff --git a/packages/openapi/resources/mapi/presets/main.yaml b/packages/openapi/resources/mapi/presets/main.yaml index 98d29fd8b..a246db841 100644 --- a/packages/openapi/resources/mapi/presets/main.yaml +++ b/packages/openapi/resources/mapi/presets/main.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.1 +openapi: 3.0.0 info: title: Storyblok Presets API version: 1.0.0 @@ -14,7 +14,7 @@ paths: summary: Retrieve Multiple Presets description: Returns an array of preset objects. parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: component_id in: query required: false @@ -34,17 +34,17 @@ paths: items: $ref: '#/components/schemas/Preset' '400': - $ref: ../shared/responses.yaml#/BadRequest + $ref: ../../shared/responses.yaml#/BadRequest '401': - $ref: ../shared/responses.yaml#/Unauthorized + $ref: ../../shared/responses.yaml#/Unauthorized '404': - $ref: ../shared/responses.yaml#/NotFound + $ref: ../../shared/responses.yaml#/NotFound post: operationId: create summary: Create a Preset description: This endpoint can be used to create new presets. parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -65,19 +65,19 @@ paths: preset: $ref: '#/components/schemas/Preset' '400': - $ref: ../shared/responses.yaml#/BadRequest + $ref: ../../shared/responses.yaml#/BadRequest '401': - $ref: ../shared/responses.yaml#/Unauthorized + $ref: ../../shared/responses.yaml#/Unauthorized '404': - $ref: ../shared/responses.yaml#/NotFound + $ref: ../../shared/responses.yaml#/NotFound /v1/spaces/{space_id}/presets/{preset_id}: get: operationId: get summary: Retrieve a Single Preset description: Returns a single preset object with a specific numeric id. parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/preset_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/preset_id responses: '200': description: Successfully retrieved preset @@ -89,18 +89,18 @@ paths: preset: $ref: '#/components/schemas/Preset' '400': - $ref: ../shared/responses.yaml#/BadRequest + $ref: ../../shared/responses.yaml#/BadRequest '401': - $ref: ../shared/responses.yaml#/Unauthorized + $ref: ../../shared/responses.yaml#/Unauthorized '404': - $ref: ../shared/responses.yaml#/NotFound + $ref: ../../shared/responses.yaml#/NotFound put: operationId: update summary: Update a Preset description: This endpoint can be used to update presets using the numeric ID. parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/preset_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/preset_id requestBody: required: true content: @@ -121,18 +121,18 @@ paths: preset: $ref: '#/components/schemas/Preset' '400': - $ref: ../shared/responses.yaml#/BadRequest + $ref: ../../shared/responses.yaml#/BadRequest '401': - $ref: ../shared/responses.yaml#/Unauthorized + $ref: ../../shared/responses.yaml#/Unauthorized '404': - $ref: ../shared/responses.yaml#/NotFound + $ref: ../../shared/responses.yaml#/NotFound delete: operationId: delete summary: Delete a Preset description: Delete a preset by using its numeric id. parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/preset_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/preset_id responses: '200': description: Successfully deleted preset @@ -144,11 +144,11 @@ paths: preset: $ref: '#/components/schemas/Preset' '400': - $ref: ../shared/responses.yaml#/BadRequest + $ref: ../../shared/responses.yaml#/BadRequest '401': - $ref: ../shared/responses.yaml#/Unauthorized + $ref: ../../shared/responses.yaml#/Unauthorized '404': - $ref: ../shared/responses.yaml#/NotFound + $ref: ../../shared/responses.yaml#/NotFound components: securitySchemes: $ref: ../shared/security-schemes.yaml#/securitySchemes diff --git a/packages/openapi/resources/mapi/shared/components.yaml b/packages/openapi/resources/mapi/shared/components.yaml deleted file mode 100644 index 744543e82..000000000 --- a/packages/openapi/resources/mapi/shared/components.yaml +++ /dev/null @@ -1,5 +0,0 @@ -BearerAuth: - type: http - scheme: bearer - description: Bearer token authentication - diff --git a/packages/openapi/resources/mapi/spaces/main.yaml b/packages/openapi/resources/mapi/spaces/main.yaml index afb7a3e1d..a03c165c2 100644 --- a/packages/openapi/resources/mapi/spaces/main.yaml +++ b/packages/openapi/resources/mapi/spaces/main.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.1 +openapi: 3.0.0 info: title: Storyblok Spaces API version: 1.0.0 @@ -89,7 +89,7 @@ paths: summary: Retrieve a Single Space description: Returns a single space object by providing a specific numeric id. parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id responses: '200': description: Space details @@ -113,7 +113,7 @@ paths: summary: Update a Space description: Update a space using the numeric ID. You can only able to update the properties mentioned here. parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: @@ -150,7 +150,7 @@ paths: summary: Delete a Space description: Delete a space by its numeric id. parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id responses: '200': description: Space deleted diff --git a/packages/openapi/resources/mapi/stories/main.yaml b/packages/openapi/resources/mapi/stories/main.yaml index b57a254a3..7abf76b11 100644 --- a/packages/openapi/resources/mapi/stories/main.yaml +++ b/packages/openapi/resources/mapi/stories/main.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.1 +openapi: 3.0.0 info: title: Storyblok Stories API version: 1.0.0 @@ -13,17 +13,9 @@ paths: operationId: list summary: Retrieve Multiple Stories parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/pagination.yaml#/page - - name: per_page - in: query - required: false - schema: - type: integer - minimum: 1 - maximum: 100 - default: 25 - description: Number of stories per page. Default is 25, maximum is 100. + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/pagination.yaml#/page + - $ref: ../../shared/pagination.yaml#/per_page - name: contain_component in: query required: false @@ -126,6 +118,13 @@ paths: schema: type: boolean description: true for entries that are currently published; false for those that are currently not published or unpublished + - name: version + in: query + required: false + schema: + type: string + enum: ['published', 'draft'] + default: 'published' - name: by_slugs in: query required: false @@ -234,7 +233,7 @@ paths: '200': description: List of stories headers: - $ref: ../shared/pagination.yaml#/pagination_headers + $ref: ../../shared/pagination.yaml#/pagination_headers content: application/json: schema: @@ -254,7 +253,7 @@ paths: operationId: create summary: Create a Story parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: release_id in: query required: false @@ -318,8 +317,8 @@ paths: operationId: get summary: Retrieve One Story parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id - name: uuid in: query required: false @@ -352,8 +351,8 @@ paths: operationId: updateStory summary: Update a Story parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id - name: release_id in: query required: false @@ -400,12 +399,14 @@ paths: description: Unauthorized '404': description: Story not found + '500': + description: Internal server error delete: operationId: delete summary: Delete a Story parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id responses: '200': description: Story deleted @@ -427,8 +428,8 @@ paths: operationId: duplicate summary: Duplicate a Story parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id - name: release_id in: query required: false @@ -474,8 +475,8 @@ paths: operationId: publish summary: Publish a Story parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id - name: lang in: query required: false @@ -509,8 +510,8 @@ paths: operationId: unpublish summary: Unpublish a Story parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id - name: lang in: query required: false @@ -544,8 +545,8 @@ paths: operationId: export summary: Export a Story parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id - name: version in: query required: false @@ -585,8 +586,8 @@ paths: operationId: import summary: Import a Story parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id - name: version in: query required: false @@ -644,8 +645,8 @@ paths: operationId: translate summary: Translate a Story by AI parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id requestBody: required: true content: @@ -690,7 +691,7 @@ paths: operationId: versions summary: Get Story Versions (New) parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id - name: by_story_id in: query required: false @@ -803,8 +804,8 @@ paths: operationId: restoreVersions summary: Restore a Story Version parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id - name: versions_v2 in: query required: true @@ -845,8 +846,8 @@ paths: summary: Compare a Story Version description: Compare the changes between two versions of a story in Storyblok. You need to provide the story `ID` and version `ID` in the request to retrieve the comparison results. parameters: - - $ref: ../shared/parameters.yaml#/space_id - - $ref: ../shared/parameters.yaml#/story_id + - $ref: ../../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/story_id - name: version in: query required: true @@ -872,7 +873,7 @@ paths: operationId: getUnpublishedDependencies summary: Get Unpublished Dependencies parameters: - - $ref: ../shared/parameters.yaml#/space_id + - $ref: ../../shared/parameters.yaml#/space_id requestBody: required: true content: diff --git a/packages/openapi/resources/mapi/stories/schemas/blok.yaml b/packages/openapi/resources/mapi/stories/schemas/blok.yaml index eb9bb9e31..760a90e12 100644 --- a/packages/openapi/resources/mapi/stories/schemas/blok.yaml +++ b/packages/openapi/resources/mapi/stories/schemas/blok.yaml @@ -22,5 +22,6 @@ additionalProperties: - type: boolean - type: array items: - oneOf: - - $ref: '#' + - $ref: '#' + - type: object + additionalProperties: true diff --git a/packages/openapi/resources/mapi/stories/schemas/story.yaml b/packages/openapi/resources/mapi/stories/schemas/story.yaml index d6a637448..2c13eee2a 100644 --- a/packages/openapi/resources/mapi/stories/schemas/story.yaml +++ b/packages/openapi/resources/mapi/stories/schemas/story.yaml @@ -69,6 +69,7 @@ type: string format: date-time description: Latest publishing date yyyy-MM-dd'T'HH:mm:ssZ + nullable: true uuid: type: string format: uuid @@ -93,6 +94,9 @@ full_slug: type: string description: The full slug of the story, combining the parent folder(s) and the designated story slug + default_full_slug: + type: string + nullable: true default_root: type: string nullable: true @@ -159,6 +163,7 @@ translated_slugs: type: array description: Array of translated slug objects (if the app Translatable Slugs is installed) + nullable: true items: type: object properties: @@ -181,6 +186,7 @@ type: string format: date-time description: First publishing date yyyy-MM-dd'T'HH:mm:ssZ + nullable: true last_author: type: object description: Last author @@ -263,6 +269,7 @@ release_id: type: integer description: ID of the current release (can be requested with the from_release API parameter) + nullable: true scheduled_dates: type: string format: date-time @@ -272,3 +279,6 @@ description: Array of user IDs who have added the story in their favorites items: type: integer + lang: + type: string + default: "default" diff --git a/packages/openapi/resources/mapi/users/main.yaml b/packages/openapi/resources/mapi/users/main.yaml index b6f6b95f4..ab749a84d 100644 --- a/packages/openapi/resources/mapi/users/main.yaml +++ b/packages/openapi/resources/mapi/users/main.yaml @@ -1,4 +1,4 @@ -openapi: 3.1.1 +openapi: 3.0.0 info: title: Storyblok Users API version: 1.0.0 diff --git a/packages/openapi/resources/mapi/shared/pagination.yaml b/packages/openapi/resources/shared/pagination.yaml similarity index 97% rename from packages/openapi/resources/mapi/shared/pagination.yaml rename to packages/openapi/resources/shared/pagination.yaml index 628b03cdc..102a70018 100644 --- a/packages/openapi/resources/mapi/shared/pagination.yaml +++ b/packages/openapi/resources/shared/pagination.yaml @@ -18,6 +18,7 @@ per_page: schema: type: integer minimum: 1 + maximum: 100 default: 25 description: Number of items per page. Default is 25. diff --git a/packages/openapi/resources/mapi/shared/parameters.yaml b/packages/openapi/resources/shared/parameters.yaml similarity index 100% rename from packages/openapi/resources/mapi/shared/parameters.yaml rename to packages/openapi/resources/shared/parameters.yaml diff --git a/packages/openapi/resources/mapi/shared/responses.yaml b/packages/openapi/resources/shared/responses.yaml similarity index 100% rename from packages/openapi/resources/mapi/shared/responses.yaml rename to packages/openapi/resources/shared/responses.yaml diff --git a/packages/react/playground/next15/.gitignore b/packages/react/playground/next15/.gitignore index 44fdeff2b..1cc5272d4 100644 --- a/packages/react/playground/next15/.gitignore +++ b/packages/react/playground/next15/.gitignore @@ -39,4 +39,11 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts -certificates \ No newline at end of file +certificates + +# Playwright +node_modules/ +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/packages/react/playground/next15/next.config.ts b/packages/react/playground/next15/next.config.ts index 5e891cf00..f9002c7fb 100644 --- a/packages/react/playground/next15/next.config.ts +++ b/packages/react/playground/next15/next.config.ts @@ -1,7 +1,9 @@ import type { NextConfig } from 'next'; const nextConfig: NextConfig = { - /* config options here */ + typescript: { + ignoreBuildErrors: true, + }, }; export default nextConfig; diff --git a/packages/react/playground/next15/package.json b/packages/react/playground/next15/package.json index cc8dd3996..a09d564d1 100644 --- a/packages/react/playground/next15/package.json +++ b/packages/react/playground/next15/package.json @@ -6,7 +6,8 @@ "dev": "next dev --experimental-https", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "test:integration": "playwright test" }, "dependencies": { "@storyblok/react": "workspace:*", @@ -16,10 +17,13 @@ "react-dom": "19.1.0" }, "devDependencies": { + "@playwright/test": "^1.55.0", + "@storyblok/openapi": "workspace:*", + "@storyblok/test-utils": "workspace:*", "@tailwindcss/postcss": "^4.1.10", "@types/node": "^20", - "@types/react": "^19", "@types/react-dom": "^19", + "@types/react": "^19", "postcss": "^8.5.6", "tailwindcss": "^4.1.10" }, diff --git a/packages/react/playground/next15/specmatic.json b/packages/react/playground/next15/specmatic.json new file mode 100644 index 000000000..2a6d52c35 --- /dev/null +++ b/packages/react/playground/next15/specmatic.json @@ -0,0 +1,10 @@ +{ + "version": 2, + "contracts": [ + { + "consumes": [ + "./node_modules/@storyblok/openapi/dist/capi/stories.yaml" + ] + } + ] +} diff --git a/packages/react/playground/next15/src/app/components/Page.tsx b/packages/react/playground/next15/src/app/components/Page.tsx index 770e200a6..0a8ab30ae 100644 --- a/packages/react/playground/next15/src/app/components/Page.tsx +++ b/packages/react/playground/next15/src/app/components/Page.tsx @@ -1,6 +1,6 @@ import { storyblokEditable, StoryblokServerComponent } from '@storyblok/react/rsc'; -const Page = ({ blok }) => ( +const Page = ({ blok }: { blok: { body: any[] }}) => (
{blok.body.map(nestedBlok => ( diff --git a/packages/react/playground/next15/src/app/components/Teaser.tsx b/packages/react/playground/next15/src/app/components/Teaser.tsx index 9489411d9..6d66198de 100644 --- a/packages/react/playground/next15/src/app/components/Teaser.tsx +++ b/packages/react/playground/next15/src/app/components/Teaser.tsx @@ -1,7 +1,7 @@ import { storyblokEditable } from '@storyblok/react/rsc'; import { headers } from 'next/headers'; -const Teaser = ({ blok }) => { +const Teaser = ({ blok }: { blok: { headline: any }}) => { // Although we are not using the headers here, we need to call it to test that server only components are working. headers(); return ( diff --git a/packages/react/playground/next15/src/app/react/richtext/page.tsx b/packages/react/playground/next15/src/app/react/richtext/page.tsx index dff1c447a..2ea328e88 100644 --- a/packages/react/playground/next15/src/app/react/richtext/page.tsx +++ b/packages/react/playground/next15/src/app/react/richtext/page.tsx @@ -3,7 +3,9 @@ import { getStoryblokApi } from '@/lib/storyblok'; import { StoryblokServerRichText } from '@storyblok/react/rsc'; export default async function RichtextPage() { - const { data } = await fetchData(); + const sbParams: ISbStoriesParams = { version: 'draft' }; + const storyblokApi: StoryblokClient = getStoryblokApi(); + const { data } = await storyblokApi.get(`cdn/stories/react/richtext`, sbParams); if (!data.story?.content) { return ( @@ -28,10 +30,3 @@ export default async function RichtextPage() { ); } - -export async function fetchData() { - const sbParams: ISbStoriesParams = { version: 'draft' }; - - const storyblokApi: StoryblokClient = getStoryblokApi(); - return storyblokApi.get(`cdn/stories/react/richtext`, sbParams); -} diff --git a/packages/react/playground/next15/src/lib/storyblok.ts b/packages/react/playground/next15/src/lib/storyblok.ts index 06909e2ed..428d1301b 100644 --- a/packages/react/playground/next15/src/lib/storyblok.ts +++ b/packages/react/playground/next15/src/lib/storyblok.ts @@ -6,6 +6,9 @@ import { apiPlugin, storyblokInit } from '@storyblok/react/rsc'; export const getStoryblokApi = storyblokInit({ accessToken: 'OurklwV5XsDJTIE1NJaD2wtt', + apiOptions: { + endpoint: process.env.STORYBLOK_API_ENDPOINT, + }, use: [apiPlugin], components: { 'teaser': Teaser, diff --git a/packages/react/playground/next15/test/specs/app.integration.spec.ts b/packages/react/playground/next15/test/specs/app.integration.spec.ts new file mode 100644 index 000000000..5990303ad --- /dev/null +++ b/packages/react/playground/next15/test/specs/app.integration.spec.ts @@ -0,0 +1,25 @@ +// TODO package +import { it, expect } from '../../../../../test-utils/src/playwright/test-utils'; +import { hasStory } from '../../../../../test-utils/src/preconditions/stories-capi'; +import { makeStory, makeBlok } from "../../../../../test-utils/src/preconditions/stories"; + +it('should render the emoji randomizer', async ({ page, startApp }) => { + await startApp('pnpm start', [hasStory({ + story: makeStory({ + slug: 'react', + content: makeBlok({ + component: "page", + body: [ + makeBlok({ + label: "Randomize Emoji", + component: "emoji-randomizer", + }) + ] + }) + }) + })]); + + await page.goto('/'); + + await expect(page.getByRole('button', { name: "Randomize Emoji" })).toBeVisible(); +}); diff --git a/packages/test-utils/.prettierrc b/packages/test-utils/.prettierrc new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/packages/test-utils/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json new file mode 100644 index 000000000..1183c4e09 --- /dev/null +++ b/packages/test-utils/package.json @@ -0,0 +1,45 @@ +{ + "name": "@storyblok/test-utils", + "version": "1.0.0", + "description": "Storyblok Test Utils", + "private": true, + "type": "module", + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "homepage": "https://github.com/storyblok/monoblok/tree/main/packages/test-utils#readme", + "repository": { + "type": "git", + "url": "https://github.com/storyblok/monoblok.git", + "directory": "packages/mapi-client" + }, + "bugs": { + "url": "https://github.com/storyblok/monoblok/issues" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + }, + "./preconditions/*": { + "types": "./dist/preconditions/*.d.ts" + }, + "./vitest/test-utils": { + "types": "./dist/vitest/test-utils.d.ts" + } + }, + "dependencies": { + "@faker-js/faker": "^10.0.0", + "@storyblok/management-api-client": "workspace:*", + "lodash.merge": "^4.6.2" + }, + "peerDependencies": { + "@playwright/test": "^1.55.0", + "vitest": "^3.2.4" + }, + "devDependencies": { + "@types/lodash.merge": "^4.6.9", + "@types/node": "^24.3.1" + } +} diff --git a/packages/test-utils/src/playwright/test-utils.ts b/packages/test-utils/src/playwright/test-utils.ts new file mode 100644 index 000000000..303ae061e --- /dev/null +++ b/packages/test-utils/src/playwright/test-utils.ts @@ -0,0 +1,120 @@ +import { expect, test as base } from "@playwright/test"; +import { + parsePortRange, + PORT_RANGE_APP, + PORT_RANGE_STUB_SERVER, + waitForHTTP, +} from "../utils/http.ts"; +import { + makeStore, + startServer, + type Precondition, +} from "../utils/stub-server.ts"; +import { spawn } from "node:child_process"; + +interface UtilsTest { + baseURL: string; +} + +interface UtilsWorker { + appPort: number; + stubServer: { baseURL: string }; + store: ReturnType; + startApp: (command: string, preconditions?: Precondition[]) => Promise; + prepare: ( + precondition: Precondition | Precondition[] + ) => Promise[]>; +} + +const toArray = (maybeArray: unknown) => + Array.isArray(maybeArray) ? maybeArray : [maybeArray]; + +// TODO also logic for spinning up the app itself / the whole env +// maybe with switch for only stub to use dev server +export const it = base.extend({ + appPort: [ + async ({}, use, { workerIndex }) => { + const portRange = parsePortRange(PORT_RANGE_APP); + const port = portRange.start + workerIndex; + if (port > portRange.end) + throw new Error( + `Tried to allocate port ${port}, but the maximum port is ${portRange.end}. Provide a larger range or reduce the number of workers.` + ); + await use(port); + }, + { scope: "worker" }, + ], + stubServer: [ + async ({}, use, { workerIndex }) => { + const portRange = parsePortRange(PORT_RANGE_STUB_SERVER); + const port = portRange.start + workerIndex; + if (port > portRange.end) + throw new Error( + `Tried to allocate port ${port}, but the maximum port is ${portRange.end}. Provide a larger range or reduce the number of workers.` + ); + + const { baseURL, stop } = await startServer({ port }); + + try { + await use({ baseURL }); + } finally { + await stop(); + } + }, + { scope: "worker" }, + ], + store: [ + async ({ stubServer }, use) => { + await use(makeStore({ baseURL: stubServer.baseURL })); + }, + { scope: "worker" }, + ], + startApp: [ + async ({ appPort, stubServer, store }, use) => { + let stop: () => void = () => {}; + try { + await use(async (command, preconditions = []) => { + const [cmd, ...cmdOptions] = command.split(" "); + if (!cmd) throw new Error("Invalid start command!"); + const app = spawn(cmd, cmdOptions, { + env: { + ...process.env, + STORYBLOK_API_ENDPOINT: `${stubServer.baseURL}/v1`, + PORT: String(appPort), + }, + }); + app.stdout.on("data", (data) => { + console.info(`App: ${data}`); + }); + app.stderr.on("data", (data) => { + console.error(`App: ${data}`); + }); + stop = () => { + app.kill(); + }; + + await Promise.all([ + ...preconditions.map((p) => p({ store })), + waitForHTTP(`http://localhost:${appPort}`), + ]); + }); + } finally { + stop(); + } + }, + { scope: "worker" }, + ], + prepare: [ + async ({ store }, use) => { + await use((precondition) => + Promise.all(toArray(precondition).map((p) => p({ store }))) + ); + }, + { scope: "worker" }, + ], + baseURL: async ({ appPort }, use) => { + await use(`http://localhost:${appPort}`); + }, +}); + +export { expect }; diff --git a/packages/test-utils/src/preconditions/stories-capi.ts b/packages/test-utils/src/preconditions/stories-capi.ts new file mode 100644 index 000000000..6e9857e5d --- /dev/null +++ b/packages/test-utils/src/preconditions/stories-capi.ts @@ -0,0 +1,18 @@ +import type { Story } from "@storyblok/management-api-client/resources/stories"; +import type { ExampleStore } from "../utils/stub-server.ts"; +import { makeStory } from "./stories.ts"; + +export const hasStory = + ({ story = makeStory() }: { story?: Story } = {}) => + ({ store }: { store: ExampleStore }) => + store.add({ + request: { + method: "GET", + path: `/v1/cdn/stories/${story.slug}`, + }, + response: { + status: 200, + body: { story }, + }, + partial: true, + }); diff --git a/packages/test-utils/src/preconditions/stories-mapi.ts b/packages/test-utils/src/preconditions/stories-mapi.ts new file mode 100644 index 000000000..ce1534fcd --- /dev/null +++ b/packages/test-utils/src/preconditions/stories-mapi.ts @@ -0,0 +1,62 @@ +import type { Story } from "@storyblok/management-api-client/resources/stories"; +import type { ExampleStore } from "../utils/stub-server.ts"; +import { makeStory } from "./stories.ts"; + +export const hasStories = + ({ + spaceId, + stories = [makeStory(), makeStory(), makeStory()], + }: { + spaceId: string; + stories: Story[]; + }) => + ({ store }: { store: ExampleStore }) => + store.add({ + request: { + method: "GET", + path: `/v1/spaces/${spaceId}/stories`, + }, + response: { + status: 200, + headers: { + Total: stories.length, + "Per-Page": 25, + }, + body: { stories }, + }, + partial: true, + }); + +export const hasStory = + ({ spaceId, story = makeStory() }: { spaceId: string; story?: Story }) => + async ({ store }: { store: ExampleStore }) => { + await Promise.all([ + store.add({ + request: { + method: "GET", + path: `/v1/spaces/${spaceId}/stories/${story.id}`, + }, + response: { + status: 200, + body: { story }, + }, + partial: true, + }), + hasStories({ spaceId, stories: [story] })({ store }), + ]); + }; + +export const canNotUpdateStory = + ({ spaceId, storyId }: { spaceId: string; storyId: Story["id"] }) => + ({ store }: { store: ExampleStore }) => + store.add({ + request: { + method: "PUT", + path: `/v1/spaces/${spaceId}/stories/${storyId}`, + body: {}, + }, + response: { + status: 500, + }, + partial: true, + }); diff --git a/packages/test-utils/src/preconditions/stories.ts b/packages/test-utils/src/preconditions/stories.ts new file mode 100644 index 000000000..79a87590c --- /dev/null +++ b/packages/test-utils/src/preconditions/stories.ts @@ -0,0 +1,41 @@ +import { faker } from "@faker-js/faker"; +import merge from "lodash.merge"; +import type { + Blok, + Story, +} from "@storyblok/management-api-client/resources/stories"; + +export const makeBlok = (blok?: Partial): Blok => + merge( + { + _uid: faker.string.uuid(), + component: faker.helpers.slugify( + `${faker.word.verb()} ${faker.word.noun()}` + ), + } satisfies Blok, + blok + ); + +export const makeStory = (story: Partial = {}): Story => + merge( + { + id: faker.number.int({ max: 2147483647 }), + uuid: faker.string.uuid(), + name: faker.word.noun(), + created_at: "2025-09-10T16:10:40Z", + deleted_at: "2025-09-10T16:10:40Z", + updated_at: "2025-09-10T16:10:40Z", + published_at: "2025-09-10T16:10:40Z", + first_published_at: "2025-09-10T16:10:40Z", + content: makeBlok(), + published: true, + slug: faker.helpers.slugify(`${faker.word.verb()} ${faker.word.noun()}`), + path: `${faker.helpers.slugify( + `${faker.word.verb()} ${faker.word.noun()}` + )}/${faker.helpers.slugify(`${faker.word.verb()} ${faker.word.noun()}`)}`, + full_slug: `${faker.helpers.slugify( + `${faker.word.verb()} ${faker.word.noun()}` + )}/${faker.helpers.slugify(`${faker.word.verb()} ${faker.word.noun()}`)}`, + } satisfies Story, + story + ); diff --git a/packages/test-utils/src/utils/http.ts b/packages/test-utils/src/utils/http.ts new file mode 100644 index 000000000..4102e26fc --- /dev/null +++ b/packages/test-utils/src/utils/http.ts @@ -0,0 +1,50 @@ +export const PORT_RANGE_APP = + process.env.STORYBLOK_TEST_UTILS_PORT_RANGE_APP ?? "3000-3100"; + +export const PORT_RANGE_STUB_SERVER = + process.env.STORYBLOK_TEST_UTILS_PORT_RANGE_STUB_SERVER ?? "9000-9100"; + +export const waitForHTTP = async ( + url: string, + { + timeout = 20_000, + interval = 200, + method = "GET", + }: { + timeout?: number; + interval?: number; + method?: string; + } = {} +): Promise => { + const start = Date.now(); + let lastError: unknown; + + while (Date.now() - start < timeout) { + try { + const controller = new AbortController(); + const perRequestTimeout = setTimeout( + () => controller.abort(), + Math.min(5000, timeout) + ); + const res = await fetch(url, { method, signal: controller.signal }); + clearTimeout(perRequestTimeout); + + if (res.ok) return; + } catch (error) { + lastError = error; + } + await new Promise((r) => setTimeout(r, interval)); + } + + throw lastError; +}; + +export const parsePortRange = (range: string) => { + const [start, end] = range.split("-").map(Number); + if (!start || !end || Number.isNaN(start) || Number.isNaN(end)) + throw new Error( + `Invalid port range "${range}". The range must be in the format "9000-9100".` + ); + + return { start, end }; +}; diff --git a/packages/test-utils/src/utils/stub-server.ts b/packages/test-utils/src/utils/stub-server.ts new file mode 100644 index 000000000..8ba9e2700 --- /dev/null +++ b/packages/test-utils/src/utils/stub-server.ts @@ -0,0 +1,106 @@ +import { execSync } from "node:child_process"; +import { waitForHTTP } from "./http.ts"; +import path from "node:path"; +import { readFileSync } from "node:fs"; + +type HttpMethod = + | "GET" + | "POST" + | "PUT" + | "PATCH" + | "DELETE" + | "HEAD" + | "OPTIONS"; + +export type HttpRequest = { + method: HttpMethod; + path: string; + headers?: Record; + query?: Record< + string, + string | number | boolean | Array + >; + body?: unknown; +}; + +export type HttpResponse = { + status: number; + headers?: Record; + body?: unknown; +}; + +export type Example = { + request?: HttpRequest; + response?: HttpResponse; + partial?: boolean; +}; + +export type ExampleStore = { + add: (example: Example) => Promise; +}; + +export type Precondition = ({ + store, +}: { + store: ExampleStore; +}) => Promise; + +export const makeStore = ({ baseURL }: { baseURL: string }) => ({ + add: async ({ request, response, partial }: Example) => { + const example = { + "http-request": request, + "http-response": response, + }; + const result = await fetch(`${baseURL}/_specmatic/expectations`, { + method: "POST", + body: JSON.stringify(partial ? { partial: example } : example), + }); + if (!result.ok) + throw new Error( + `Couldn't store example! Make sure your example matches the OpenAPI specification!\n\nSpecmatic: ${await result.text()}` + ); + }, +}); + +export const startServer = async ({ port }: { port: number }) => { + const specmaticConfigPath = path.resolve(process.cwd(), "specmatic.json"); + const specmaticConfig = JSON.parse( + readFileSync(specmaticConfigPath, { + encoding: "utf8", + }) + ) as { + contracts: { consumes: string[] }[]; + }; + const contractMaps = specmaticConfig.contracts.flatMap((x) => + x.consumes.map( + (y) => [path.resolve(process.cwd(), y), y] satisfies [string, string] + ) + ); + const mounts = contractMaps.map( + ([from, to]) => `-v "${from}:${path.join("/usr/src/app", to)}"` + ); + + const id = execSync( + `docker run --rm -d -p ${port}:9000 ${mounts.join( + " " + )} -v "${specmaticConfigPath}:/usr/src/app/specmatic.json" specmatic/specmatic:2.23.4 stub --strict` + ) + .toString() + .trim(); + const stop = async () => { + if (id) await execSync(`docker stop ${id}`); + }; + + const baseURL = `http://localhost:${port}`; + try { + await waitForHTTP(`${baseURL}/actuator/health`); + } catch (error) { + await stop(); + throw error; + } + + return { + baseURL, + stop, + }; +}; diff --git a/packages/test-utils/src/vitest/test-utils.ts b/packages/test-utils/src/vitest/test-utils.ts new file mode 100644 index 000000000..c572869ad --- /dev/null +++ b/packages/test-utils/src/vitest/test-utils.ts @@ -0,0 +1,53 @@ +import { it as baseIt } from "vitest"; +import { + makeStore, + startServer, + type Precondition, +} from "../utils/stub-server.ts"; +import { parsePortRange, PORT_RANGE_STUB_SERVER } from "../utils/http.ts"; + +export { describe, expect, vi } from "vitest"; + +type TestContext = { + stubServer: { baseURL: string }; + store: ReturnType; + prepare: ( + precondition: Precondition | Precondition[] + ) => Promise[]>; +}; + +const toArray = (maybeArray: unknown) => + Array.isArray(maybeArray) ? maybeArray : [maybeArray]; + +export const it = baseIt.extend({ + stubServer: [ + async ({}, use) => { + const portRange = parsePortRange(PORT_RANGE_STUB_SERVER); + const port = portRange.start - 1 + Number(process.env.VITEST_WORKER_ID); + if (port > portRange.end) + throw new Error( + `Tried to allocate port ${port}, but the maximum port is ${portRange.end}. Provide a larger range or reduce the number of workers.` + ); + + const { baseURL, stop } = await startServer({ port }); + + try { + await use({ baseURL }); + } finally { + await stop(); + } + }, + { scope: "worker" }, + ], + store: [ + async ({ stubServer }, use) => { + await use(makeStore({ baseURL: stubServer.baseURL })); + }, + { scope: "worker" }, + ], + prepare: async ({ store }, use) => { + await use((precondition) => + Promise.all(toArray(precondition).map((p) => p({ store }))) + ); + }, +}); diff --git a/packages/test-utils/tsconfig.json b/packages/test-utils/tsconfig.json new file mode 100644 index 000000000..7e1940559 --- /dev/null +++ b/packages/test-utils/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "allowImportingTsExtensions": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "module": "NodeNext", + "noEmit": true, + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "ESNext", + "types": ["node"], + "verbatimModuleSyntax": true + }, + "exclude": ["node_modules"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 82956c169..7f9decb0b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,7 +17,7 @@ importers: devDependencies: '@commitlint/cli': specifier: ^19.8.1 - version: 19.8.1(@types/node@24.1.0)(typescript@5.8.3) + version: 19.8.1(@types/node@24.3.1)(typescript@5.8.3) '@commitlint/config-conventional': specifier: ^19.8.1 version: 19.8.1 @@ -102,25 +102,25 @@ importers: version: 2.3.1(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.1.3 - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) packages/astro/playground/ssg: dependencies: '@astrojs/react': specifier: ^4.3.0 - version: 4.3.0(@types/node@24.1.0)(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 4.3.0(@types/node@24.3.1)(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) '@astrojs/svelte': specifier: ^7.1.0 - version: 7.1.0(@types/node@24.1.0)(astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(svelte@5.38.7)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + version: 7.1.0(@types/node@24.3.1)(astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(svelte@5.38.7)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) '@astrojs/vue': specifier: ^5.1.0 - version: 5.1.0(@types/node@24.1.0)(astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(vue@3.5.21(typescript@5.8.3))(yaml@2.8.0) + version: 5.1.0(@types/node@24.3.1)(astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(vue@3.5.21(typescript@5.8.3))(yaml@2.8.0) '@storyblok/astro': specifier: workspace:* version: link:../.. astro: specifier: ^5.13.2 - version: 5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + version: 5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) react: specifier: ^19.1.1 version: 19.1.1 @@ -136,28 +136,28 @@ importers: devDependencies: vite-plugin-mkcert: specifier: ^1.17.8 - version: 1.17.8(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 1.17.8(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) packages/astro/playground/ssr: dependencies: '@astrojs/react': specifier: ^4.3.0 - version: 4.3.0(@types/node@24.1.0)(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 4.3.0(@types/node@24.3.1)(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) '@astrojs/svelte': specifier: ^7.1.0 - version: 7.1.0(@types/node@24.1.0)(astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(svelte@5.38.7)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + version: 7.1.0(@types/node@24.3.1)(astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(svelte@5.38.7)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) '@astrojs/vercel': specifier: ^8.2.6 - version: 8.2.7(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(rollup@4.40.2)(svelte@5.38.7)(vue-router@4.5.1(vue@3.5.21(typescript@5.8.3)))(vue@3.5.21(typescript@5.8.3)) + version: 8.2.7(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(rollup@4.40.2)(svelte@5.38.7)(vue-router@4.5.1(vue@3.5.21(typescript@5.8.3)))(vue@3.5.21(typescript@5.8.3)) '@astrojs/vue': specifier: ^5.1.0 - version: 5.1.0(@types/node@24.1.0)(astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(vue@3.5.21(typescript@5.8.3))(yaml@2.8.0) + version: 5.1.0(@types/node@24.3.1)(astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(vue@3.5.21(typescript@5.8.3))(yaml@2.8.0) '@storyblok/astro': specifier: workspace:* version: link:../.. astro: specifier: ^5.13.2 - version: 5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + version: 5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) react: specifier: ^19.1.1 version: 19.1.1 @@ -173,25 +173,25 @@ importers: devDependencies: vite-plugin-mkcert: specifier: ^1.17.8 - version: 1.17.8(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 1.17.8(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) packages/astro/playground/test: dependencies: '@astrojs/react': specifier: ^4.3.0 - version: 4.3.0(@types/node@24.1.0)(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 4.3.0(@types/node@24.3.1)(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) '@astrojs/svelte': specifier: ^7.1.0 - version: 7.1.0(@types/node@24.1.0)(astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(svelte@5.38.7)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + version: 7.1.0(@types/node@24.3.1)(astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(svelte@5.38.7)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) '@astrojs/vue': specifier: ^5.1.0 - version: 5.1.0(@types/node@24.1.0)(astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(vue@3.5.21(typescript@5.8.3))(yaml@2.8.0) + version: 5.1.0(@types/node@24.3.1)(astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(vue@3.5.21(typescript@5.8.3))(yaml@2.8.0) '@storyblok/astro': specifier: workspace:* version: link:../.. astro: specifier: ^5.13.2 - version: 5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + version: 5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) react: specifier: ^19.1.1 version: 19.1.1 @@ -271,6 +271,9 @@ importers: '@storyblok/eslint-config': specifier: workspace:* version: link:../eslint-config + '@storyblok/openapi': + specifier: workspace:* + version: link:../openapi '@types/cli-progress': specifier: ^3.11.6 version: 3.11.6 @@ -282,15 +285,15 @@ importers: version: 22.15.18 '@vitest/coverage-v8': specifier: ^3.1.3 - version: 3.1.3(vitest@3.1.3) + version: 3.1.3(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@vitest/ui': specifier: ^3.1.3 - version: 3.1.3(vitest@3.1.3) + version: 3.1.3(vitest@3.2.4) eslint: specifier: ^9.26.0 version: 9.26.0(jiti@2.4.2) memfs: - specifier: ^4.17.1 + specifier: ^4.17.2 version: 4.17.2 msw: specifier: ^2.8.2 @@ -312,13 +315,13 @@ importers: version: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vitest: specifier: ^3.1.3 - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) packages/eslint-config: dependencies: '@antfu/eslint-config': specifier: ~3.6.0 - version: 3.6.2(@typescript-eslint/utils@8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(@vue/compiler-sfc@3.5.21)(astro-eslint-parser@1.2.2)(eslint-plugin-astro@1.3.1(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-format@0.1.3(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-react-refresh@0.4.20(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-svelte@3.7.0(eslint@9.26.0(jiti@2.4.2))(svelte@5.38.7)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.1.0)(typescript@5.8.3)))(eslint@9.26.0(jiti@2.4.2))(prettier-plugin-astro@0.13.0)(svelte@5.38.7)(typescript@5.8.3)(vitest@3.1.3) + version: 3.6.2(@typescript-eslint/utils@8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(@vue/compiler-sfc@3.5.21)(astro-eslint-parser@1.2.2)(eslint-plugin-astro@1.3.1(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-format@0.1.3(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-react-refresh@0.4.20(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-svelte@3.7.0(eslint@9.26.0(jiti@2.4.2))(svelte@5.38.7)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.3.1)(typescript@5.8.3)))(eslint@9.26.0(jiti@2.4.2))(prettier-plugin-astro@0.13.0)(svelte@5.38.7)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) eslint-plugin-format: specifier: ^0.1.2 version: 0.1.3(eslint@9.26.0(jiti@2.4.2)) @@ -350,7 +353,7 @@ importers: version: 22.15.18 '@vitest/ui': specifier: ^3.1.3 - version: 3.1.3(vitest@3.1.3) + version: 3.1.3(vitest@3.2.4) cypress: specifier: ^14.3.3 version: 14.3.3 @@ -389,7 +392,7 @@ importers: version: 0.2.4(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.1.3 - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) packages/js-client: devDependencies: @@ -399,15 +402,21 @@ importers: '@storyblok/eslint-config': specifier: workspace:* version: link:../eslint-config + '@storyblok/openapi': + specifier: workspace:* + version: link:../openapi + '@storyblok/test-utils': + specifier: workspace:* + version: link:../test-utils '@tsconfig/recommended': specifier: ^1.0.8 version: 1.0.8 '@vitest/coverage-v8': specifier: ^3.1.3 - version: 3.1.3(vitest@3.1.3) + version: 3.1.3(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@vitest/ui': specifier: ^3.1.3 - version: 3.1.3(vitest@3.1.3) + version: 3.1.3(vitest@3.2.4) eslint: specifier: ^9.26.0 version: 9.26.0(jiti@2.4.2) @@ -419,10 +428,10 @@ importers: version: 5.8.3 vite: specifier: ^7.0.6 - version: 7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vitest: specifier: ^3.1.3 - version: 3.1.3(@types/debug@4.1.12)(@types/node@24.1.0)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.1.0)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) packages/js-client/playground/nextjs: devDependencies: @@ -459,7 +468,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + version: 3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) '@tsconfig/svelte': specifier: ^5.0.4 version: 5.0.4 @@ -471,10 +480,10 @@ importers: version: 4.2.19 vite: specifier: ^5.4.11 - version: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + version: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) vite-plugin-qrcode: specifier: ^0.2.3 - version: 0.2.4(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + version: 0.2.4(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) packages/js-client/playground/vanilla: dependencies: @@ -484,7 +493,7 @@ importers: devDependencies: '@tailwindcss/vite': specifier: ^4.1.4 - version: 4.1.10(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + version: 4.1.10(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) pathe: specifier: ^1.1.2 version: 1.1.2 @@ -496,10 +505,10 @@ importers: version: 5.8.3 vite: specifier: ^5.4.11 - version: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + version: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) vite-plugin-qrcode: specifier: ^0.2.3 - version: 0.2.4(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + version: 0.2.4(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) packages/js/playground/vanilla: devDependencies: @@ -508,13 +517,13 @@ importers: version: link:../.. '@vitejs/plugin-basic-ssl': specifier: ^1.1.0 - version: 1.2.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 1.2.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) vite: specifier: ^6.0.1 - version: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vite-plugin-qrcode: specifier: ^0.2.3 - version: 0.2.4(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 0.2.4(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) packages/js/playground/vue: devDependencies: @@ -523,19 +532,19 @@ importers: version: link:../.. '@vitejs/plugin-basic-ssl': specifier: ^1.1.0 - version: 1.2.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 1.2.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@vitejs/plugin-vue': specifier: ^5.1.4 - version: 5.2.4(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)) + version: 5.2.4(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)) '@vue/tsconfig': specifier: ^0.7.0 version: 0.7.0(typescript@5.8.3)(vue@3.5.21(typescript@5.8.3)) vite: specifier: ^6.0.1 - version: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vite-plugin-qrcode: specifier: ^0.2.3 - version: 0.2.4(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 0.2.4(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) vue: specifier: ^3.5.12 version: 3.5.21(typescript@5.8.3) @@ -554,7 +563,7 @@ importers: version: link:../openapi '@types/node': specifier: ^24.1.0 - version: 24.1.0 + version: 24.3.1 change-case: specifier: ^5.4.4 version: 5.4.4 @@ -572,7 +581,7 @@ importers: version: 4.20.3 vitest: specifier: ^3.1.3 - version: 3.1.3(@types/debug@4.1.12)(@types/node@24.1.0)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.1.0)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) packages/nuxt: dependencies: @@ -600,7 +609,7 @@ importers: version: 3.17.3 '@nuxt/test-utils': specifier: ^3.15.4 - version: 3.19.0(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(magicast@0.3.5)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(vitest@3.1.3)(yaml@2.8.0) + version: 3.19.0(@playwright/test@1.55.0)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(magicast@0.3.5)(playwright-core@1.55.0)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(yaml@2.8.0) '@nuxtjs/eslint-config-typescript': specifier: ^12.1.0 version: 12.1.0(eslint-plugin-import-x@4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3) @@ -729,7 +738,7 @@ importers: version: 4.5.3(@types/node@22.15.18)(rollup@4.40.2)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.1.3 - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) packages/react/playground/next13: dependencies: @@ -794,7 +803,7 @@ importers: version: 0.5.16(tailwindcss@4.1.10) next: specifier: 15.3.2 - version: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: 19.1.0 version: 19.1.0 @@ -802,6 +811,15 @@ importers: specifier: 19.1.0 version: 19.1.0(react@19.1.0) devDependencies: + '@playwright/test': + specifier: ^1.55.0 + version: 1.55.0 + '@storyblok/openapi': + specifier: workspace:* + version: link:../../../openapi + '@storyblok/test-utils': + specifier: workspace:* + version: link:../../../test-utils '@tailwindcss/postcss': specifier: ^4.1.10 version: 4.1.10 @@ -831,7 +849,7 @@ importers: version: 0.5.16(tailwindcss@4.1.10) next: specifier: 15.3.2 - version: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + version: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: specifier: 19.1.0 version: 19.1.0 @@ -902,7 +920,7 @@ importers: version: 22.15.18 '@vitest/coverage-v8': specifier: ^3.1.3 - version: 3.1.3(vitest@3.1.3) + version: 3.1.3(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) eslint: specifier: ^9.26.0 version: 9.26.0(jiti@2.4.2) @@ -923,7 +941,7 @@ importers: version: 3.5.0(typescript@5.8.3)(vue-tsc@2.2.10(typescript@5.8.3))(vue@3.5.21(typescript@5.8.3)) vitest: specifier: ^3.1.3 - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) packages/richtext: dependencies: @@ -942,7 +960,7 @@ importers: version: 0.18.2 '@commitlint/cli': specifier: ^19.8.1 - version: 19.8.1(@types/node@24.1.0)(typescript@5.8.3) + version: 19.8.1(@types/node@24.3.1)(typescript@5.8.3) '@commitlint/config-conventional': specifier: ^19.8.1 version: 19.8.1 @@ -954,10 +972,10 @@ importers: version: 14.1.2 '@vitest/coverage-v8': specifier: ^3.1.3 - version: 3.1.3(vitest@3.1.3) + version: 3.1.3(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@vitest/ui': specifier: ^3.1.3 - version: 3.1.3(vitest@3.1.3) + version: 3.1.3(vitest@3.2.4) eslint: specifier: ^9.26.0 version: 9.26.0(jiti@2.4.2) @@ -981,7 +999,7 @@ importers: version: 3.5.3 release-it: specifier: ^18.1.2 - version: 18.1.2(@types/node@24.1.0)(typescript@5.8.3) + version: 18.1.2(@types/node@24.3.1)(typescript@5.8.3) tsdown: specifier: ^0.12.9 version: 0.12.9(@arethetypeswrong/core@0.18.2)(publint@0.3.12)(typescript@5.8.3)(vue-tsc@2.2.10(typescript@5.8.3)) @@ -990,7 +1008,7 @@ importers: version: 5.8.3 vitest: specifier: ^3.1.3 - version: 3.1.3(@types/debug@4.1.12)(@types/node@24.1.0)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.1.0)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vue: specifier: ^3.5.13 version: 3.5.21(typescript@5.8.3) @@ -1002,7 +1020,7 @@ importers: version: link:../../../astro astro: specifier: ^5.5.3 - version: 5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + version: 5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) packages/richtext/playground/node: dependencies: @@ -1017,7 +1035,7 @@ importers: version: link:../../../react '@vitejs/plugin-basic-ssl': specifier: ^2.1.0 - version: 2.1.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 2.1.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) react: specifier: ^19.1.0 version: 19.1.1 @@ -1026,7 +1044,7 @@ importers: version: 19.1.1(react@19.1.1) vite-plugin-qrcode: specifier: ^0.3.0 - version: 0.3.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 0.3.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) devDependencies: '@types/react': specifier: ^19.1.0 @@ -1042,7 +1060,7 @@ importers: version: 8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3) '@vitejs/plugin-react-swc': specifier: ^3.7.1 - version: 3.9.0(@swc/helpers@0.5.17)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 3.9.0(@swc/helpers@0.5.17)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) eslint: specifier: ^9.13.0 version: 9.26.0(jiti@2.4.2) @@ -1057,7 +1075,7 @@ importers: version: 5.8.3 vite: specifier: ^6.2.4 - version: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) packages/richtext/playground/vanilla: dependencies: @@ -1066,7 +1084,7 @@ importers: version: link:../.. '@vitejs/plugin-basic-ssl': specifier: ^2.1.0 - version: 2.1.0(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + version: 2.1.0(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) storyblok-js-client: specifier: workspace:* version: link:../../../js-client @@ -1076,10 +1094,10 @@ importers: version: 5.8.3 vite: specifier: ^5.4.10 - version: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + version: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) vite-plugin-qrcode: specifier: ^0.2.4 - version: 0.2.4(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + version: 0.2.4(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) packages/richtext/playground/vue: dependencies: @@ -1091,10 +1109,10 @@ importers: version: link:../../../vue '@vitejs/plugin-basic-ssl': specifier: ^2.1.0 - version: 2.1.0(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + version: 2.1.0(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) vite-plugin-qrcode: specifier: ^0.3.0 - version: 0.3.0(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + version: 0.3.0(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) vue: specifier: ^3.4.21 version: 3.5.21(typescript@5.8.3) @@ -1104,13 +1122,13 @@ importers: devDependencies: '@vitejs/plugin-vue': specifier: ^5.1.4 - version: 5.2.4(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2))(vue@3.5.21(typescript@5.8.3)) + version: 5.2.4(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2))(vue@3.5.21(typescript@5.8.3)) typescript: specifier: ^5.6.3 version: 5.8.3 vite: specifier: ^5.4.10 - version: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + version: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) vue-tsc: specifier: ^2.1.8 version: 2.2.10(typescript@5.8.3) @@ -1135,16 +1153,16 @@ importers: version: link:../eslint-config '@sveltejs/adapter-auto': specifier: ^5.0.0 - version: 5.0.0(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))) + version: 5.0.0(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))) '@sveltejs/kit': specifier: ^2.20.2 - version: 2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@sveltejs/package': specifier: ^2.3.10 version: 2.3.11(svelte@5.38.7)(typescript@5.8.3) '@sveltejs/vite-plugin-svelte': specifier: ^5.0.3 - version: 5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) cypress: specifier: ^14.3.3 version: 14.3.3 @@ -1153,7 +1171,7 @@ importers: version: 9.26.0(jiti@2.4.2) eslint-plugin-svelte: specifier: ^3.3.3 - version: 3.7.0(eslint@9.26.0(jiti@2.4.2))(svelte@5.38.7)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.1.0)(typescript@5.8.3)) + version: 3.7.0(eslint@9.26.0(jiti@2.4.2))(svelte@5.38.7)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.3.1)(typescript@5.8.3)) jsdom: specifier: ^26.0.0 version: 26.1.0 @@ -1180,13 +1198,13 @@ importers: version: 8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3) vite: specifier: ^6.3.5 - version: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vite-plugin-dts: specifier: ^4.5.3 - version: 4.5.3(@types/node@24.1.0)(rollup@4.40.2)(typescript@5.8.3)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 4.5.3(@types/node@24.3.1)(rollup@4.40.2)(typescript@5.8.3)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.1.3 - version: 3.1.3(@types/debug@4.1.12)(@types/node@24.1.0)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.1.0)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) packages/svelte/playground/sveltekit: dependencies: @@ -1196,16 +1214,16 @@ importers: devDependencies: '@sveltejs/adapter-auto': specifier: ^5.0.0 - version: 5.0.0(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))) + version: 5.0.0(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))) '@sveltejs/kit': specifier: ^2.20.2 - version: 2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@sveltejs/vite-plugin-svelte': specifier: ^5.0.3 - version: 5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@vitejs/plugin-basic-ssl': specifier: ^2.0.0 - version: 2.1.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 2.1.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) svelte: specifier: ^5.25.3 version: 5.38.7 @@ -1217,7 +1235,32 @@ importers: version: 5.8.3 vite: specifier: ^6.2.3 - version: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + + packages/test-utils: + dependencies: + '@faker-js/faker': + specifier: ^10.0.0 + version: 10.0.0 + '@playwright/test': + specifier: ^1.55.0 + version: 1.55.0 + '@storyblok/management-api-client': + specifier: workspace:* + version: link:../mapi-client + lodash.merge: + specifier: ^4.6.2 + version: 4.6.2 + vitest: + specifier: ^3.2.4 + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + devDependencies: + '@types/lodash.merge': + specifier: ^4.6.9 + version: 4.6.9 + '@types/node': + specifier: ^24.3.1 + version: 24.3.1 packages/vue: dependencies: @@ -1269,7 +1312,7 @@ importers: version: 4.5.3(@types/node@22.15.18)(rollup@4.40.2)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.1.3 - version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vue: specifier: ^3.5.13 version: 3.5.21(typescript@5.8.3) @@ -1297,13 +1340,13 @@ importers: version: 0.5.16(tailwindcss@4.1.10) '@tailwindcss/vite': specifier: ^4.1.10 - version: 4.1.10(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 4.1.10(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@vitejs/plugin-basic-ssl': specifier: ^1.2.0 - version: 1.2.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + version: 1.2.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@vitejs/plugin-vue': specifier: ^5.2.1 - version: 5.2.4(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.6.3)) + version: 5.2.4(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.6.3)) tailwindcss: specifier: ^4.1.10 version: 4.1.10 @@ -1312,7 +1355,7 @@ importers: version: 5.6.3 vite: specifier: ^6.0.1 - version: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + version: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vue-tsc: specifier: ^2.1.10 version: 2.2.10(typescript@5.6.3) @@ -3017,6 +3060,10 @@ packages: '@exodus/schemasafe@1.3.0': resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==} + '@faker-js/faker@10.0.0': + resolution: {integrity: sha512-UollFEUkVXutsaP+Vndjxar40Gs5JL2HeLcl8xO1QAjJgOdhc3OmBFWyEylS+RddWaaBiAzH+5/17PLQJwDiLw==} + engines: {node: ^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0, npm: '>=10'} + '@faker-js/faker@7.6.0': resolution: {integrity: sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==} engines: {node: '>=14.0.0', npm: '>=6.0.0'} @@ -4438,6 +4485,11 @@ packages: resolution: {integrity: sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@playwright/test@1.55.0': + resolution: {integrity: sha512-04IXzPwHrW69XusN/SIdDdKZBzMfOT9UNT/YiJit/xpy2VuAoB8NHc8Aplb96zsWDddLnbkPL3TsmrS04ZU2xQ==} + engines: {node: '>=18'} + hasBin: true + '@pnpm/config.env-replace@1.1.0': resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} engines: {node: '>=12.22.0'} @@ -5253,6 +5305,9 @@ packages: '@types/babel__traverse@7.20.7': resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@types/chai@5.2.2': + resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + '@types/cli-progress@3.11.6': resolution: {integrity: sha512-cE3+jb9WRlu+uOSAugewNpITJDt1VF8dHOopPO4IABFc3SXYL5WE/+PTz/FCdZRRfIujiWW3n3aMbv1eIGVRWA==} @@ -5265,6 +5320,9 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/eslint@9.6.1': resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} @@ -5304,6 +5362,9 @@ packages: '@types/linkify-it@5.0.0': resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + '@types/lodash.merge@4.6.9': + resolution: {integrity: sha512-23sHDPmzd59kUgWyKGiOMO2Qb9YtqRO/x4IhkgNUiPQ1+5MUVqi6bCZeq9nBJ17msjIMbEIO5u+XW4Kz6aGUhQ==} + '@types/lodash.mergewith@4.6.9': resolution: {integrity: sha512-fgkoCAOF47K7sxrQ7Mlud2TH023itugZs2bUg8h/KzT+BnZNrR2jAOmaokbLunHNnobXVWOezAeNn/lZqwxkcw==} @@ -5334,8 +5395,8 @@ packages: '@types/node@22.15.18': resolution: {integrity: sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg==} - '@types/node@24.1.0': - resolution: {integrity: sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==} + '@types/node@24.3.1': + resolution: {integrity: sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -5814,14 +5875,14 @@ packages: vitest: optional: true - '@vitest/expect@3.1.3': - resolution: {integrity: sha512-7FTQQuuLKmN1Ig/h+h/GO+44Q1IlglPlR2es4ab7Yvfx+Uk5xsv+Ykk+MEt/M2Yn/xGmzaLKxGw2lgy2bwuYqg==} + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - '@vitest/mocker@3.1.3': - resolution: {integrity: sha512-PJbLjonJK82uCWHjzgBJZuR7zmAOrSvKk1QBxrennDIgtH4uK0TB1PvYmc0XBCigxxtiAVPfWtAdy4lpz8SQGQ==} + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} peerDependencies: msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: msw: optional: true @@ -5831,14 +5892,17 @@ packages: '@vitest/pretty-format@3.1.3': resolution: {integrity: sha512-i6FDiBeJUGLDKADw2Gb01UtUNb12yyXAqC/mmRWuYl+m/U9GS7s8us5ONmGkGpUUo7/iAYzI2ePVfOZTYvUifA==} - '@vitest/runner@3.1.3': - resolution: {integrity: sha512-Tae+ogtlNfFei5DggOsSUvkIaSuVywujMj6HzR97AHK6XK8i3BuVyIifWAm/sE3a15lF5RH9yQIrbXYuo0IFyA==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - '@vitest/snapshot@3.1.3': - resolution: {integrity: sha512-XVa5OPNTYUsyqG9skuUkFzAeFnEzDp8hQu7kZ0N25B1+6KjGm4hWLtURyBbsIAOekfWQ7Wuz/N/XXzgYO3deWQ==} + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - '@vitest/spy@3.1.3': - resolution: {integrity: sha512-x6w+ctOEmEXdWaa6TO4ilb7l9DxPR5bwEb6hILKuxfU1NqWT2mpJD9NJN7t3OTfxmVlOMrvtoFJGdgyzZ605lQ==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} '@vitest/ui@3.1.3': resolution: {integrity: sha512-IipSzX+8DptUdXN/GWq3hq5z18MwnpphYdOMm0WndkRGYELzfq7NDP8dMpZT7JGW1uXFrIGxOW2D0Xi++ulByg==} @@ -5848,6 +5912,9 @@ packages: '@vitest/utils@3.1.3': resolution: {integrity: sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@volar/language-core@2.4.13': resolution: {integrity: sha512-MnQJ7eKchJx5Oz+YdbqyFUk8BN6jasdJv31n/7r6/WwlOOv7qzvot6B66887l2ST3bUW4Mewml54euzpJWA6bg==} @@ -8556,6 +8623,11 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + 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} @@ -9907,6 +9979,9 @@ packages: loupe@3.1.3: resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -11084,6 +11159,16 @@ packages: playground@file:packages/js-client/playground: resolution: {directory: packages/js-client/playground, type: directory} + playwright-core@1.55.0: + resolution: {integrity: sha512-GvZs4vU3U5ro2nZpeiwyb0zuFaqb9sUiAJuyrWpcGouD8y9/HLgGbNRjIph7zU9D3hnPaisMl9zG9CgFi/biIg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.55.0: + resolution: {integrity: sha512-sdCWStblvV1YU909Xqx0DhOjPZE4/5lJsIS84IfN9dAZfcl/CIZ5O8l3o0j7hPMjDvqoTF8ZUcc+i/GL5erstA==} + engines: {node: '>=18'} + hasBin: true + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -12589,16 +12674,16 @@ packages: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} - tinypool@1.0.2: - resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} tinyrainbow@2.0.0: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} - tinyspy@3.0.2: - resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + tinyspy@4.0.3: + resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} engines: {node: '>=14.0.0'} tldts-core@6.1.86: @@ -12910,8 +12995,8 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.8.0: - resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + undici-types@7.10.0: + resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} undici@6.21.1: resolution: {integrity: sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==} @@ -13207,8 +13292,8 @@ packages: peerDependencies: vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 - vite-node@3.1.3: - resolution: {integrity: sha512-uHV4plJ2IxCl4u1up1FQRrqclylKAogbtBfOTwcuJ28xFi+89PZ57BRh+naIRvH70HPwxy5QHYzg1OrEaC7AbA==} + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true @@ -13449,16 +13534,16 @@ packages: vitest-environment-nuxt@1.0.1: resolution: {integrity: sha512-eBCwtIQriXW5/M49FjqNKfnlJYlG2LWMSNFsRVKomc8CaMqmhQPBS5LZ9DlgYL9T8xIVsiA6RZn2lk7vxov3Ow==} - vitest@3.1.3: - resolution: {integrity: sha512-188iM4hAHQ0km23TN/adso1q5hhwKqUpv+Sd6p5sOuh6FhQnRNW3IsiIpvxqahtBabsJ2SLZgmGSpcYK4wQYJw==} + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.1.3 - '@vitest/ui': 3.1.3 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -13826,7 +13911,7 @@ snapshots: '@andrewbranch/untar.js@1.0.3': {} - '@antfu/eslint-config@3.6.2(@typescript-eslint/utils@8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(@vue/compiler-sfc@3.5.21)(astro-eslint-parser@1.2.2)(eslint-plugin-astro@1.3.1(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-format@0.1.3(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-react-refresh@0.4.20(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-svelte@3.7.0(eslint@9.26.0(jiti@2.4.2))(svelte@5.38.7)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.1.0)(typescript@5.8.3)))(eslint@9.26.0(jiti@2.4.2))(prettier-plugin-astro@0.13.0)(svelte@5.38.7)(typescript@5.8.3)(vitest@3.1.3)': + '@antfu/eslint-config@3.6.2(@typescript-eslint/utils@8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(@vue/compiler-sfc@3.5.21)(astro-eslint-parser@1.2.2)(eslint-plugin-astro@1.3.1(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-format@0.1.3(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-react-refresh@0.4.20(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-svelte@3.7.0(eslint@9.26.0(jiti@2.4.2))(svelte@5.38.7)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.3.1)(typescript@5.8.3)))(eslint@9.26.0(jiti@2.4.2))(prettier-plugin-astro@0.13.0)(svelte@5.38.7)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: '@antfu/install-pkg': 0.4.1 '@clack/prompts': 0.7.0 @@ -13835,7 +13920,7 @@ snapshots: '@stylistic/eslint-plugin': 2.13.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/eslint-plugin': 8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/parser': 8.32.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3) - '@vitest/eslint-plugin': 1.1.44(@typescript-eslint/utils@8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3) + '@vitest/eslint-plugin': 1.1.44(@typescript-eslint/utils@8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) eslint: 9.26.0(jiti@2.4.2) eslint-config-flat-gitignore: 0.3.0(eslint@9.26.0(jiti@2.4.2)) eslint-flat-config-utils: 0.4.0 @@ -13869,7 +13954,7 @@ snapshots: eslint-plugin-astro: 1.3.1(eslint@9.26.0(jiti@2.4.2)) eslint-plugin-format: 0.1.3(eslint@9.26.0(jiti@2.4.2)) eslint-plugin-react-refresh: 0.4.20(eslint@9.26.0(jiti@2.4.2)) - eslint-plugin-svelte: 3.7.0(eslint@9.26.0(jiti@2.4.2))(svelte@5.38.7)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.1.0)(typescript@5.8.3)) + eslint-plugin-svelte: 3.7.0(eslint@9.26.0(jiti@2.4.2))(svelte@5.38.7)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.3.1)(typescript@5.8.3)) prettier-plugin-astro: 0.13.0 transitivePeerDependencies: - '@eslint/json' @@ -13955,15 +14040,15 @@ snapshots: dependencies: prismjs: 1.30.0 - '@astrojs/react@4.3.0(@types/node@24.1.0)(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)': + '@astrojs/react@4.3.0(@types/node@24.3.1)(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(jiti@2.4.2)(lightningcss@1.30.1)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)': dependencies: '@types/react': 19.1.4 '@types/react-dom': 19.1.5(@types/react@19.1.4) - '@vitejs/plugin-react': 4.4.1(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + '@vitejs/plugin-react': 4.4.1(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) react: 19.1.1 react-dom: 19.1.1(react@19.1.1) ultrahtml: 1.6.0 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -13978,14 +14063,14 @@ snapshots: - tsx - yaml - '@astrojs/svelte@7.1.0(@types/node@24.1.0)(astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(svelte@5.38.7)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)': + '@astrojs/svelte@7.1.0(@types/node@24.3.1)(astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(svelte@5.38.7)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0)': dependencies: - '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) - astro: 5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + astro: 5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) svelte: 5.38.7 svelte2tsx: 0.7.39(svelte@5.38.7)(typescript@5.8.3) typescript: 5.8.3 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -14012,14 +14097,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/vercel@8.2.7(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(rollup@4.40.2)(svelte@5.38.7)(vue-router@4.5.1(vue@3.5.21(typescript@5.8.3)))(vue@3.5.21(typescript@5.8.3))': + '@astrojs/vercel@8.2.7(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(rollup@4.40.2)(svelte@5.38.7)(vue-router@4.5.1(vue@3.5.21(typescript@5.8.3)))(vue@3.5.21(typescript@5.8.3))': dependencies: '@astrojs/internal-helpers': 0.7.2 - '@vercel/analytics': 1.5.0(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(svelte@5.38.7)(vue-router@4.5.1(vue@3.5.21(typescript@5.8.3)))(vue@3.5.21(typescript@5.8.3)) + '@vercel/analytics': 1.5.0(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(svelte@5.38.7)(vue-router@4.5.1(vue@3.5.21(typescript@5.8.3)))(vue@3.5.21(typescript@5.8.3)) '@vercel/functions': 2.2.13 '@vercel/nft': 0.29.3(rollup@4.40.2) '@vercel/routing-utils': 5.1.1 - astro: 5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + astro: 5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) esbuild: 0.25.4 tinyglobby: 0.2.14 transitivePeerDependencies: @@ -14035,14 +14120,14 @@ snapshots: - vue - vue-router - '@astrojs/vue@5.1.0(@types/node@24.1.0)(astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(vue@3.5.21(typescript@5.8.3))(yaml@2.8.0)': + '@astrojs/vue@5.1.0(@types/node@24.3.1)(astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0))(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(vue@3.5.21(typescript@5.8.3))(yaml@2.8.0)': dependencies: - '@vitejs/plugin-vue': 5.2.1(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)) - '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)) + '@vitejs/plugin-vue': 5.2.1(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)) + '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)) '@vue/compiler-sfc': 3.5.14 - astro: 5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vite-plugin-vue-devtools: 7.7.6(rollup@4.40.2)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)) + astro: 5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite-plugin-vue-devtools: 7.7.6(rollup@4.40.2)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)) vue: 3.5.21(typescript@5.8.3) transitivePeerDependencies: - '@nuxt/kit' @@ -14916,11 +15001,11 @@ snapshots: '@colors/colors@1.6.0': {} - '@commitlint/cli@19.8.1(@types/node@24.1.0)(typescript@5.8.3)': + '@commitlint/cli@19.8.1(@types/node@24.3.1)(typescript@5.8.3)': dependencies: '@commitlint/format': 19.8.1 '@commitlint/lint': 19.8.1 - '@commitlint/load': 19.8.1(@types/node@24.1.0)(typescript@5.8.3) + '@commitlint/load': 19.8.1(@types/node@24.3.1)(typescript@5.8.3) '@commitlint/read': 19.8.1 '@commitlint/types': 19.8.1 tinyexec: 1.0.1 @@ -14967,7 +15052,7 @@ snapshots: '@commitlint/rules': 19.8.1 '@commitlint/types': 19.8.1 - '@commitlint/load@19.8.1(@types/node@24.1.0)(typescript@5.8.3)': + '@commitlint/load@19.8.1(@types/node@24.3.1)(typescript@5.8.3)': dependencies: '@commitlint/config-validator': 19.8.1 '@commitlint/execute-rule': 19.8.1 @@ -14975,7 +15060,7 @@ snapshots: '@commitlint/types': 19.8.1 chalk: 5.4.1 cosmiconfig: 9.0.0(typescript@5.8.3) - cosmiconfig-typescript-loader: 6.1.0(@types/node@24.1.0)(cosmiconfig@9.0.0(typescript@5.8.3))(typescript@5.8.3) + cosmiconfig-typescript-loader: 6.1.0(@types/node@24.3.1)(cosmiconfig@9.0.0(typescript@5.8.3))(typescript@5.8.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -15582,6 +15667,8 @@ snapshots: '@exodus/schemasafe@1.3.0': {} + '@faker-js/faker@10.0.0': {} + '@faker-js/faker@7.6.0': {} '@fastify/busboy@3.1.1': {} @@ -15805,15 +15892,15 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/checkbox@4.1.8(@types/node@24.1.0)': + '@inquirer/checkbox@4.1.8(@types/node@24.3.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) + '@inquirer/core': 10.1.13(@types/node@24.3.1) '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/type': 3.0.7(@types/node@24.3.1) ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/confirm@5.1.12(@types/node@22.15.18)': dependencies: @@ -15822,12 +15909,12 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/confirm@5.1.12(@types/node@24.1.0)': + '@inquirer/confirm@5.1.12(@types/node@24.3.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/core': 10.1.13(@types/node@24.3.1) + '@inquirer/type': 3.0.7(@types/node@24.3.1) optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/core@10.1.13(@types/node@22.15.18)': dependencies: @@ -15842,10 +15929,10 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/core@10.1.13(@types/node@24.1.0)': + '@inquirer/core@10.1.13(@types/node@24.3.1)': dependencies: '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/type': 3.0.7(@types/node@24.3.1) ansi-escapes: 4.3.2 cli-width: 4.1.0 mute-stream: 2.0.0 @@ -15853,7 +15940,7 @@ snapshots: wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/editor@4.2.13(@types/node@22.15.18)': dependencies: @@ -15863,13 +15950,13 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/editor@4.2.13(@types/node@24.1.0)': + '@inquirer/editor@4.2.13(@types/node@24.3.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/core': 10.1.13(@types/node@24.3.1) + '@inquirer/type': 3.0.7(@types/node@24.3.1) external-editor: 3.1.0 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/expand@4.0.15(@types/node@22.15.18)': dependencies: @@ -15879,13 +15966,13 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/expand@4.0.15(@types/node@24.1.0)': + '@inquirer/expand@4.0.15(@types/node@24.3.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/core': 10.1.13(@types/node@24.3.1) + '@inquirer/type': 3.0.7(@types/node@24.3.1) yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/figures@1.0.12': {} @@ -15896,12 +15983,12 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/input@4.1.12(@types/node@24.1.0)': + '@inquirer/input@4.1.12(@types/node@24.3.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/core': 10.1.13(@types/node@24.3.1) + '@inquirer/type': 3.0.7(@types/node@24.3.1) optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/number@3.0.15(@types/node@22.15.18)': dependencies: @@ -15910,12 +15997,12 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/number@3.0.15(@types/node@24.1.0)': + '@inquirer/number@3.0.15(@types/node@24.3.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/core': 10.1.13(@types/node@24.3.1) + '@inquirer/type': 3.0.7(@types/node@24.3.1) optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/password@4.0.15(@types/node@22.15.18)': dependencies: @@ -15925,13 +16012,13 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/password@4.0.15(@types/node@24.1.0)': + '@inquirer/password@4.0.15(@types/node@24.3.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/core': 10.1.13(@types/node@24.3.1) + '@inquirer/type': 3.0.7(@types/node@24.3.1) ansi-escapes: 4.3.2 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/prompts@7.5.3(@types/node@22.15.18)': dependencies: @@ -15948,20 +16035,20 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/prompts@7.5.3(@types/node@24.1.0)': - dependencies: - '@inquirer/checkbox': 4.1.8(@types/node@24.1.0) - '@inquirer/confirm': 5.1.12(@types/node@24.1.0) - '@inquirer/editor': 4.2.13(@types/node@24.1.0) - '@inquirer/expand': 4.0.15(@types/node@24.1.0) - '@inquirer/input': 4.1.12(@types/node@24.1.0) - '@inquirer/number': 3.0.15(@types/node@24.1.0) - '@inquirer/password': 4.0.15(@types/node@24.1.0) - '@inquirer/rawlist': 4.1.3(@types/node@24.1.0) - '@inquirer/search': 3.0.15(@types/node@24.1.0) - '@inquirer/select': 4.2.3(@types/node@24.1.0) + '@inquirer/prompts@7.5.3(@types/node@24.3.1)': + dependencies: + '@inquirer/checkbox': 4.1.8(@types/node@24.3.1) + '@inquirer/confirm': 5.1.12(@types/node@24.3.1) + '@inquirer/editor': 4.2.13(@types/node@24.3.1) + '@inquirer/expand': 4.0.15(@types/node@24.3.1) + '@inquirer/input': 4.1.12(@types/node@24.3.1) + '@inquirer/number': 3.0.15(@types/node@24.3.1) + '@inquirer/password': 4.0.15(@types/node@24.3.1) + '@inquirer/rawlist': 4.1.3(@types/node@24.3.1) + '@inquirer/search': 3.0.15(@types/node@24.3.1) + '@inquirer/select': 4.2.3(@types/node@24.3.1) optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/rawlist@4.1.3(@types/node@22.15.18)': dependencies: @@ -15971,13 +16058,13 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/rawlist@4.1.3(@types/node@24.1.0)': + '@inquirer/rawlist@4.1.3(@types/node@24.3.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/core': 10.1.13(@types/node@24.3.1) + '@inquirer/type': 3.0.7(@types/node@24.3.1) yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/search@3.0.15(@types/node@22.15.18)': dependencies: @@ -15988,14 +16075,14 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/search@3.0.15(@types/node@24.1.0)': + '@inquirer/search@3.0.15(@types/node@24.3.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) + '@inquirer/core': 10.1.13(@types/node@24.3.1) '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/type': 3.0.7(@types/node@24.3.1) yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/select@4.2.3(@types/node@22.15.18)': dependencies: @@ -16007,23 +16094,23 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@inquirer/select@4.2.3(@types/node@24.1.0)': + '@inquirer/select@4.2.3(@types/node@24.3.1)': dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) + '@inquirer/core': 10.1.13(@types/node@24.3.1) '@inquirer/figures': 1.0.12 - '@inquirer/type': 3.0.7(@types/node@24.1.0) + '@inquirer/type': 3.0.7(@types/node@24.3.1) ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@inquirer/type@3.0.7(@types/node@22.15.18)': optionalDependencies: '@types/node': 22.15.18 - '@inquirer/type@3.0.7(@types/node@24.1.0)': + '@inquirer/type@3.0.7(@types/node@24.3.1)': optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@ioredis/commands@1.2.0': {} @@ -16273,11 +16360,11 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor-model@7.30.6(@types/node@24.1.0)': + '@microsoft/api-extractor-model@7.30.6(@types/node@24.3.1)': dependencies: '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.13.1(@types/node@24.1.0) + '@rushstack/node-core-library': 5.13.1(@types/node@24.3.1) transitivePeerDependencies: - '@types/node' @@ -16299,15 +16386,15 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.52.8(@types/node@24.1.0)': + '@microsoft/api-extractor@7.52.8(@types/node@24.3.1)': dependencies: - '@microsoft/api-extractor-model': 7.30.6(@types/node@24.1.0) + '@microsoft/api-extractor-model': 7.30.6(@types/node@24.3.1) '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.13.1(@types/node@24.1.0) + '@rushstack/node-core-library': 5.13.1(@types/node@24.3.1) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.15.3(@types/node@24.1.0) - '@rushstack/ts-command-line': 5.0.1(@types/node@24.1.0) + '@rushstack/terminal': 0.15.3(@types/node@24.3.1) + '@rushstack/ts-command-line': 5.0.1(@types/node@24.3.1) lodash: 4.17.21 minimatch: 3.0.8 resolve: 1.22.10 @@ -16779,7 +16866,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/test-utils@3.19.0(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(magicast@0.3.5)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(vitest@3.1.3)(yaml@2.8.0)': + '@nuxt/test-utils@3.19.0(@playwright/test@1.55.0)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(magicast@0.3.5)(playwright-core@1.55.0)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(yaml@2.8.0)': dependencies: '@nuxt/kit': 3.17.3(magicast@0.3.5) '@nuxt/schema': 3.17.3 @@ -16805,12 +16892,13 @@ snapshots: ufo: 1.6.1 unplugin: 2.3.4 vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vitest-environment-nuxt: 1.0.1(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(magicast@0.3.5)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(vitest@3.1.3)(yaml@2.8.0) + vitest-environment-nuxt: 1.0.1(@playwright/test@1.55.0)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(magicast@0.3.5)(playwright-core@1.55.0)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(yaml@2.8.0) vue: 3.5.21(typescript@5.8.3) optionalDependencies: - '@vitest/ui': 3.1.3(vitest@3.1.3) + '@playwright/test': 1.55.0 jsdom: 26.1.0 - vitest: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + playwright-core: 1.55.0 + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -16844,7 +16932,7 @@ snapshots: h3: 1.15.3 jiti: 2.4.2 knitwork: 1.2.0 - magic-string: 0.30.17 + magic-string: 0.30.18 mlly: 1.7.4 mocked-exports: 0.1.1 ohash: 2.0.11 @@ -16858,7 +16946,7 @@ snapshots: unenv: 2.0.0-rc.17 unplugin: 2.3.4 vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vite-node: 3.1.3(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vite-plugin-checker: 0.9.3(eslint@9.26.0(jiti@2.4.2))(meow@13.2.0)(optionator@0.9.4)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue-tsc@2.2.10(typescript@5.8.3)) vue: 3.5.21(typescript@5.8.3) vue-bundle-renderer: 2.1.1 @@ -16894,7 +16982,7 @@ snapshots: '@typescript-eslint/parser': 6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.26.0(jiti@2.4.2) eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.26.0(jiti@2.4.2)) eslint-plugin-vue: 9.33.0(eslint@9.26.0(jiti@2.4.2)) transitivePeerDependencies: - eslint-import-resolver-webpack @@ -16905,8 +16993,8 @@ snapshots: '@nuxtjs/eslint-config@12.0.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2))': dependencies: eslint: 9.26.0(jiti@2.4.2) - eslint-config-standard: 17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-n@15.7.0(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-promise@6.6.0(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)) + eslint-config-standard: 17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-n@15.7.0(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-promise@6.6.0(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.26.0(jiti@2.4.2)) eslint-plugin-n: 15.7.0(eslint@9.26.0(jiti@2.4.2)) eslint-plugin-node: 11.1.0(eslint@9.26.0(jiti@2.4.2)) eslint-plugin-promise: 6.6.0(eslint@9.26.0(jiti@2.4.2)) @@ -17430,6 +17518,10 @@ snapshots: '@pkgr/core@0.2.4': {} + '@playwright/test@1.55.0': + dependencies: + playwright: 1.55.0 + '@pnpm/config.env-replace@1.1.0': {} '@pnpm/network.ca-file@1.0.2': @@ -17665,7 +17757,7 @@ snapshots: estree-walker: 2.0.2 fdir: 6.4.4(picomatch@4.0.2) is-reference: 1.2.1 - magic-string: 0.30.17 + magic-string: 0.30.18 picomatch: 4.0.2 optionalDependencies: rollup: 4.40.2 @@ -17730,7 +17822,7 @@ snapshots: '@rollup/plugin-replace@6.0.2(rollup@4.40.2)': dependencies: '@rollup/pluginutils': 5.1.4(rollup@4.40.2) - magic-string: 0.30.17 + magic-string: 0.30.18 optionalDependencies: rollup: 4.40.2 @@ -17844,7 +17936,7 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@rushstack/node-core-library@5.13.1(@types/node@24.1.0)': + '@rushstack/node-core-library@5.13.1(@types/node@24.3.1)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -17855,7 +17947,7 @@ snapshots: resolve: 1.22.10 semver: 7.5.4 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@rushstack/rig-package@0.5.3': dependencies: @@ -17869,12 +17961,12 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - '@rushstack/terminal@0.15.3(@types/node@24.1.0)': + '@rushstack/terminal@0.15.3(@types/node@24.3.1)': dependencies: - '@rushstack/node-core-library': 5.13.1(@types/node@24.1.0) + '@rushstack/node-core-library': 5.13.1(@types/node@24.3.1) supports-color: 8.1.1 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 '@rushstack/ts-command-line@5.0.1(@types/node@22.15.18)': dependencies: @@ -17885,9 +17977,9 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@rushstack/ts-command-line@5.0.1(@types/node@24.1.0)': + '@rushstack/ts-command-line@5.0.1(@types/node@24.3.1)': dependencies: - '@rushstack/terminal': 0.15.3(@types/node@24.1.0) + '@rushstack/terminal': 0.15.3(@types/node@24.3.1) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -17976,7 +18068,7 @@ snapshots: eslint-visitor-keys: 4.2.0 espree: 10.3.0 estraverse: 5.3.0 - picomatch: 4.0.2 + picomatch: 4.0.3 transitivePeerDependencies: - supports-color - typescript @@ -17985,15 +18077,15 @@ snapshots: dependencies: acorn: 8.14.1 - '@sveltejs/adapter-auto@5.0.0(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))': + '@sveltejs/adapter-auto@5.0.0(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))': dependencies: - '@sveltejs/kit': 2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + '@sveltejs/kit': 2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) import-meta-resolve: 4.1.0 - '@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: '@sveltejs/acorn-typescript': 1.0.5(acorn@8.14.1) - '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@types/cookie': 0.6.0 acorn: 8.14.1 cookie: 0.6.0 @@ -18006,12 +18098,12 @@ snapshots: set-cookie-parser: 2.7.1 sirv: 3.0.1 svelte: 5.38.7 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - '@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: '@sveltejs/acorn-typescript': 1.0.5(acorn@8.14.1) - '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) '@types/cookie': 0.6.0 acorn: 8.14.1 cookie: 0.6.0 @@ -18024,7 +18116,7 @@ snapshots: set-cookie-parser: 2.7.1 sirv: 3.0.1 svelte: 5.38.7 - vite: 7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) optional: true '@sveltejs/package@2.3.11(svelte@5.38.7)(typescript@5.8.3)': @@ -18038,71 +18130,71 @@ snapshots: transitivePeerDependencies: - typescript - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)))(svelte@4.2.19)(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)))(svelte@4.2.19)(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) debug: 4.4.1(supports-color@8.1.1) svelte: 4.2.19 - vite: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + vite: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) debug: 4.4.1(supports-color@8.1.1) svelte: 5.38.7 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) debug: 4.4.1(supports-color@8.1.1) svelte: 5.38.7 - vite: 7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - supports-color optional: true - '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)))(svelte@4.2.19)(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)))(svelte@4.2.19)(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) debug: 4.4.1(supports-color@8.1.1) deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 svelte: 4.2.19 svelte-hmr: 0.16.0(svelte@4.2.19) - vite: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) - vitefu: 0.2.5(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)) + vite: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) + vitefu: 0.2.5(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) debug: 4.4.1(supports-color@8.1.1) deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 svelte: 5.38.7 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vitefu: 1.0.6(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vitefu: 1.0.6(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) debug: 4.4.1(supports-color@8.1.1) deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 svelte: 5.38.7 - vite: 7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vitefu: 1.0.6(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + vite: 7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vitefu: 1.0.6(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) transitivePeerDependencies: - supports-color optional: true @@ -18178,7 +18270,7 @@ snapshots: enhanced-resolve: 5.18.1 jiti: 2.4.2 lightningcss: 1.30.1 - magic-string: 0.30.17 + magic-string: 0.30.18 source-map-js: 1.2.1 tailwindcss: 4.1.10 @@ -18252,12 +18344,12 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 4.1.10 - '@tailwindcss/vite@4.1.10(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2))': + '@tailwindcss/vite@4.1.10(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2))': dependencies: '@tailwindcss/node': 4.1.10 '@tailwindcss/oxide': 4.1.10 tailwindcss: 4.1.10 - vite: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + vite: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) '@tailwindcss/vite@4.1.10(vite@6.3.5(@types/node@20.17.47)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: @@ -18266,12 +18358,12 @@ snapshots: tailwindcss: 4.1.10 vite: 6.3.5(@types/node@20.17.47)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - '@tailwindcss/vite@4.1.10(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@tailwindcss/vite@4.1.10(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: '@tailwindcss/node': 4.1.10 '@tailwindcss/oxide': 4.1.10 tailwindcss: 4.1.10 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) '@testing-library/dom@10.4.0': dependencies: @@ -18371,6 +18463,10 @@ snapshots: dependencies: '@babel/types': 7.28.2 + '@types/chai@5.2.2': + dependencies: + '@types/deep-eql': 4.0.2 + '@types/cli-progress@3.11.6': dependencies: '@types/node': 20.17.47 @@ -18385,6 +18481,8 @@ snapshots: dependencies: '@types/ms': 2.1.0 + '@types/deep-eql@4.0.2': {} + '@types/eslint@9.6.1': dependencies: '@types/estree': 1.0.7 @@ -18427,6 +18525,10 @@ snapshots: '@types/linkify-it@5.0.0': {} + '@types/lodash.merge@4.6.9': + dependencies: + '@types/lodash': 4.17.16 + '@types/lodash.mergewith@4.6.9': dependencies: '@types/lodash': 4.17.16 @@ -18462,9 +18564,9 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@24.1.0': + '@types/node@24.3.1': dependencies: - undici-types: 7.8.0 + undici-types: 7.10.0 '@types/normalize-package-data@2.4.4': {} @@ -18971,10 +19073,10 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.7.2': optional: true - '@vercel/analytics@1.5.0(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(svelte@5.38.7)(vue-router@4.5.1(vue@3.5.21(typescript@5.8.3)))(vue@3.5.21(typescript@5.8.3))': + '@vercel/analytics@1.5.0(@sveltejs/kit@2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)(svelte@5.38.7)(vue-router@4.5.1(vue@3.5.21(typescript@5.8.3)))(vue@3.5.21(typescript@5.8.3))': optionalDependencies: - '@sveltejs/kit': 2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) - next: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@sveltejs/kit': 2.21.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)))(svelte@5.38.7)(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + next: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: 19.1.1 svelte: 5.38.7 vue: 3.5.21(typescript@5.8.3) @@ -19034,26 +19136,26 @@ snapshots: optionalDependencies: ajv: 6.12.6 - '@vitejs/plugin-basic-ssl@1.2.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@vitejs/plugin-basic-ssl@1.2.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - '@vitejs/plugin-basic-ssl@2.1.0(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2))': + '@vitejs/plugin-basic-ssl@2.1.0(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2))': dependencies: - vite: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + vite: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) '@vitejs/plugin-basic-ssl@2.1.0(vite@6.3.5(@types/node@20.17.47)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: vite: 6.3.5(@types/node@20.17.47)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - '@vitejs/plugin-basic-ssl@2.1.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@vitejs/plugin-basic-ssl@2.1.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - '@vitejs/plugin-react-swc@3.9.0(@swc/helpers@0.5.17)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@vitejs/plugin-react-swc@3.9.0(@swc/helpers@0.5.17)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: '@swc/core': 1.11.24(@swc/helpers@0.5.17) - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - '@swc/helpers' @@ -19068,14 +19170,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.4.1(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@vitejs/plugin-react@4.4.1(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: '@babel/core': 7.27.1 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.27.1) '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.27.1) '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - supports-color @@ -19089,25 +19191,25 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@4.2.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3))': + '@vitejs/plugin-vue-jsx@4.2.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3))': dependencies: '@babel/core': 7.27.1 '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.1) '@rolldown/pluginutils': 1.0.0-beta.31 '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.27.1) - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vue: 3.5.21(typescript@5.8.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.1(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3))': + '@vitejs/plugin-vue@5.2.1(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3))': dependencies: - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vue: 3.5.21(typescript@5.8.3) - '@vitejs/plugin-vue@5.2.4(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2))(vue@3.5.21(typescript@5.8.3))': + '@vitejs/plugin-vue@5.2.4(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2))(vue@3.5.21(typescript@5.8.3))': dependencies: - vite: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + vite: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) vue: 3.5.21(typescript@5.8.3) '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3))': @@ -19115,17 +19217,17 @@ snapshots: vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vue: 3.5.21(typescript@5.8.3) - '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.6.3))': + '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.6.3))': dependencies: - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vue: 3.5.21(typescript@5.6.3) - '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3))': + '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3))': dependencies: - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vue: 3.5.21(typescript@5.8.3) - '@vitest/coverage-v8@3.1.3(vitest@3.1.3)': + '@vitest/coverage-v8@3.1.3(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -19139,63 +19241,69 @@ snapshots: std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - supports-color - '@vitest/eslint-plugin@1.1.44(@typescript-eslint/utils@8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.1.3)': + '@vitest/eslint-plugin@1.1.44(@typescript-eslint/utils@8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: '@typescript-eslint/utils': 8.37.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.26.0(jiti@2.4.2) optionalDependencies: typescript: 5.8.3 - vitest: 3.1.3(@types/debug@4.1.12)(@types/node@24.1.0)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.1.0)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - '@vitest/expect@3.1.3': + '@vitest/expect@3.2.4': dependencies: - '@vitest/spy': 3.1.3 - '@vitest/utils': 3.1.3 + '@types/chai': 5.2.2 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.1.3(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@vitest/mocker@3.2.4(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: - '@vitest/spy': 3.1.3 + '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.18 optionalDependencies: msw: 2.10.2(@types/node@22.15.18)(typescript@5.8.3) vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - '@vitest/mocker@3.1.3(msw@2.10.2(@types/node@24.1.0)(typescript@5.8.3))(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': + '@vitest/mocker@3.2.4(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))': dependencies: - '@vitest/spy': 3.1.3 + '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.18 optionalDependencies: - msw: 2.10.2(@types/node@24.1.0)(typescript@5.8.3) - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + msw: 2.10.2(@types/node@24.3.1)(typescript@5.8.3) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) '@vitest/pretty-format@3.1.3': dependencies: tinyrainbow: 2.0.0 - '@vitest/runner@3.1.3': + '@vitest/pretty-format@3.2.4': dependencies: - '@vitest/utils': 3.1.3 + tinyrainbow: 2.0.0 + + '@vitest/runner@3.2.4': + dependencies: + '@vitest/utils': 3.2.4 pathe: 2.0.3 + strip-literal: 3.0.0 - '@vitest/snapshot@3.1.3': + '@vitest/snapshot@3.2.4': dependencies: - '@vitest/pretty-format': 3.1.3 - magic-string: 0.30.17 + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.18 pathe: 2.0.3 - '@vitest/spy@3.1.3': + '@vitest/spy@3.2.4': dependencies: - tinyspy: 3.0.2 + tinyspy: 4.0.3 - '@vitest/ui@3.1.3(vitest@3.1.3)': + '@vitest/ui@3.1.3(vitest@3.2.4)': dependencies: '@vitest/utils': 3.1.3 fflate: 0.8.2 @@ -19204,7 +19312,7 @@ snapshots: sirv: 3.0.1 tinyglobby: 0.2.13 tinyrainbow: 2.0.0 - vitest: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) '@vitest/utils@3.1.3': dependencies: @@ -19212,6 +19320,12 @@ snapshots: loupe: 3.1.3 tinyrainbow: 2.0.0 + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + '@volar/language-core@2.4.13': dependencies: '@volar/source-map': 2.4.13 @@ -19298,7 +19412,7 @@ snapshots: '@vue/compiler-ssr': 3.5.14 '@vue/shared': 3.5.14 estree-walker: 2.0.2 - magic-string: 0.30.17 + magic-string: 0.30.18 postcss: 8.5.6 source-map-js: 1.2.1 @@ -19343,14 +19457,14 @@ snapshots: transitivePeerDependencies: - vite - '@vue/devtools-core@7.7.6(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3))': + '@vue/devtools-core@7.7.6(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3))': dependencies: '@vue/devtools-kit': 7.7.6 '@vue/devtools-shared': 7.7.6 mitt: 3.0.1 nanoid: 5.1.5 pathe: 2.0.3 - vite-hot-client: 2.0.4(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + vite-hot-client: 2.0.4(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) vue: 3.5.21(typescript@5.8.3) transitivePeerDependencies: - vite @@ -19929,7 +20043,7 @@ snapshots: - uploadthing - yaml - astro@5.13.2(@types/node@24.1.0)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0): + astro@5.13.2(@types/node@24.3.1)(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1)(jiti@2.4.2)(lightningcss@1.30.1)(rollup@4.40.2)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(yaml@2.8.0): dependencies: '@astrojs/compiler': 2.12.2 '@astrojs/internal-helpers': 0.7.2 @@ -19985,8 +20099,8 @@ snapshots: unist-util-visit: 5.0.0 unstorage: 1.16.0(db0@0.3.2(@libsql/client@0.15.4))(ioredis@5.6.1) vfile: 6.0.3 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vitefu: 1.0.6(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vitefu: 1.0.6(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) xxhash-wasm: 1.1.0 yargs-parser: 21.1.1 yocto-spinner: 0.2.2 @@ -20839,9 +20953,9 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig-typescript-loader@6.1.0(@types/node@24.1.0)(cosmiconfig@9.0.0(typescript@5.8.3))(typescript@5.8.3): + cosmiconfig-typescript-loader@6.1.0(@types/node@24.3.1)(cosmiconfig@9.0.0(typescript@5.8.3))(typescript@5.8.3): dependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 cosmiconfig: 9.0.0(typescript@5.8.3) jiti: 2.4.2 typescript: 5.8.3 @@ -21677,7 +21791,7 @@ snapshots: eslint: 8.55.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.55.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0(eslint@8.55.0))(eslint@8.55.0) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.55.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.55.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0(eslint@8.55.0))(eslint@8.55.0))(eslint@8.55.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.55.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.55.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.55.0) eslint-plugin-react: 7.37.5(eslint@8.55.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.55.0) @@ -21696,7 +21810,7 @@ snapshots: '@typescript-eslint/parser': 8.37.0(eslint@8.57.0)(typescript@5.8.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.57.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.57.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.37.0(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.37.0(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.0) eslint-plugin-react: 7.37.5(eslint@8.57.0) @@ -21712,10 +21826,10 @@ snapshots: dependencies: eslint: 9.26.0(jiti@2.4.2) - eslint-config-standard@17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-n@15.7.0(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-promise@6.6.0(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)): + eslint-config-standard@17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-n@15.7.0(eslint@9.26.0(jiti@2.4.2)))(eslint-plugin-promise@6.6.0(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)): dependencies: eslint: 9.26.0(jiti@2.4.2) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.26.0(jiti@2.4.2)) eslint-plugin-n: 15.7.0(eslint@9.26.0(jiti@2.4.2)) eslint-plugin-promise: 6.6.0(eslint@9.26.0(jiti@2.4.2)) @@ -21763,12 +21877,12 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.7.2 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.55.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.55.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0(eslint@8.55.0))(eslint@8.55.0))(eslint@8.55.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.55.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.55.0) eslint-plugin-import-x: 4.11.1(eslint@8.55.0)(typescript@5.8.3) transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.57.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0)(eslint@8.57.0): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.57.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.37.0(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1(supports-color@8.1.1) @@ -21795,7 +21909,7 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.7.2 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.26.0(jiti@2.4.2)) eslint-plugin-import-x: 4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3) transitivePeerDependencies: - supports-color @@ -21836,14 +21950,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.37.0(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.37.0(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.57.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.37.0(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7(supports-color@8.1.1) optionalDependencies: '@typescript-eslint/parser': 8.37.0(eslint@8.57.0)(typescript@5.8.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.57.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.57.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.37.0(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - supports-color @@ -21964,7 +22078,7 @@ snapshots: - supports-color - typescript - eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.55.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.55.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0(eslint@8.55.0))(eslint@8.55.0))(eslint@8.55.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.55.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.55.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -21993,7 +22107,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2)): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.26.0(jiti@2.4.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -22033,7 +22147,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.37.0(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@8.57.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.37.0(eslint@8.57.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.11.1(eslint@8.57.0)(typescript@5.8.3))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.37.0(eslint@8.57.0)(typescript@5.8.3))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -22262,7 +22376,7 @@ snapshots: regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-svelte@3.7.0(eslint@9.26.0(jiti@2.4.2))(svelte@5.38.7)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.1.0)(typescript@5.8.3)): + eslint-plugin-svelte@3.7.0(eslint@9.26.0(jiti@2.4.2))(svelte@5.38.7)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.3.1)(typescript@5.8.3)): dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.26.0(jiti@2.4.2)) '@jridgewell/sourcemap-codec': 1.5.0 @@ -22270,7 +22384,7 @@ snapshots: esutils: 2.0.3 known-css-properties: 0.36.0 postcss: 8.5.6 - postcss-load-config: 3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.1.0)(typescript@5.8.3)) + postcss-load-config: 3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.3.1)(typescript@5.8.3)) postcss-safe-parser: 7.0.1(postcss@8.5.6) semver: 7.7.2 svelte-eslint-parser: 1.2.0(svelte@5.38.7) @@ -22587,7 +22701,7 @@ snapshots: esrap@2.1.0: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.5.0 esrecurse@4.3.0: dependencies: @@ -22919,7 +23033,7 @@ snapshots: fix-dts-default-cjs-exports@1.0.1: dependencies: - magic-string: 0.30.17 + magic-string: 0.30.18 mlly: 1.7.4 rollup: 4.40.2 @@ -23030,6 +23144,9 @@ snapshots: fs.realpath@1.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -23614,12 +23731,12 @@ snapshots: run-async: 3.0.0 rxjs: 7.8.2 - inquirer@12.3.0(@types/node@24.1.0): + inquirer@12.3.0(@types/node@24.3.1): dependencies: - '@inquirer/core': 10.1.13(@types/node@24.1.0) - '@inquirer/prompts': 7.5.3(@types/node@24.1.0) - '@inquirer/type': 3.0.7(@types/node@24.1.0) - '@types/node': 24.1.0 + '@inquirer/core': 10.1.13(@types/node@24.3.1) + '@inquirer/prompts': 7.5.3(@types/node@24.3.1) + '@inquirer/type': 3.0.7(@types/node@24.3.1) + '@types/node': 24.3.1 ansi-escapes: 4.3.2 mute-stream: 2.0.0 run-async: 3.0.0 @@ -24532,6 +24649,8 @@ snapshots: loupe@3.1.3: {} + loupe@3.2.1: {} + lower-case@2.0.2: dependencies: tslib: 2.8.1 @@ -24561,7 +24680,7 @@ snapshots: magic-regexp@0.8.0: dependencies: estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.18 mlly: 1.7.4 regexp-tree: 0.1.27 type-level-regexp: 0.1.17 @@ -25192,12 +25311,12 @@ snapshots: transitivePeerDependencies: - '@types/node' - msw@2.10.2(@types/node@24.1.0)(typescript@5.8.3): + msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3): dependencies: '@bundled-es-modules/cookie': 2.0.1 '@bundled-es-modules/statuses': 1.0.1 '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.1.12(@types/node@24.1.0) + '@inquirer/confirm': 5.1.12(@types/node@24.3.1) '@mswjs/interceptors': 0.39.2 '@open-draft/deferred-promise': 2.2.0 '@open-draft/until': 2.1.0 @@ -25313,7 +25432,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: '@next/env': 15.3.2 '@swc/counter': 0.1.3 @@ -25334,12 +25453,13 @@ snapshots: '@next/swc-win32-arm64-msvc': 15.3.2 '@next/swc-win32-x64-msvc': 15.3.2 '@opentelemetry/api': 1.9.0 + '@playwright/test': 1.55.0 sharp: 0.34.1 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.9.0)(@playwright/test@1.55.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: '@next/env': 15.3.2 '@swc/counter': 0.1.3 @@ -25360,6 +25480,7 @@ snapshots: '@next/swc-win32-arm64-msvc': 15.3.2 '@next/swc-win32-x64-msvc': 15.3.2 '@opentelemetry/api': 1.9.0 + '@playwright/test': 1.55.0 sharp: 0.34.1 transitivePeerDependencies: - '@babel/core' @@ -25406,7 +25527,7 @@ snapshots: klona: 2.0.6 knitwork: 1.2.0 listhen: 1.9.0 - magic-string: 0.30.17 + magic-string: 0.30.18 magicast: 0.3.5 mime: 4.0.7 mlly: 1.7.4 @@ -26273,6 +26394,14 @@ snapshots: playground@file:packages/js-client/playground: {} + playwright-core@1.55.0: {} + + playwright@1.55.0: + dependencies: + playwright-core: 1.55.0 + optionalDependencies: + fsevents: 2.3.2 + pluralize@8.0.0: {} polished@4.3.1: @@ -26318,13 +26447,13 @@ snapshots: dependencies: postcss: 8.5.6 - postcss-load-config@3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.1.0)(typescript@5.8.3)): + postcss-load-config@3.1.4(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.3.1)(typescript@5.8.3)): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: postcss: 8.5.6 - ts-node: 10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.1.0)(typescript@5.8.3) + ts-node: 10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.3.1)(typescript@5.8.3) postcss-merge-longhand@7.0.5(postcss@8.5.6): dependencies: @@ -27012,7 +27141,7 @@ snapshots: - supports-color - typescript - release-it@18.1.2(@types/node@24.1.0)(typescript@5.8.3): + release-it@18.1.2(@types/node@24.3.1)(typescript@5.8.3): dependencies: '@iarna/toml': 2.2.5 '@octokit/rest': 21.0.2 @@ -27023,7 +27152,7 @@ snapshots: execa: 9.5.2 git-url-parse: 16.0.0 globby: 14.0.2 - inquirer: 12.3.0(@types/node@24.1.0) + inquirer: 12.3.0(@types/node@24.3.1) issue-parser: 7.0.1 lodash: 4.17.21 mime-types: 2.1.35 @@ -27213,7 +27342,7 @@ snapshots: rollup-plugin-dts@6.2.1(rollup@3.29.5)(typescript@5.8.3): dependencies: - magic-string: 0.30.17 + magic-string: 0.30.18 rollup: 3.29.5 typescript: 5.8.3 optionalDependencies: @@ -27221,7 +27350,7 @@ snapshots: rollup-plugin-dts@6.2.1(rollup@4.40.2)(typescript@5.8.3): dependencies: - magic-string: 0.30.17 + magic-string: 0.30.18 rollup: 4.40.2 typescript: 5.8.3 optionalDependencies: @@ -28182,11 +28311,11 @@ snapshots: fdir: 6.4.6(picomatch@4.0.3) picomatch: 4.0.3 - tinypool@1.0.2: {} + tinypool@1.1.1: {} tinyrainbow@2.0.0: {} - tinyspy@3.0.2: {} + tinyspy@4.0.3: {} tldts-core@6.1.86: {} @@ -28263,14 +28392,14 @@ snapshots: dependencies: typescript: 5.8.3 - ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.1.0)(typescript@5.8.3): + ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@24.3.1)(typescript@5.8.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 24.1.0 + '@types/node': 24.3.1 acorn: 8.14.1 acorn-walk: 8.3.4 arg: 4.1.3 @@ -28460,7 +28589,7 @@ snapshots: globby: 13.2.2 hookable: 5.5.3 jiti: 1.21.7 - magic-string: 0.30.17 + magic-string: 0.30.18 mkdist: 1.6.0(typescript@5.8.3)(vue-tsc@2.2.10(typescript@5.8.3)) mlly: 1.7.4 pathe: 1.1.2 @@ -28524,14 +28653,14 @@ snapshots: dependencies: acorn: 8.14.1 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.18 unplugin: 2.3.4 undici-types@6.19.8: {} undici-types@6.21.0: {} - undici-types@7.8.0: {} + undici-types@7.10.0: {} undici@6.21.1: {} @@ -28593,10 +28722,10 @@ snapshots: escape-string-regexp: 5.0.0 estree-walker: 3.0.3 local-pkg: 1.1.1 - magic-string: 0.30.17 + magic-string: 0.30.18 mlly: 1.7.4 pathe: 2.0.3 - picomatch: 4.0.2 + picomatch: 4.0.3 pkg-types: 2.1.0 scule: 1.3.0 strip-literal: 3.0.0 @@ -28678,7 +28807,7 @@ snapshots: fast-glob: 3.3.3 json5: 2.2.3 local-pkg: 1.1.1 - magic-string: 0.30.17 + magic-string: 0.30.18 micromatch: 4.0.8 mlly: 1.7.4 pathe: 2.0.3 @@ -28699,7 +28828,7 @@ snapshots: unplugin@2.3.4: dependencies: acorn: 8.14.1 - picomatch: 4.0.2 + picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 unrs-resolver@1.7.2: @@ -28875,11 +29004,11 @@ snapshots: dependencies: vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vite-hot-client@2.0.4(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): + vite-hot-client@2.0.4(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vite-node@3.1.3(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): + vite-node@3.2.4(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): dependencies: cac: 6.7.14 debug: 4.4.1(supports-color@8.1.1) @@ -28900,13 +29029,13 @@ snapshots: - tsx - yaml - vite-node@3.1.3(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): + vite-node@3.2.4(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): dependencies: cac: 6.7.14 debug: 4.4.1(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -28961,9 +29090,9 @@ snapshots: - rollup - supports-color - vite-plugin-dts@4.5.3(@types/node@24.1.0)(rollup@4.40.2)(typescript@5.8.3)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): + vite-plugin-dts@4.5.3(@types/node@24.3.1)(rollup@4.40.2)(typescript@5.8.3)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: - '@microsoft/api-extractor': 7.52.8(@types/node@24.1.0) + '@microsoft/api-extractor': 7.52.8(@types/node@24.3.1) '@rollup/pluginutils': 5.1.4(rollup@4.40.2) '@volar/typescript': 2.4.13 '@vue/language-core': 2.2.0(typescript@5.8.3) @@ -28974,13 +29103,13 @@ snapshots: magic-string: 0.30.17 typescript: 5.8.3 optionalDependencies: - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite-plugin-inspect@0.8.9(rollup@4.40.2)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): + vite-plugin-inspect@0.8.9(rollup@4.40.2)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: '@antfu/utils': 0.7.10 '@rollup/pluginutils': 5.1.4(rollup@4.40.2) @@ -28991,7 +29120,7 @@ snapshots: perfect-debounce: 1.0.0 picocolors: 1.1.1 sirv: 3.0.1 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - rollup - supports-color @@ -29013,48 +29142,48 @@ snapshots: transitivePeerDependencies: - supports-color - vite-plugin-mkcert@1.17.8(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): + vite-plugin-mkcert@1.17.8(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: axios: 1.9.0(debug@4.4.1) debug: 4.4.1(supports-color@8.1.1) picocolors: 1.1.1 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - supports-color - vite-plugin-mkcert@1.17.8(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): + vite-plugin-mkcert@1.17.8(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: axios: 1.9.0(debug@4.4.1) debug: 4.4.1(supports-color@8.1.1) picocolors: 1.1.1 - vite: 7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - supports-color - vite-plugin-qrcode@0.2.4(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)): + vite-plugin-qrcode@0.2.4(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)): dependencies: qrcode-terminal: 0.12.0 - vite: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + vite: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) vite-plugin-qrcode@0.2.4(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: qrcode-terminal: 0.12.0 vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vite-plugin-qrcode@0.2.4(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): + vite-plugin-qrcode@0.2.4(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: qrcode-terminal: 0.12.0 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vite-plugin-qrcode@0.3.0(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)): + vite-plugin-qrcode@0.3.0(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)): dependencies: qrcode-terminal: 0.12.0 - vite: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + vite: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) - vite-plugin-qrcode@0.3.0(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): + vite-plugin-qrcode@0.3.0(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: qrcode-terminal: 0.12.0 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vite-plugin-static-copy@2.3.1(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: @@ -29065,23 +29194,23 @@ snapshots: picocolors: 1.1.1 vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vite-plugin-vue-devtools@7.7.6(rollup@4.40.2)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)): + vite-plugin-vue-devtools@7.7.6(rollup@4.40.2)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)): dependencies: - '@vue/devtools-core': 7.7.6(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)) + '@vue/devtools-core': 7.7.6(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(vue@3.5.21(typescript@5.8.3)) '@vue/devtools-kit': 7.7.6 '@vue/devtools-shared': 7.7.6 execa: 9.5.3 sirv: 3.0.1 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vite-plugin-inspect: 0.8.9(rollup@4.40.2)(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) - vite-plugin-vue-inspector: 5.3.1(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite-plugin-inspect: 0.8.9(rollup@4.40.2)(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + vite-plugin-vue-inspector: 5.3.1(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) transitivePeerDependencies: - '@nuxt/kit' - rollup - supports-color - vue - vite-plugin-vue-inspector@5.3.1(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): + vite-plugin-vue-inspector@5.3.1(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): dependencies: '@babel/core': 7.27.1 '@babel/plugin-proposal-decorators': 7.27.1(@babel/core@7.27.1) @@ -29092,7 +29221,7 @@ snapshots: '@vue/compiler-dom': 3.5.21 kolorist: 1.8.0 magic-string: 0.30.18 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) transitivePeerDependencies: - supports-color @@ -29106,13 +29235,13 @@ snapshots: vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) vue: 3.5.21(typescript@5.8.3) - vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2): + vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2): dependencies: esbuild: 0.21.5 postcss: 8.5.6 rollup: 4.40.2 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 fsevents: 2.3.3 lightningcss: 1.30.1 terser: 5.39.2 @@ -29151,7 +29280,7 @@ snapshots: tsx: 4.20.3 yaml: 2.8.0 - vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): + vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): dependencies: esbuild: 0.25.4 fdir: 6.4.4(picomatch@4.0.2) @@ -29160,7 +29289,7 @@ snapshots: rollup: 4.40.2 tinyglobby: 0.2.13 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 fsevents: 2.3.3 jiti: 2.4.2 lightningcss: 1.30.1 @@ -29168,7 +29297,7 @@ snapshots: tsx: 4.20.3 yaml: 2.8.0 - vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): + vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): dependencies: esbuild: 0.25.4 fdir: 6.4.6(picomatch@4.0.3) @@ -29177,7 +29306,7 @@ snapshots: rollup: 4.40.2 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 24.1.0 + '@types/node': 24.3.1 fsevents: 2.3.3 jiti: 2.4.2 lightningcss: 1.30.1 @@ -29185,26 +29314,26 @@ snapshots: tsx: 4.20.3 yaml: 2.8.0 - vitefu@0.2.5(vite@5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2)): + vitefu@0.2.5(vite@5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2)): optionalDependencies: - vite: 5.4.19(@types/node@24.1.0)(lightningcss@1.30.1)(terser@5.39.2) + vite: 5.4.19(@types/node@24.3.1)(lightningcss@1.30.1)(terser@5.39.2) vitefu@1.0.6(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): optionalDependencies: vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vitefu@1.0.6(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): + vitefu@1.0.6(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): optionalDependencies: - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vitefu@1.0.6(vite@7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): + vitefu@1.0.6(vite@7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)): optionalDependencies: - vite: 7.0.6(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 7.0.6(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) optional: true - vitest-environment-nuxt@1.0.1(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(magicast@0.3.5)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(vitest@3.1.3)(yaml@2.8.0): + vitest-environment-nuxt@1.0.1(@playwright/test@1.55.0)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(magicast@0.3.5)(playwright-core@1.55.0)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(yaml@2.8.0): dependencies: - '@nuxt/test-utils': 3.19.0(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(magicast@0.3.5)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(vitest@3.1.3)(yaml@2.8.0) + '@nuxt/test-utils': 3.19.0(@playwright/test@1.55.0)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(magicast@0.3.5)(playwright-core@1.55.0)(terser@5.39.2)(tsx@4.20.3)(typescript@5.8.3)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0))(yaml@2.8.0) transitivePeerDependencies: - '@cucumber/cucumber' - '@jest/globals' @@ -29230,33 +29359,35 @@ snapshots: - vitest - yaml - vitest@3.1.3(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.18)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): dependencies: - '@vitest/expect': 3.1.3 - '@vitest/mocker': 3.1.3(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) - '@vitest/pretty-format': 3.1.3 - '@vitest/runner': 3.1.3 - '@vitest/snapshot': 3.1.3 - '@vitest/spy': 3.1.3 - '@vitest/utils': 3.1.3 + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(msw@2.10.2(@types/node@22.15.18)(typescript@5.8.3))(vite@6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + '@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.2.0 debug: 4.4.1(supports-color@8.1.1) expect-type: 1.2.1 - magic-string: 0.30.17 + magic-string: 0.30.18 pathe: 2.0.3 + picomatch: 4.0.3 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 tinyglobby: 0.2.14 - tinypool: 1.0.2 + tinypool: 1.1.1 tinyrainbow: 2.0.0 vite: 6.3.5(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vite-node: 3.1.3(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@22.15.18)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 '@types/node': 22.15.18 - '@vitest/ui': 3.1.3(vitest@3.1.3) + '@vitest/ui': 3.1.3(vitest@3.2.4) jsdom: 26.1.0 transitivePeerDependencies: - jiti @@ -29272,33 +29403,35 @@ snapshots: - tsx - yaml - vitest@3.1.3(@types/debug@4.1.12)(@types/node@24.1.0)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.1.0)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.1)(@vitest/ui@3.1.3)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0): dependencies: - '@vitest/expect': 3.1.3 - '@vitest/mocker': 3.1.3(msw@2.10.2(@types/node@24.1.0)(typescript@5.8.3))(vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) - '@vitest/pretty-format': 3.1.3 - '@vitest/runner': 3.1.3 - '@vitest/snapshot': 3.1.3 - '@vitest/spy': 3.1.3 - '@vitest/utils': 3.1.3 + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(msw@2.10.2(@types/node@24.3.1)(typescript@5.8.3))(vite@6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0)) + '@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.2.0 debug: 4.4.1(supports-color@8.1.1) expect-type: 1.2.1 - magic-string: 0.30.17 + magic-string: 0.30.18 pathe: 2.0.3 + picomatch: 4.0.3 std-env: 3.9.0 tinybench: 2.9.0 tinyexec: 0.3.2 tinyglobby: 0.2.14 - tinypool: 1.0.2 + tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) - vite-node: 3.1.3(@types/node@24.1.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite: 6.3.5(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@24.3.1)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.2)(tsx@4.20.3)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 24.1.0 - '@vitest/ui': 3.1.3(vitest@3.1.3) + '@types/node': 24.3.1 + '@vitest/ui': 3.1.3(vitest@3.2.4) jsdom: 26.1.0 transitivePeerDependencies: - jiti