diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index d06c8843..fb7f9707 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -7,6 +7,7 @@ on: jobs: build-and-test: runs-on: ubuntu-latest + if: github.event.pull_request.head.repo.full_name == github.repository steps: - uses: actions/checkout@v4 @@ -57,12 +58,51 @@ jobs: exit 1 - name: Install Playwright browsers - run: pnpm exec playwright install --with-deps chromium firefox webkit + run: pnpm exec playwright install --with-deps chromium - name: Run Playwright tests - run: pnpm exec playwright test --project chromium + run: pnpm exec playwright test env: PROJECT_URL: http://localhost:8887 + # E2E Notification + E2E_NOTIFICATION_SMTP_HOST: ${{ secrets.E2E_NOTIFICATION_SMTP_HOST }} + E2E_NOTIFICATION_SMTP_PORT: ${{ secrets.E2E_NOTIFICATION_SMTP_PORT }} + E2E_NOTIFICATION_SMTP_USER: ${{ secrets.E2E_NOTIFICATION_SMTP_USER }} + E2E_NOTIFICATION_SMTP_PASSWORD: ${{ secrets.E2E_NOTIFICATION_SMTP_PASSWORD }} + E2E_NOTIFICATION_SMTP_FROM: ${{ secrets.E2E_NOTIFICATION_SMTP_FROM }} + E2E_NOTIFICATION_SMTP_TO: ${{ secrets.E2E_NOTIFICATION_SMTP_TO }} + E2E_NOTIFICATION_SLACK_WEBHOOK: ${{ secrets.E2E_NOTIFICATION_SLACK_WEBHOOK }} + E2E_NOTIFICATION_DISCORD_WEBHOOK: ${{ secrets.E2E_NOTIFICATION_DISCORD_WEBHOOK }} + E2E_NOTIFICATION_TELEGRAM_BOT_TOKEN: ${{ secrets.E2E_NOTIFICATION_TELEGRAM_BOT_TOKEN }} + E2E_NOTIFICATION_TELEGRAM_CHAT_ID: ${{ secrets.E2E_NOTIFICATION_TELEGRAM_CHAT_ID }} + E2E_NOTIFICATION_TELEGRAM_TOPIC_ID: ${{ secrets.E2E_NOTIFICATION_TELEGRAM_TOPIC_ID }} + E2E_NOTIFICATION_GOTIFY_SERVER_URL: ${{ secrets.E2E_NOTIFICATION_GOTIFY_SERVER_URL }} + E2E_NOTIFICATION_GOTIFY_APP_TOKEN: ${{ secrets.E2E_NOTIFICATION_GOTIFY_APP_TOKEN }} + E2E_NOTIFICATION_NTFY_TOPIC: ${{ secrets.E2E_NOTIFICATION_NTFY_TOPIC }} + E2E_NOTIFICATION_NTFY_SERVER_URL: ${{ secrets.E2E_NOTIFICATION_NTFY_SERVER_URL }} + E2E_NOTIFICATION_NTFY_TOKEN: ${{ secrets.E2E_NOTIFICATION_NTFY_TOKEN }} + E2E_NOTIFICATION_NTFY_USERNAME: ${{ secrets.E2E_NOTIFICATION_NTFY_USERNAME }} + E2E_NOTIFICATION_NTFY_PASSWORD: ${{ secrets.E2E_NOTIFICATION_NTFY_PASSWORD }} + E2E_NOTIFICATION_WEBHOOK_URL: ${{ secrets.E2E_NOTIFICATION_WEBHOOK_URL }} + E2E_NOTIFICATION_WEBHOOK_SECRET_HEADER: ${{ secrets.E2E_NOTIFICATION_WEBHOOK_SECRET_HEADER }} + E2E_NOTIFICATION_WEBHOOK_SECRET: ${{ secrets.E2E_NOTIFICATION_WEBHOOK_SECRET }} + + # E2E Storage + E2E_STORAGE_AWS_S3_ENDPOINT_URL: ${{ secrets.E2E_STORAGE_AWS_S3_ENDPOINT_URL }} + E2E_STORAGE_AWS_S3_REGION: ${{ secrets.E2E_STORAGE_AWS_S3_REGION }} + E2E_STORAGE_AWS_S3_ACCESS_KEY: ${{ secrets.E2E_STORAGE_AWS_S3_ACCESS_KEY }} + E2E_STORAGE_AWS_S3_SECRET_KEY: ${{ secrets.E2E_STORAGE_AWS_S3_SECRET_KEY }} + E2E_STORAGE_AWS_S3_BUCKET_NAME: ${{ secrets.E2E_STORAGE_AWS_S3_BUCKET_NAME }} + E2E_STORAGE_AWS_S3_PORT: ${{ secrets.E2E_STORAGE_AWS_S3_PORT }} + E2E_STORAGE_R2_ENDPOINT_URL: ${{ secrets.E2E_STORAGE_R2_ENDPOINT_URL }} + E2E_STORAGE_R2_REGION: ${{ secrets.E2E_STORAGE_R2_REGION }} + E2E_STORAGE_R2_ACCESS_KEY: ${{ secrets.E2E_STORAGE_R2_ACCESS_KEY }} + E2E_STORAGE_R2_SECRET_KEY: ${{ secrets.E2E_STORAGE_R2_SECRET_KEY }} + E2E_STORAGE_R2_BUCKET_NAME: ${{ secrets.E2E_STORAGE_R2_BUCKET_NAME }} + E2E_STORAGE_R2_PORT: ${{ secrets.E2E_STORAGE_R2_PORT }} + E2E_STORAGE_GOOGLE_DRIVE_CLIENT_ID: ${{ secrets.E2E_STORAGE_GOOGLE_DRIVE_CLIENT_ID }} + E2E_STORAGE_GOOGLE_DRIVE_CLIENT_SECRET: ${{ secrets.E2E_STORAGE_GOOGLE_DRIVE_CLIENT_SECRET }} + E2E_STORAGE_GOOGLE_DRIVE_FOLDER_ID: ${{ secrets.E2E_STORAGE_GOOGLE_DRIVE_FOLDER_ID }} - name: Upload report if failed if: failure() diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index e6dec38f..d9a26bbf 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: aquasecurity/trivy-action@0.35.0 + - uses: aquasecurity/trivy-action@v0.35.0 with: scan-type: 'fs' format: 'table' diff --git a/.gitignore b/.gitignore index 07983545..6b7224af 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,4 @@ certificates /blob-report/ /playwright/.cache/ /playwright/.auth/ +/e2e/local-storage.json diff --git a/Makefile b/Makefile index f3f252ce..dbd714b1 100644 --- a/Makefile +++ b/Makefile @@ -46,3 +46,17 @@ export-keycloak: @docker rm -f kc-exporter >/dev/null 2>&1 @docker compose -f docker-compose.func.yml start keycloak >/dev/null 2>&1 @echo "Keycloak configuration and users exported to seeds/keycloak/*.json" + +end-to-end: + @echo "Starting E2E testing..." + @docker compose -f docker-compose.e2e.yml up -d + @CI=true PROJECT_URL=http://localhost:8887 pnpm playwright test --project=chromium || (docker compose -f docker-compose.e2e.yml down --volumes && exit 1) + @docker compose -f docker-compose.e2e.yml down --volumes + @echo "Finished E2E testing successfully." + +e2e-manual: + @echo "Starting E2E testing..." + @docker compose -f docker-compose.e2e.yml up -d + @pnpm playwright test --ui || (docker compose -f docker-compose.e2e.yml down --volumes && exit 1) + @docker compose -f docker-compose.e2e.yml down --volumes + @echo "Finished E2E testing successfully." \ No newline at end of file diff --git a/docker-compose.e2e.yml b/docker-compose.e2e.yml new file mode 100644 index 00000000..d0412db7 --- /dev/null +++ b/docker-compose.e2e.yml @@ -0,0 +1,37 @@ +services: + app: + build: + context: . + dockerfile: docker/dockerfile/Dockerfile + target: prod + ports: + - '8887:80' + environment: + TZ: "Europe/Paris" + env_file: + - .env + volumes: + - portabase-e2e-data:/data + depends_on: + db: + condition: service_healthy + + db: + image: postgres:18-alpine + ports: + - "5433:5432" + volumes: + - postgres-e2e-data:/var/lib/postgresql/data + environment: + - POSTGRES_DB=devdb + - POSTGRES_USER=devuser + - POSTGRES_PASSWORD=changeme + healthcheck: + test: ["CMD-SHELL", "pg_isready -U devuser -d devdb"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + portabase-e2e-data: + postgres-e2e-data: diff --git a/e2e/access-management.spec.ts b/e2e/access-management.spec.ts new file mode 100644 index 00000000..bc1a7b45 --- /dev/null +++ b/e2e/access-management.spec.ts @@ -0,0 +1,74 @@ +import {expect, test} from "@playwright/test"; +import {users} from "./helpers/auth"; +import {changeUserRole, create, switchToDefault} from "./helpers/access-management"; +import {LOCAL_STORAGE_PATH} from "./helpers/session"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const firstOrganization = "Organization A"; +const secondOrganization = "Organization B"; + +test.describe.serial(() => { + test("Create an organization from organizations page", async ({page}) => { + await page.goto("/dashboard/admin/organizations"); + await expect(page.getByRole("heading", {name: "Active organizations"})).toBeVisible(); + + await create(page, "button", firstOrganization); + + await expect(page.getByText(/Organization has been successfully created\./i)).toBeVisible(); + await expect(page).toHaveURL("/dashboard/admin/organizations"); + await expect(page.getByRole("button", {name: firstOrganization, exact: true})).toBeVisible(); + + await switchToDefault(page); + }); + + test("Create an organization from sidebar button", async ({page}) => { + await page.goto("/dashboard/home"); + await expect(page.getByRole("heading", {name: "Dashboard"})).toBeVisible(); + + await create(page, "sidebar", secondOrganization); + + await expect(page.getByText(/Organization has been successfully created\./i)).toBeVisible(); + await expect(page).toHaveURL("/dashboard/home"); + await expect(page.getByRole("button", {name: secondOrganization, exact: true})).toBeVisible(); + + await switchToDefault(page); + }); + + test("Change John Doe's role from pending to user", async ({page}) => { + await page.goto("/dashboard/admin/users"); + await expect(page.getByText(users.normal.email, {exact: true})).toBeVisible(); + + const userRow = page.locator("tr").filter({hasText: users.normal.email}).first(); + await expect(userRow).toBeVisible(); + await userRow.locator("button").last().click(); + await page.getByRole('menuitem', {name: 'Role'}).click(); + + await expect(page.getByRole("heading", {name: "Change the user's role"})).toBeVisible(); + + await changeUserRole(page, "user") + + await expect(page.getByText("User role changed successfully.")).toBeVisible(); + await expect(page.locator("tr").filter({hasText: users.normal.email}).getByText("user", {exact: true})).toBeVisible(); + }); + + test("Add John Doe to Organization A", async ({page}) => { + await page.goto("/dashboard/admin/organizations"); + await expect(page.getByRole("heading", {name: "Active organizations"})).toBeVisible(); + + const organizationRow = page.locator("tr").filter({hasText: firstOrganization}).first(); + await expect(organizationRow).toBeVisible(); + await organizationRow.locator('a[href*="/dashboard/admin/organizations/"], a[href*="organizations/"]').click(); + + await expect(page.getByText(firstOrganization, {exact: true})).toBeVisible(); + await page.getByRole("button", {name: /Add member/i}).click(); + await expect(page.getByRole("heading", {name: "Add member to your organization"})).toBeVisible(); + + await page.getByPlaceholder("Enter a user email").fill(users.normal.email); + await page.getByRole("option", {name: new RegExp(users.normal.email, "i")}).click(); + await page.getByRole("button", {name: "Confirm"}).click(); + + await expect(page.getByText("Member successfully added!")).toBeVisible(); + await expect(page.getByText(users.normal.email, {exact: true})).toBeVisible(); + }); +}); diff --git a/e2e/agent.spec.ts b/e2e/agent.spec.ts new file mode 100644 index 00000000..893eeaaa --- /dev/null +++ b/e2e/agent.spec.ts @@ -0,0 +1,116 @@ +import {expect, test} from "@playwright/test"; +import {execSync} from "child_process"; +import fs from "fs"; +import os from "os"; +import path from "path"; +import {createAgentWithDockerDatabases} from "./helpers/agent-cli"; +import {create, edit, get, remove} from "./helpers/agent"; +import {LOCAL_STORAGE_PATH} from "./helpers/session"; + +const agent = { + aName: "Agent A", + aUpdatedName: "Agent A Updated", + bName: "Agent B", + description: "Agent created by Playwright E2E", + updatedDescription: "Agent updated by Playwright E2E", +}; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +test.describe.serial(() => { + let agentWorkspace: string | null = null; + + test("Create agent A from empty state", async ({page}) => { + await page.goto("/dashboard/agents"); + await expect(page.getByRole("heading", {name: "Agents"})).toBeVisible(); + await expect(page.getByText("Create new Agent", {exact: true})).toBeVisible(); + await create(page, "emptyState", agent.aName, agent.description); + + await expect(page.getByText("Success creating agent")).toBeVisible(); + await expect(get(page, agent.aName)).toBeVisible(); + await expect(page.getByText("Create new Agent", {exact: true})).toHaveCount(0); + }); + + test("Edit agent A", async ({page}) => { + await page.goto("/dashboard/agents"); + await expect(page.getByRole("heading", {name: "Agents"})).toBeVisible(); + await expect(get(page, agent.aName)).toBeVisible(); + + await edit(page, agent.aName, agent.aUpdatedName, agent.updatedDescription); + + await expect(page.getByText("Success updating agent")).toBeVisible(); + await expect(page.getByText(agent.aUpdatedName, {exact: true})).toBeVisible(); + await expect(page.getByText(agent.updatedDescription, {exact: true})).toBeVisible(); + }); + + test("Create agent B from classic button", async ({page}) => { + await page.goto("/dashboard/agents"); + await expect(page.getByRole("heading", {name: "Agents"})).toBeVisible(); + await expect(page.getByRole("button", {name: /Create Agent/i})).toBeVisible(); + await create(page, "button", agent.bName, agent.description); + + await expect(page.getByText("Success creating agent")).toBeVisible(); + await expect(get(page, agent.bName)).toBeVisible(); + }); + + test("Delete Agent B", async ({page}) => { + await page.goto("/dashboard/agents"); + await expect(page.getByRole("heading", {name: "Agents"})).toBeVisible(); + await expect(get(page, agent.bName)).toBeVisible(); + await remove(page, agent.bName); + + await expect(page.getByText("Agent has been successfully deleted.")).toBeVisible(); + await expect(page).toHaveURL("/dashboard/agents"); + await expect(page.getByText(agent.bName)).toHaveCount(0); + }); + + // test("Launch the updated agent", async ({page}) => { + // await page.goto("/dashboard/agents"); + // await expect(page.getByRole("heading", {name: "Agents"})).toBeVisible(); + // await get(page, agent.aName).click(); + // + // await expect(page).toHaveURL(/\/dashboard\/agents\/.+/); + // await expect(page.getByText(agent.aName, {exact: true})).toBeVisible(); + // await expect(page.getByText("Registration & Setup")).toBeVisible(); + // + // const commandInput = page.locator("input[readonly]").first(); + // await page.locator("input[readonly]").first().locator("xpath=following-sibling::button[1]").click(); + // const command = await commandInput.inputValue(); + // + // agentWorkspace = fs.mkdtempSync(path.join(os.tmpdir(), "portabase-agent-")); + // await createAgentWithDockerDatabases(command, agentWorkspace); + // execSync(`portabase start "${agent.aName}"`, { + // cwd: agentWorkspace, + // stdio: "pipe", + // timeout: 120_000, + // }); + // + // await expect(page.getByText("Never connected.")).toHaveCount(0, {timeout: 120_000}); + // await expect(page.getByText("Action Required")).toHaveCount(0); + // }); + + test.afterAll(async () => { + if (agentWorkspace) { + try { + execSync(`portabase stop "${agent.aName}"`, { + cwd: agentWorkspace, + stdio: "pipe", + timeout: 30_000, + }); + } catch { + } + + try { + execSync(`portabase uninstall --force "${agent.aName}"`, { + cwd: agentWorkspace, + stdio: "pipe", + timeout: 30_000, + }); + } catch { + } + + fs.rmSync(agentWorkspace, {recursive: true, force: true}); + agentWorkspace = null; + } + }); +}); \ No newline at end of file diff --git a/e2e/auth.spec.ts b/e2e/auth.spec.ts index d615ba44..34872cdb 100644 --- a/e2e/auth.spec.ts +++ b/e2e/auth.spec.ts @@ -1,43 +1,17 @@ -import {test, expect, Page} from '@playwright/test'; +import {test, expect} from '@playwright/test'; +import {login, register, users} from "./helpers/auth"; +import {LOCAL_STORAGE_PATH} from "./helpers/session"; +const TIMEOUT = undefined +// const TIMEOUT = 5000 -type UserCredentials = { - username: string - email: string - password: string -} +test.use({storageState: LOCAL_STORAGE_PATH}) - -const users: Record = { - admin: {username: 'Admin', email: 'admin@example.com', password: 'testPASS123456!'}, - normal: {username: 'John Doe', email: 'john.doe@example.com', password: 'testPASS123456!'}, -} - -async function register(page: Page, name: string, email: string, password: string, confirmPassword: string) { - await page.locator('input[name="name"]').fill(name) - await page.locator('input[name="email"]').fill(email) - await page.locator('input[name="password"]').fill(password) - await page.locator('input[name="confirmPassword"]').fill(confirmPassword) - - await page.click('button[type="submit"]') -} - -async function login(page: Page, email: string, password: string) { - await page.locator('input[name="email"]').fill(email) - await page.locator('input[name="password"]').fill(password) - - await page.locator('button:has-text("Login")').click() -} - -async function logout() { - //TODO -} - -test.describe.serial('User signup and login flows', () => { +test.describe.serial( () => { test('Redirect to login if not connected', async ({page}) => { await page.goto('/dashboard/projects'); - await expect(page).toHaveURL("login?redirect=%2Fdashboard%2Fprojects"); + await expect(page).toHaveURL("login?redirect=%2Fdashboard%2Fprojects", {timeout: TIMEOUT}); }); test('Password too short', async ({page}) => { @@ -85,7 +59,7 @@ test.describe.serial('User signup and login flows', () => { await register(page, users["admin"].username, users["admin"].email, users["admin"].password, users["admin"].password) - await expect(page).toHaveURL('/login') + await expect(page).toHaveURL('/login', {timeout: TIMEOUT}) }) test('User already exists.', async ({page}) => { @@ -108,7 +82,7 @@ test.describe.serial('User signup and login flows', () => { await register(page, users["normal"].username, users["normal"].email, users["normal"].password, users["normal"].password) - await expect(page).toHaveURL('login') + await expect(page).toHaveURL('/login', {timeout: TIMEOUT}) }) test('Failed login because account not active', async ({page}) => { @@ -120,16 +94,11 @@ test.describe.serial('User signup and login flows', () => { }) test('Successful login', async ({page}) => { - await page.goto('login') + await page.goto('/login') await login(page, users["admin"].email, users["admin"].password) - await expect(page).toHaveURL('/dashboard/home') + await expect(page).toHaveURL('/dashboard/home', {timeout: TIMEOUT}) + await expect(page.getByRole('link', {name: 'Logo Portabase'})).toBeVisible() + await page.context().storageState({path: LOCAL_STORAGE_PATH}) }) - }) - - -// test('Successful logout', async ({page}) => { -// await logout() -// await expect(page).toHaveURL('/login') -// }) \ No newline at end of file diff --git a/e2e/cleanup.spec.ts b/e2e/cleanup.spec.ts new file mode 100644 index 00000000..95fe7fe9 --- /dev/null +++ b/e2e/cleanup.spec.ts @@ -0,0 +1,32 @@ +import {expect, test} from "@playwright/test"; +import fs from "fs"; +import {logout} from "./helpers/auth"; +import {LOCAL_STORAGE_PATH} from "./helpers/session"; + + +test.use({storageState: LOCAL_STORAGE_PATH}); + +test.describe( () => { + test.afterAll(async () => { + if (fs.existsSync(LOCAL_STORAGE_PATH)) { + fs.unlinkSync(LOCAL_STORAGE_PATH); + } + }); + + test("Remove shared storage state", async ({page}) => { + await test.step("Logout shared authenticated session", async () => { + if (!fs.existsSync(LOCAL_STORAGE_PATH)) { + return; + } + + const content = fs.readFileSync(LOCAL_STORAGE_PATH, "utf-8").trim(); + if (!content || content === "{}") { + return; + } + + await page.goto('/dashboard/home'); + await logout(page); + await expect(page).toHaveURL(/\/login(?:\?.*)?$/); + }); + }); +}); diff --git a/e2e/helpers/access-management.ts b/e2e/helpers/access-management.ts new file mode 100644 index 00000000..dea6286d --- /dev/null +++ b/e2e/helpers/access-management.ts @@ -0,0 +1,70 @@ +import {Page} from "@playwright/test"; + +export function getUserRow(page: Page, email: string) { + return page.locator("tr").filter({hasText: email}).first(); +} + +export function getOrganizationRow(page: Page, organizationName: string) { + return page.locator("tr").filter({hasText: organizationName}).first(); +} + +/** + * Create an organization from the selected entrypoint. + * + * Available entrypoints: + * - `button`: the organizations page create button. + * - `sidebar`: the sidebar organization switcher. + * + * Executes from: + * - `/dashboard/admin/organizations` for "button" entrypoint + * - any `/dashboard/**` page for "sidebar" entrypoint + */ +export async function create(page: Page, entrypoint: "button" | "sidebar", name: string) { + if (entrypoint === "sidebar") { + await page.getByRole("button", {name: "Default Organization"}).click(); + await page.getByText("Create organization", {exact: true}).click(); + } else { + await page.getByRole("button", {name: /Create a new organization/i}).click(); + } + + await page.getByLabel("Name").fill(name); + await page.getByRole("button", {name: "Create"}).click(); +} + +/** + * Switch the active organization from the sidebar switcher. + * + * Executes from: any `/dashboard/**` if the sidebar is visible. + */ +export async function switchTo(page: Page, name: string) { + await page.getByTestId('organization-dropdown').click(); + await page.getByRole('menuitem', {name: name}).click(); +} + +/** + * Switch back to the default organization. + * + * Executes from: any `/dashboard/**` if the sidebar is visible. + */ +export async function switchToDefault(page: Page) { + await switchTo(page, "Default Organization"); +} + +const ROLE_LABELS = { + pending: "Pending", + user: "User", + admin: "Admin", +} as const; + +/** + * Change the global role of a user from the admin users role modal. + * + * Executes from: the "Change the user's role" dialog opened from `/dashboard/admin/users`. + */ +export async function changeUserRole(page: Page, role: keyof typeof ROLE_LABELS) { + const roleOption = ROLE_LABELS[role]; + + await page.getByRole("combobox").click(); + await page.getByRole("option", {name: roleOption}).click(); + await page.getByRole("button", {name: "Validate"}).click(); +} \ No newline at end of file diff --git a/e2e/helpers/agent-cli.ts b/e2e/helpers/agent-cli.ts new file mode 100644 index 00000000..aec53c6d --- /dev/null +++ b/e2e/helpers/agent-cli.ts @@ -0,0 +1,107 @@ +import * as pty from "node-pty"; + +type InteractiveStep = { + match: RegExp; + reply: string; +}; + +function normalizeOutput(output: string) { + return output.replace(/\u001b\[[0-9;?]*[ -/]*[@-~]/g, ""); +} + +/** + * Run an interactive CLI command and answer prompts in sequence. + * Entry point: + * - `command` is the full CLI command executed in the PTY. + * - `cwd` is the local workspace where the command is launched. + * - `steps` defines which prompt text is matched and which reply is sent. + * - `timeoutMs` controls when the command is aborted if it stalls. + * Executes from: not page-bound; runs from a local test workspace on the Node.js side. + */ +export async function runInteractiveCommand( + command: string, + cwd: string, + steps: InteractiveStep[], + timeoutMs: number = 120_000, +) { + await new Promise((resolve, reject) => { + const child = pty.spawn("sh", ["-lc", command], { + cwd, + env: { + ...process.env, + TERM: "xterm-256color", + }, + cols: 120, + rows: 30, + }); + + let currentStep = 0; + let output = ""; + const timer = setTimeout(() => { + child.kill(); + reject(new Error(`Interactive command timed out.\n\nCommand: ${command}\n\nOutput:\n${normalizeOutput(output)}`)); + }, timeoutMs); + + const handleChunk = (chunk: string) => { + output += chunk; + const normalizedOutput = normalizeOutput(output); + + while (currentStep < steps.length && steps[currentStep].match.test(normalizedOutput)) { + child.write(steps[currentStep].reply); + currentStep += 1; + } + }; + + child.onData(handleChunk); + child.onExit(({exitCode}) => { + clearTimeout(timer); + if (exitCode === 0) { + resolve(); + return; + } + + reject(new Error(`Interactive command failed with exit code ${exitCode}.\n\nCommand: ${command}\n\nOutput:\n${normalizeOutput(output)}`)); + }); + }); +} + +/** + * Create and configure a Portabase agent with two Docker-backed databases. + * Entry point: + * - `command` is the CLI setup command copied from the agent details page. + * - `cwd` is the local workspace where the agent is installed. + * - this helper answers the wizard for PostgreSQL first, then MariaDB. + * Executes from: not page-bound; runs from a local test workspace on the Node.js side. + */ +export async function createAgentWithDockerDatabases(command: string, cwd: string) { + await runInteractiveCommand(command, cwd, [ + { + match: /configure.*database|add.*database/i, + reply: "y\n", + }, + { + match: /docker.*new local container|manual.*external|external.*existing/i, + reply: "\r", + }, + { + match: /postgresql|mariadb/i, + reply: "\r", + }, + { + match: /another.*database|add.*another|configure.*another/i, + reply: "y\n", + }, + { + match: /docker.*new local container|manual.*external|external.*existing/i, + reply: "\r", + }, + { + match: /postgresql|mariadb/i, + reply: "\u001B[B\r", + }, + { + match: /another.*database|add.*another|configure.*another/i, + reply: "n\n", + }, + ]); +} diff --git a/e2e/helpers/agent.ts b/e2e/helpers/agent.ts new file mode 100644 index 00000000..565f106f --- /dev/null +++ b/e2e/helpers/agent.ts @@ -0,0 +1,66 @@ +import {Page} from "@playwright/test"; + + +/** + * Locate an agent card in the list. + + * Executes from: `/dashboard/agents`. + */ +export function get(page: Page, name: string) { + return page.locator('a[href^="/dashboard/agents"]').filter({hasText: name}).first(); +} + +/** + * Create an agent from the selected entrypoint. + * + * Available entrypoints: + * - `button`: the classic create button. + * - `emptyState`: the empty-state CTA. + * - `auto`: uses the classic create button and falls back to the empty-state CTA. + * + * Executes from: `/dashboard/agents`. + */ +export async function create(page: Page, entrypoint: "auto" | "emptyState" | "button" = "auto", agentName: string, description: string) { + if (entrypoint === "auto") { + const createButton = page.getByRole("button", {name: /Create Agent/i}); + if (await createButton.isVisible()) await page.getByRole("button", {name: /Create Agent/i}).click(); + await page.getByText("Create new Agent", {exact: true}).click(); + } else if (entrypoint === "button") { + await page.getByRole("button", {name: /Create Agent/i}).click(); + } else if (entrypoint === "emptyState") { + await page.getByText("Create new Agent", {exact: true}).click(); + } + + await page.getByLabel("Name").fill(agentName); + await page.getByLabel("Description").fill(description); + await page.getByRole("button", {name: "Create"}).click(); +} + +/** + * Edit an existing agent (name and description) from its details page. + * + * Executes from: `/dashboard/agents/[agentId]`. + */ +export async function edit(page: Page, currentName: string, updatedName: string, updatedDescription: string) { + await get(page, currentName).click(); + + await page + .getByRole("button", {name: /Delete Agent/i}) + .locator("xpath=ancestor::div[1]/preceding-sibling::div[1]/*[1]") + .click(); + + await page.getByLabel("Name").fill(updatedName); + await page.getByLabel("Description").fill(updatedDescription); + await page.getByRole("button", {name: "Update"}).click(); +} + +/** + * Delete an agent from its details page. + + * Executes from: `/dashboard/agents/[agentId]`. + */ +export async function remove(page: Page, name: string) { + await get(page, name).click(); + await page.getByRole("button", {name: /Delete Agent/i}).click(); + await page.getByRole("button", {name: "Delete", exact: true}).click(); +} diff --git a/e2e/helpers/auth.ts b/e2e/helpers/auth.ts new file mode 100644 index 00000000..9835c03b --- /dev/null +++ b/e2e/helpers/auth.ts @@ -0,0 +1,50 @@ +import {Page} from "@playwright/test"; + +export type UserCredentials = { + username: string + email: string + password: string +} + +export const users: Record = { + admin: {username: "Admin", email: "admin@example.com", password: "testPASS123456!"}, + normal: {username: "John Doe", email: "john.doe@example.com", password: "testPASS123456!"}, +} + +/** + * Fill and submit the registration form. + * + * Executes from: `/register`. + */ +export async function register(page: Page, name: string, email: string, password: string, confirmPassword: string) { + await page.locator('input[name="name"]').fill(name) + await page.locator('input[name="email"]').fill(email) + await page.locator('input[name="password"]').fill(password) + await page.locator('input[name="confirmPassword"]').fill(confirmPassword) + + await page.click('button[type="submit"]') +} + +/** + * Fill and submit the login form. + * + * Executes from: `/login`. + */ +export async function login(page: Page, email: string, password: string) { + await page.locator('input[name="email"]').fill(email) + await page.locator('input[name="password"]').fill(password) + + await page.locator('button:has-text("Login")').click() +} + +/** + * Log out the current authenticated user. + * + * Executes from: any authenticated `/dashboard/**` page. + */ +export async function logout(page: Page) { + const profileButton = page.getByTestId('profile-dropdown') + await profileButton.first().click(); + + await page.getByRole("menuitem").filter({hasText: /Logout/i}).click(); +} diff --git a/e2e/helpers/env.ts b/e2e/helpers/env.ts new file mode 100644 index 00000000..ba4d6f84 --- /dev/null +++ b/e2e/helpers/env.ts @@ -0,0 +1,62 @@ +const REQUIRED_E2E_ENV_VARS = [ + "E2E_NOTIFICATION_SMTP_HOST", + "E2E_NOTIFICATION_SMTP_PORT", + "E2E_NOTIFICATION_SMTP_USER", + "E2E_NOTIFICATION_SMTP_PASSWORD", + "E2E_NOTIFICATION_SMTP_FROM", + "E2E_NOTIFICATION_SMTP_TO", + "E2E_NOTIFICATION_SLACK_WEBHOOK", + "E2E_NOTIFICATION_DISCORD_WEBHOOK", + "E2E_NOTIFICATION_TELEGRAM_BOT_TOKEN", + "E2E_NOTIFICATION_TELEGRAM_CHAT_ID", + "E2E_NOTIFICATION_TELEGRAM_TOPIC_ID", + "E2E_NOTIFICATION_GOTIFY_SERVER_URL", + "E2E_NOTIFICATION_GOTIFY_APP_TOKEN", + "E2E_NOTIFICATION_NTFY_TOPIC", + "E2E_NOTIFICATION_NTFY_SERVER_URL", + "E2E_NOTIFICATION_NTFY_TOKEN", + "E2E_NOTIFICATION_NTFY_USERNAME", + "E2E_NOTIFICATION_NTFY_PASSWORD", + "E2E_NOTIFICATION_WEBHOOK_URL", + "E2E_NOTIFICATION_WEBHOOK_SECRET_HEADER", + "E2E_NOTIFICATION_WEBHOOK_SECRET", + "E2E_STORAGE_AWS_S3_ENDPOINT_URL", + "E2E_STORAGE_AWS_S3_REGION", + "E2E_STORAGE_AWS_S3_ACCESS_KEY", + "E2E_STORAGE_AWS_S3_SECRET_KEY", + "E2E_STORAGE_AWS_S3_BUCKET_NAME", + "E2E_STORAGE_AWS_S3_PORT", + "E2E_STORAGE_R2_ENDPOINT_URL", + "E2E_STORAGE_R2_REGION", + "E2E_STORAGE_R2_ACCESS_KEY", + "E2E_STORAGE_R2_SECRET_KEY", + "E2E_STORAGE_R2_BUCKET_NAME", + "E2E_STORAGE_R2_PORT", + "E2E_STORAGE_GOOGLE_DRIVE_CLIENT_ID", + "E2E_STORAGE_GOOGLE_DRIVE_CLIENT_SECRET", + "E2E_STORAGE_GOOGLE_DRIVE_FOLDER_ID", +] as const; + +function assertRequiredEnvVars() { + const missingVars = REQUIRED_E2E_ENV_VARS.filter((name) => { + const value = process.env[name]?.trim(); + return !value; + }); + + if (missingVars.length > 0) { + throw new Error( + `Missing required environment variables:\n${missingVars.map((name) => `- ${name}`).join("\n")}`, + ); + } +} + +assertRequiredEnvVars(); + +export function getEnv(name: string): string { + const value = process.env[name]?.trim(); + if (!value) { + throw new Error(`Missing required environment variable: ${name}`); + } + + return value; +} diff --git a/e2e/helpers/notification.ts b/e2e/helpers/notification.ts new file mode 100644 index 00000000..9d54983d --- /dev/null +++ b/e2e/helpers/notification.ts @@ -0,0 +1,94 @@ +import {Page} from "@playwright/test"; + + +/** + * Locate a notification channel card in the list. + * + * Executes from: `/dashboard/notifications/channels`. + */ +export function get(page: Page, channelName: string) { + return page.locator('div.block.transition-all.duration-200.rounded-xl', { + has: page.locator('h3', {hasText: channelName}), + }).first(); +} + +/** + * Open the edit dialog for an existing notification channel. + * + * Executes from: `/dashboard/notifications/channels`. + */ +export async function edit(page: Page, channelName: string) { + const card = get(page, channelName); + await card.locator("button").nth(1).click(); +} + +/** + * Delete an existing notification channel. + * + * Executes from: `/dashboard/notifications/channels`. + */ +export async function remove(page: Page, channelName: string) { + const card = get(page, channelName); + await card.locator("button").nth(2).click(); + await page.getByRole("button", {name: "Delete"}).click(); +} + +/** + * Fill the notification channel creation form. + * + * Available entrypoints: + * - `button`: the classic add button. + * - `emptyState`: the empty-state CTA. + * - `auto` use the classic add button and falls back to the empty-state CTA. + * + * Executes from: `/dashboard/notifications/channels`. + */ +export async function create( + page: Page, + provider: "Discord" | "Gotify" | "ntfy.sh" | "Slack" | "Email" | "Telegram" | "Webhook", + channelName: string, + fillConfig: (page: Page) => Promise, + entrypoint: "auto" | "emptyState" | "button" = "auto", +) { + if (entrypoint === "auto") { + const addButton = page.getByRole("button", {name: /Add notification channel/i}); + if (await addButton.isVisible()) await page.getByRole("button", {name: /Add notification channel/i}).click(); + else await page.getByRole("button", {name: /No notification channels configured yet/i}).click(); + } else if (entrypoint === "button") { + await page.getByRole("button", {name: /Add notification channel/i}).click(); + } else if (entrypoint === "emptyState") { + await page.getByRole("button", {name: /No notification channels configured yet/i}).click(); + } + + await page.getByText(provider, {exact: true}).click(); + await page.getByLabel(/Channel Name/).fill(channelName); + await fillConfig(page); +} + +/** + * Submit the notification channel creation form. + * + * Executes from: the add notification channel dialog opened from `/dashboard/notifications/channels`. + */ +export async function submit(page: Page) { + await page.getByRole("button", {name: "Add Channel"}).click(); +} + +/** + * Open the edit dialog for a notification channel and trigger the test action. + * + * Executes from: `/dashboard/notifications/channels`. + */ +export async function testFromEdit(page: Page, channelName: string) { + await edit(page, channelName); + await page.getByRole("button", {name: /Test Channel/i}).click(); +} + +/** + * Close the current notification channel dialog without saving. + * + * Executes from: the add or edit notification channel dialog. + */ +export async function cancel(page: Page) { + await page.getByRole("button", {name: "Cancel"}).click(); +} diff --git a/e2e/helpers/project.ts b/e2e/helpers/project.ts new file mode 100644 index 00000000..ee788866 --- /dev/null +++ b/e2e/helpers/project.ts @@ -0,0 +1,59 @@ +import {Page} from "@playwright/test"; + + +/** + * Locate a project card in the list. + * + * Executes from: `/dashboard/projects`. + */ +export function get(page: Page, projectName: string) { + return page.locator('a[href^="/dashboard/projects/"]').filter({hasText: projectName}).first(); +} + +/** + * Create a project from the selected entrypoint. + * + * Available entrypoints: + * - `emptyState`: the empty-state CTA. + * - `button`: the classic create button. + * + * * Executes from: `/dashboard/projects`. + */ +export async function create(page: Page, entrypoint: "emptyState" | "button", projectName: string) { + if (entrypoint === "emptyState") { + await page.getByText("Create new Project", {exact: true}).click(); + } else { + await page.getByRole("button", {name: /Create Project/i}).click(); + } + + await page.getByLabel("Name").fill(projectName); + await page.getByRole("button", {name: "Create"}).click(); +} + +/** + * Edit an existing project from its details page. + * + * Executes from: `/dashboard/projects/[projectId]`. + */ +export async function edit(page: Page, currentName: string, updatedName: string) { + await get(page, currentName).click(); + + await page + .getByRole("button", {name: /Delete Project/i}) + .locator("xpath=ancestor::div[1]/preceding-sibling::div[1]/*[1]") + .click(); + + await page.getByLabel("Name").fill(updatedName); + await page.getByRole("button", {name: "Update"}).click(); +} + +/** + * Delete an existing project from its details page. + * + * Executes from: `/dashboard/projects/[projectId]`. + * */ +export async function remove(page: Page, projectName: string) { + await get(page, projectName).click(); + await page.getByRole("button", {name: /Delete Project/i}).click(); + await page.getByRole("button", {name: "Delete", exact: true}).click(); +} diff --git a/e2e/helpers/session.ts b/e2e/helpers/session.ts new file mode 100644 index 00000000..938f8b3e --- /dev/null +++ b/e2e/helpers/session.ts @@ -0,0 +1 @@ +export const LOCAL_STORAGE_PATH = "./e2e/local-storage.json"; diff --git a/e2e/helpers/storage.ts b/e2e/helpers/storage.ts new file mode 100644 index 00000000..f8a7a606 --- /dev/null +++ b/e2e/helpers/storage.ts @@ -0,0 +1,103 @@ +import {Page} from "@playwright/test"; + + +/** + * Locate a storage channel card in the channels list. + * + * Executes from: `/dashboard/storages/channels`. + */ +export function get(page: Page, channelName: string) { + return page.locator('div.block.transition-all.duration-200.rounded-xl', { + has: page.locator('h3', {hasText: channelName}), + }).first(); +} + +/** + * Fill the storage channel creation form. + * + * Available entrypoints: + * - `button`: the classic add button. + * - `emptyState`: the empty-state CTA. + * - `auto`: uses the classic add button and falls back to the empty-state CTA. + * + * Executes from: `/dashboard/storages/channels`. + */ +export async function create( + page: Page, + provider: "S3" | "Google Drive", + channelName: string, + fillConfig: (page: Page) => Promise, + entrypoint: "auto" | "emptyState" | "button" = "auto", +) { + if (entrypoint === "auto") { + const addButton = page.getByRole("button", {name: /Add storage channel/i}); + if (await addButton.isVisible()) await page.getByRole("button", {name: /Add storage channel/i}).click(); + else await page.getByText("No storage channels configured yet", {exact: true}).click(); + } else if (entrypoint === "button") { + await page.getByRole("button", {name: /Add storage channel/i}).click(); + } else if (entrypoint === "emptyState") { + await page.getByText("No storage channels configured yet", {exact: true}).click(); + } + + await page.getByText(provider, {exact: true}).click(); + await page.getByLabel(/Channel Name/).fill(channelName); + await fillConfig(page); +} + +/** + * Open the edit dialog for an existing storage channel. + * + * Executes from: `/dashboard/storages/channels`. + */ +export async function edit(page: Page, channelName: string) { + const card = get(page, channelName); + await card.locator("button").nth(1).click(); +} + +/** + * Delete an existing storage channel. + * + * Executes from: `/dashboard/storages/channels`. + */ +export async function remove(page: Page, channelName: string) { + const card = get(page, channelName); + await card.locator("button").nth(2).click(); + await page.getByRole("button", {name: "Delete"}).click(); +} + +/** + * Trigger the storage connection test in the current dialog. + * + * Executes from: the add or edit storage channel dialog opened from `/dashboard/storages/channels`. + */ +export async function testConnection(page: Page) { + await page.getByRole("button", {name: /Test Storage/i}).click(); +} + +/** + * Submit the storage channel creation form. + * + * Executes from: the add storage channel dialog opened from `/dashboard/storages/channels`. + */ +export async function submit(page: Page) { + await page.getByRole("button", {name: "Add Channel"}).click(); +} + +/** + * Open the edit dialog for a storage channel and trigger the test action. + * + * Executes from: `/dashboard/storages/channels`. + */ +export async function testFromEdit(page: Page, channelName: string) { + await edit(page, channelName); + await testConnection(page); +} + +/** + * Close the current storage channel dialog without saving. + * + * Executes from: the add or edit storage channel dialog. + */ +export async function cancel(page: Page) { + await page.getByRole("button", {name: "Cancel"}).click(); +} diff --git a/e2e/notification/discord.spec.ts b/e2e/notification/discord.spec.ts new file mode 100644 index 00000000..4e5f4706 --- /dev/null +++ b/e2e/notification/discord.spec.ts @@ -0,0 +1,71 @@ +import {expect, test} from "@playwright/test"; +import { + cancel, create, get, remove, submit, testFromEdit, +} from "../helpers/notification"; +import {getEnv} from "../helpers/env"; +import {LOCAL_STORAGE_PATH} from "../helpers/session"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const validChannelName = "Discord E2E Required"; +const invalidChannelName = "Discord E2E Invalid"; + +// test.describe.serial("Valid channel", () => { +// test("Create and test a valid Discord channel", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await create(page, "Discord", validChannelName, async (page) => { +// await page.getByLabel(/Discord Webhook URL/).fill(getEnv("E2E_NOTIFICATION_DISCORD_WEBHOOK")); +// }); +// await expect(page.getByRole("heading", {name: "Add Notification Channel"})).toBeVisible(); +// await submit(page); +// await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); +// await expect(get(page, validChannelName)).toBeVisible(); +// +// await testFromEdit(page, validChannelName); +// await expect(page.getByRole("heading", {name: "Edit Notification Channel"})).toBeVisible(); +// await expect(page.getByText("Sent to Discord")).toBeVisible(); +// await cancel(page); +// await expect(page.getByRole("heading", {name: "Edit Notification Channel"})).toHaveCount(0); +// }); +// +// test("Edit and test a valid Discord channel", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await expect(get(page, validChannelName)).toBeVisible(); +// await testFromEdit(page, validChannelName); +// await expect(page.getByRole("heading", {name: "Edit Notification Channel"})).toBeVisible(); +// await expect(page.getByText("Sent to Discord")).toBeVisible(); +// await cancel(page); +// await expect(page.getByRole("heading", {name: "Edit Notification Channel"})).toHaveCount(0); +// }); +// }); + +test.describe.serial("Invalid channel", () => { + test("Create and test invalid Discord channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await create(page, "Discord", invalidChannelName, async (page) => { + await page.getByLabel(/Discord Webhook URL/).fill("https://discord.com/api/webhooks/123456789012345678/wrong-discord-webhook-token"); + }); + await expect(page.getByRole("heading", {name: "Add Notification Channel"})).toBeVisible(); + await submit(page); + await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + + await testFromEdit(page, invalidChannelName); + await expect(page.getByRole("heading", {name: "Edit Notification Channel"})).toBeVisible(); + await expect(page.getByText("An error occurred while testing the notification channel, check your configuration")).toBeVisible(); + await cancel(page); + await expect(page.getByRole("heading", {name: "Edit Notification Channel"})).toHaveCount(0); + }); + + test("Delete invalid Discord channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await remove(page, invalidChannelName); + await expect(page.getByText("Notification channel has been successfully removed.")).toBeVisible(); + await expect(page.getByText(invalidChannelName)).toHaveCount(0); + }); +}); diff --git a/e2e/notification/gotify.spec.ts b/e2e/notification/gotify.spec.ts new file mode 100644 index 00000000..059aa812 --- /dev/null +++ b/e2e/notification/gotify.spec.ts @@ -0,0 +1,66 @@ +import {expect, test} from "@playwright/test"; +import { + cancel, create, get, remove, submit, testFromEdit, +} from "../helpers/notification"; +import {getEnv} from "../helpers/env"; +import {LOCAL_STORAGE_PATH} from "../helpers/session"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const validChannelName = "Gotify E2E Required"; +const invalidChannelName = "Gotify E2E Invalid"; + +// test.describe.serial("Valid channel", () => { +// test("Create and test a valid Gotify channel", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await create(page, "Gotify", validChannelName, async (page) => { +// await page.getByLabel(/Gotify Server URL/).fill(getEnv("E2E_NOTIFICATION_GOTIFY_SERVER_URL")); +// await page.getByLabel(/Application Token/).fill(getEnv("E2E_NOTIFICATION_GOTIFY_APP_TOKEN")); +// }); +// await expect(page.getByRole("heading", {name: "Add Notification Channel"})).toBeVisible(); +// await submit(page); +// await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); +// await expect(get(page, validChannelName)).toBeVisible(); +// +// await testFromEdit(page, validChannelName); +// await expect(page.getByText("Sent to Gotify")).toBeVisible(); +// await cancel(page); +// }); +// +// test("Edit and test a valid Gotify channel", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await expect(get(page, validChannelName)).toBeVisible(); +// await testFromEdit(page, validChannelName); +// await expect(page.getByText("Sent to Gotify")).toBeVisible(); +// await cancel(page); +// }); +// }); + +test.describe.serial("Invalid channel", () => { + test("Create and test invalid Gotify channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await create(page, "Gotify", invalidChannelName, async (page) => { + await page.getByLabel(/Gotify Server URL/).fill(getEnv("E2E_NOTIFICATION_GOTIFY_SERVER_URL")); + await page.getByLabel(/Application Token/).fill("wrong-gotify-app-token"); + }); + await expect(page.getByRole("heading", {name: "Add Notification Channel"})).toBeVisible(); + await submit(page); + await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await testFromEdit(page, invalidChannelName); + await expect(page.getByText("An error occurred while testing the notification channel, check your configuration")).toBeVisible(); + await cancel(page); + }); + + test("Delete invalid Gotify channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await remove(page, invalidChannelName); + await expect(page.getByText("Notification channel has been successfully removed.")).toBeVisible(); + await expect(page.getByText(invalidChannelName)).toHaveCount(0); + }); +}); diff --git a/e2e/notification/ntfy.spec.ts b/e2e/notification/ntfy.spec.ts new file mode 100644 index 00000000..cbf8178f --- /dev/null +++ b/e2e/notification/ntfy.spec.ts @@ -0,0 +1,73 @@ +import {expect, test} from "@playwright/test"; +import { + cancel, create, get, remove, submit, testFromEdit, +} from "../helpers/notification"; +import {getEnv} from "../helpers/env"; +import {LOCAL_STORAGE_PATH} from "../helpers/session"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const requiredChannelName = "Ntfy E2E Required"; +const optionalChannelName = "Ntfy E2E Optional"; +const invalidChannelName = "Ntfy E2E Invalid"; + +// test.describe.serial("Valid channels", () => { +// test("Create and test a valid Ntfy channel with only required fields", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await create(page, "ntfy.sh", requiredChannelName, async (page) => { +// await page.getByLabel(/Topic Name/).fill(getEnv("E2E_NOTIFICATION_NTFY_TOPIC")); +// }); +// await submit(page); +// await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); +// await expect(get(page, requiredChannelName)).toBeVisible(); +// await testFromEdit(page, requiredChannelName); +// await expect(page.getByText("Sent to ntfy")).toBeVisible(); +// await cancel(page); +// }); +// +// test("Create and test a valid Ntfy channel with optional fields", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await create(page, "ntfy.sh", optionalChannelName, async (page) => { +// await page.getByLabel(/Topic Name/).fill(getEnv("E2E_NOTIFICATION_NTFY_TOPIC")); +// await page.getByLabel(/^Server URL$/).fill(getEnv("E2E_NOTIFICATION_NTFY_SERVER_URL")); +// await page.getByLabel(/^Access Token$/).fill(getEnv("E2E_NOTIFICATION_NTFY_TOKEN")); +// await page.getByLabel(/^Basic Auth Username$/).fill(getEnv("E2E_NOTIFICATION_NTFY_USERNAME")); +// await page.getByLabel(/^Basic Auth Password$/).fill(getEnv("E2E_NOTIFICATION_NTFY_PASSWORD")); +// }); +// await submit(page); +// await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); +// await expect(get(page, optionalChannelName)).toBeVisible(); +// await testFromEdit(page, optionalChannelName); +// await expect(page.getByText("Sent to ntfy")).toBeVisible(); +// await cancel(page); +// }); +// }); + +test.describe.serial("Invalid channel", () => { + test("Create and test invalid Ntfy channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await create(page, "ntfy.sh", invalidChannelName, async (page) => { + await page.getByLabel(/Topic Name/).fill("wrong-ntfy-topic"); + await page.getByLabel(/^Server URL$/).fill(getEnv("E2E_NOTIFICATION_NTFY_SERVER_URL")); + await page.getByLabel(/^Access Token$/).fill("wrong-ntfy-token"); + }); + await submit(page); + await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await testFromEdit(page, invalidChannelName); + await expect(page.getByText("An error occurred while testing the notification channel, check your configuration")).toBeVisible(); + await cancel(page); + }); + + test("Delete invalid Ntfy channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await remove(page, invalidChannelName); + await expect(page.getByText("Notification channel has been successfully removed.")).toBeVisible(); + await expect(page.getByText(invalidChannelName)).toHaveCount(0); + }); +}); diff --git a/e2e/notification/slack.spec.ts b/e2e/notification/slack.spec.ts new file mode 100644 index 00000000..aba1d0f7 --- /dev/null +++ b/e2e/notification/slack.spec.ts @@ -0,0 +1,61 @@ +import {expect, test} from "@playwright/test"; +import { + cancel, create, get, remove, submit, testFromEdit, +} from "../helpers/notification"; +import {getEnv} from "../helpers/env"; +import {LOCAL_STORAGE_PATH} from "../helpers/session"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const validChannelName = "Slack E2E Required"; +const invalidChannelName = "Slack E2E Invalid"; + +// test.describe.serial("Valid channel", () => { +// test("Create and test a valid Slack channel", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await create(page, "Slack", validChannelName, async (page) => { +// await page.getByLabel(/Slack Webhook URL/).fill(getEnv("E2E_NOTIFICATION_SLACK_WEBHOOK")); +// }); +// await submit(page); +// await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); +// await expect(get(page, validChannelName)).toBeVisible(); +// await testFromEdit(page, validChannelName); +// await expect(page.getByText("Sent to Slack")).toBeVisible(); +// await cancel(page); +// }); +// +// test("Edit and test a valid Slack E2E channel", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await expect(get(page, validChannelName)).toBeVisible(); +// await testFromEdit(page, validChannelName); +// await expect(page.getByText("Sent to Slack")).toBeVisible(); +// await cancel(page); +// }); +// }); + +test.describe.serial("Invalid channel", () => { + test("Create and test invalid Slack channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await create(page, "Slack", invalidChannelName, async (page) => { + await page.getByLabel(/Slack Webhook URL/).fill("https://WRONG_SLACK_WEBHOOK"); + }); + await submit(page); + await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await testFromEdit(page, invalidChannelName); + await expect(page.getByText("An error occurred while testing the notification channel, check your configuration")).toBeVisible(); + await cancel(page); + }); + + test("Delete invalid Slack channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await remove(page, invalidChannelName); + await expect(page.getByText("Notification channel has been successfully removed.")).toBeVisible(); + await expect(page.getByText(invalidChannelName)).toHaveCount(0); + }); +}); diff --git a/e2e/notification/smtp.spec.ts b/e2e/notification/smtp.spec.ts new file mode 100644 index 00000000..093b5954 --- /dev/null +++ b/e2e/notification/smtp.spec.ts @@ -0,0 +1,72 @@ +import {expect, test} from "@playwright/test"; +import {getEnv} from "../helpers/env"; +import { + cancel, create, get, remove, submit, testFromEdit, +} from "../helpers/notification"; +import {LOCAL_STORAGE_PATH} from "../helpers/session"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const validChannelName = "SMTP E2E Required"; +const invalidChannelName = "SMTP E2E Invalid"; +const successMessage = `Email sent: ${getEnv("E2E_NOTIFICATION_SMTP_TO")}`; + +// test.describe.serial("Valid channel", () => { +// test("Create and test a valid SMTP channel", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await create(page, "Email", validChannelName, async (page) => { +// await page.getByLabel(/SMTP Host/).fill(getEnv("E2E_NOTIFICATION_SMTP_HOST")); +// await page.getByLabel(/SMTP Port/).fill(getEnv("E2E_NOTIFICATION_SMTP_PORT")); +// await page.getByLabel(/Username/).fill(getEnv("E2E_NOTIFICATION_SMTP_USER")); +// await page.getByLabel(/Password/).fill(getEnv("E2E_NOTIFICATION_SMTP_PASSWORD")); +// await page.getByLabel(/From Email/).fill(getEnv("E2E_NOTIFICATION_SMTP_FROM")); +// await page.getByLabel(/To Email/).fill(getEnv("E2E_NOTIFICATION_SMTP_TO")); +// }); +// await submit(page); +// await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); +// await expect(get(page, validChannelName)).toBeVisible(); +// await testFromEdit(page, validChannelName); +// await expect(page.getByText(successMessage)).toBeVisible(); +// await cancel(page); +// }); +// +// test("Edit and test a valid SMTP channel", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await expect(get(page, validChannelName)).toBeVisible(); +// await testFromEdit(page, validChannelName); +// await expect(page.getByText(successMessage)).toBeVisible(); +// await cancel(page); +// }); +// }); + +test.describe.serial("Invalid channel", () => { + test("Create and test invalid SMTP E2E channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await create(page, "Email", invalidChannelName, async (page) => { + await page.getByLabel(/SMTP Host/).fill("smtp.invalid"); + await page.getByLabel(/SMTP Port/).fill(getEnv("E2E_NOTIFICATION_SMTP_PORT")); + await page.getByLabel(/Username/).fill(getEnv("E2E_NOTIFICATION_SMTP_USER")); + await page.getByLabel(/Password/).fill("wrong-password"); + await page.getByLabel(/From Email/).fill(getEnv("E2E_NOTIFICATION_SMTP_FROM")); + await page.getByLabel(/To Email/).fill(getEnv("E2E_NOTIFICATION_SMTP_TO")); + }); + await submit(page); + await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await testFromEdit(page, invalidChannelName); + await expect(page.getByText("An error occurred while testing the notification channel, check your configuration")).toBeVisible(); + await cancel(page); + }); + + test("Delete invalid SMTP channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await remove(page, invalidChannelName); + await expect(page.getByText("Notification channel has been successfully removed.")).toBeVisible(); + await expect(page.getByText(invalidChannelName)).toHaveCount(0); + }); +}); diff --git a/e2e/notification/teams.spec.ts b/e2e/notification/teams.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/e2e/notification/telegram.spec.ts b/e2e/notification/telegram.spec.ts new file mode 100644 index 00000000..85963d71 --- /dev/null +++ b/e2e/notification/telegram.spec.ts @@ -0,0 +1,72 @@ +import {expect, test} from "@playwright/test"; +import { + cancel, create, get, remove, submit, testFromEdit, +} from "../helpers/notification"; +import {getEnv} from "../helpers/env"; +import {LOCAL_STORAGE_PATH} from "../helpers/session"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const requiredChannelName = "Telegram E2E Required"; +const optionalChannelName = "Telegram E2E Optional"; +const invalidChannelName = "Telegram E2E Invalid"; + +// test.describe.serial("Valid channels", () => { +// test("Create and test a valid Telegram channel", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await create(page, "Telegram", requiredChannelName, async (page) => { +// await page.getByLabel(/Telegram Bot Token/).fill(getEnv("E2E_NOTIFICATION_TELEGRAM_BOT_TOKEN")); +// await page.getByLabel(/Telegram Chat ID/).fill(getEnv("E2E_NOTIFICATION_TELEGRAM_CHAT_ID")); +// }); +// await submit(page); +// await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); +// await expect(get(page, requiredChannelName)).toBeVisible(); +// await testFromEdit(page, requiredChannelName); +// await expect(page.getByText("Sent to Telegram")).toBeVisible(); +// await cancel(page); +// }); +// +// test("Create and test a valid Telegram channel with Topic ID", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await create(page, "Telegram", optionalChannelName, async (page) => { +// await page.getByLabel(/Telegram Bot Token/).fill(getEnv("E2E_NOTIFICATION_TELEGRAM_BOT_TOKEN")); +// await page.getByLabel(/Telegram Chat ID/).fill(getEnv("E2E_NOTIFICATION_TELEGRAM_CHAT_ID")); +// await page.getByLabel(/Telegram Topic ID/).fill(getEnv("E2E_NOTIFICATION_TELEGRAM_TOPIC_ID")); +// }); +// await submit(page); +// await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); +// await expect(get(page, optionalChannelName)).toBeVisible(); +// await testFromEdit(page, optionalChannelName); +// await expect(page.getByText("Sent to Telegram")).toBeVisible(); +// await cancel(page); +// }); +// }); + +test.describe.serial("Invalid channel", () => { + test("Create and test invalid Telegram channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await create(page, "Telegram", invalidChannelName, async (page) => { + await page.getByLabel(/Telegram Bot Token/).fill("wrong-telegram-bot-token"); + await page.getByLabel(/Telegram Chat ID/).fill(getEnv("E2E_NOTIFICATION_TELEGRAM_CHAT_ID")); + await page.getByLabel(/Telegram Topic ID/).fill(getEnv("E2E_NOTIFICATION_TELEGRAM_TOPIC_ID")); + }); + await submit(page); + await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await testFromEdit(page, invalidChannelName); + await expect(page.getByText("An error occurred while testing the notification channel, check your configuration")).toBeVisible(); + await cancel(page); + }); + + test("Delete invalid Telegram channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await remove(page, invalidChannelName); + await expect(page.getByText("Notification channel has been successfully removed.")).toBeVisible(); + await expect(page.getByText(invalidChannelName)).toHaveCount(0); + }); +}); diff --git a/e2e/notification/webhook.spec.ts b/e2e/notification/webhook.spec.ts new file mode 100644 index 00000000..428adf65 --- /dev/null +++ b/e2e/notification/webhook.spec.ts @@ -0,0 +1,71 @@ +import {expect, test} from "@playwright/test"; +import { + cancel, create, get, remove, submit, testFromEdit, +} from "../helpers/notification"; +import {getEnv} from "../helpers/env"; +import {LOCAL_STORAGE_PATH} from "../helpers/session"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const requiredChannelName = "Webhook E2E Required"; +const optionalChannelName = "Webhook E2E Optional"; +const invalidChannelName = "Webhook E2E Invalid"; + +// test.describe.serial("Valid channels", () => { +// test("Create and test a valid Webhook channel", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await create(page, "Webhook", requiredChannelName, async (page) => { +// await page.getByLabel(/Webhook URL/).fill(getEnv("E2E_NOTIFICATION_WEBHOOK_URL")); +// }); +// await submit(page); +// await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); +// await expect(get(page, requiredChannelName)).toBeVisible(); +// await testFromEdit(page, requiredChannelName); +// await expect(page.getByText("Sent to Webhook")).toBeVisible(); +// await cancel(page); +// }); +// +// test("Create and test a valid Webhook channel with optional header", async ({page}) => { +// await page.goto("/dashboard/notifications/channels"); +// await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); +// await create(page, "Webhook", optionalChannelName, async (page) => { +// await page.getByLabel(/Webhook URL/).fill(getEnv("E2E_NOTIFICATION_WEBHOOK_URL")); +// await page.getByLabel(/^Header Name$/).fill(getEnv("E2E_NOTIFICATION_WEBHOOK_SECRET_HEADER")); +// await page.getByLabel(/^Secret Value$/).fill(getEnv("E2E_NOTIFICATION_WEBHOOK_SECRET")); +// }); +// await submit(page); +// await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); +// await expect(get(page, optionalChannelName)).toBeVisible(); +// await testFromEdit(page, optionalChannelName); +// await expect(page.getByText("Sent to Webhook")).toBeVisible(); +// await cancel(page); +// }); +// }); + +test.describe.serial("Invalid channel", () => { + test("Create and test invalid Webhook channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await create(page, "Webhook", invalidChannelName, async (page) => { + await page.getByLabel(/Webhook URL/).fill("https://webhook.example.com/api/wrong-webhook"); + await page.getByLabel(/^Header Name$/).fill(getEnv("E2E_NOTIFICATION_WEBHOOK_SECRET_HEADER")); + await page.getByLabel(/^Secret Value$/).fill("wrong-webhook-secret"); + }); + await submit(page); + await expect(page.getByText("Notification channel has been successfully created.")).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await testFromEdit(page, invalidChannelName); + await expect(page.getByText("An error occurred while testing the notification channel, check your configuration")).toBeVisible(); + await cancel(page); + }); + + test("Delete invalid Webhook E2E channel", async ({page}) => { + await page.goto("/dashboard/notifications/channels"); + await expect(page.getByRole("heading", {name: "Notification channels"})).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await remove(page, invalidChannelName); + await expect(page.getByText("Notification channel has been successfully removed.")).toBeVisible(); + await expect(page.getByText(invalidChannelName)).toHaveCount(0); + }); +}); diff --git a/e2e/project.spec.ts b/e2e/project.spec.ts new file mode 100644 index 00000000..7685ccdf --- /dev/null +++ b/e2e/project.spec.ts @@ -0,0 +1,59 @@ +import {expect, test} from "@playwright/test"; +import {create, edit, get, remove} from "./helpers/project"; +import {LOCAL_STORAGE_PATH} from "./helpers/session"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const project = { + emptyStateName: "Project A", + buttonName: "Project B", + updatedButtonName: "Project B Updated", +}; + +test.describe.serial(() => { + test("Create a project from empty state", async ({page}) => { + await page.goto("/dashboard/projects"); + await expect(page.getByRole("heading", {name: "Projects"})).toBeVisible(); + await expect(page.getByText("Create new Project", {exact: true})).toBeVisible(); + + await create(page, "emptyState", project.emptyStateName); + + await expect(page.getByText("Project has been successfully created.")).toBeVisible(); + await expect(get(page, project.emptyStateName)).toBeVisible(); + await expect(page.getByText("Create new Project", {exact: true})).toHaveCount(0); + }); + + test("Create a project from classic button", async ({page}) => { + await page.goto("/dashboard/projects"); + await expect(page.getByRole("heading", {name: "Projects"})).toBeVisible(); + await expect(get(page, project.emptyStateName)).toBeVisible(); + + await create(page, "button", project.buttonName); + + await expect(page.getByText("Project has been successfully created.")).toBeVisible(); + await expect(get(page, project.buttonName)).toBeVisible(); + }); + + test("Edit the second created project", async ({page}) => { + await page.goto("/dashboard/projects"); + await expect(page.getByRole("heading", {name: "Projects"})).toBeVisible(); + await expect(get(page, project.buttonName)).toBeVisible(); + + await edit(page, project.buttonName, project.updatedButtonName); + + await expect(page.getByText("Project has been successfully updated.")).toBeVisible(); + await expect(page.getByText(project.updatedButtonName, {exact: true})).toBeVisible(); + }); + + test("Delete the second created project", async ({page}) => { + await page.goto("/dashboard/projects"); + await expect(page.getByRole("heading", {name: "Projects"})).toBeVisible(); + await expect(get(page, project.updatedButtonName)).toBeVisible(); + + await remove(page, project.updatedButtonName); + + await expect(page).toHaveURL("/dashboard/projects"); + await expect(page.getByText("Projects has been successfully archived.")).toBeVisible(); + await expect(page.getByText(project.updatedButtonName)).toHaveCount(0); + }); +}); diff --git a/e2e/setup.spec.ts b/e2e/setup.spec.ts new file mode 100644 index 00000000..3bcc3baa --- /dev/null +++ b/e2e/setup.spec.ts @@ -0,0 +1,13 @@ +import {test} from "@playwright/test"; +import fs from "fs"; +import {LOCAL_STORAGE_PATH} from "./helpers/session"; + +test.describe(() => { + test.beforeAll(async () => { + if (fs.existsSync(LOCAL_STORAGE_PATH)) fs.unlinkSync(LOCAL_STORAGE_PATH); + fs.writeFileSync(LOCAL_STORAGE_PATH, JSON.stringify({})); + }); + + test("Prepare shared storage state", async () => { + }); +}); diff --git a/e2e/storage/azure.spec.ts b/e2e/storage/azure.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/e2e/storage/gcs.spec.ts b/e2e/storage/gcs.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/e2e/storage/google-drive.spec.ts b/e2e/storage/google-drive.spec.ts new file mode 100644 index 00000000..aa050e20 --- /dev/null +++ b/e2e/storage/google-drive.spec.ts @@ -0,0 +1,60 @@ +import {expect, test} from "@playwright/test"; +import {getEnv} from "../helpers/env"; +import {LOCAL_STORAGE_PATH} from "../helpers/session"; +import { + cancel, create, get, remove, submit, testConnection, testFromEdit, +} from "../helpers/storage"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const requiredChannelName = "Google Drive E2E Required"; +const invalidChannelName = "Google Drive E2E Invalid"; + +// test.describe.serial("Valid channel", () => { +// test("Create and test a valid Google Drive channel", async ({page}) => { +// await page.goto("/dashboard/storages/channels"); +// await expect(page.getByRole("heading", {name: "Storage channels"})).toBeVisible(); +// await create(page, "Google Drive", requiredChannelName, async (page) => { +// await page.getByLabel(/Client ID/).fill(getEnv("E2E_STORAGE_GOOGLE_DRIVE_CLIENT_ID")); +// await page.getByLabel(/Client Secret/).fill(getEnv("E2E_STORAGE_GOOGLE_DRIVE_CLIENT_SECRET")); +// await page.getByLabel(/Folder ID/).fill(getEnv("E2E_STORAGE_GOOGLE_DRIVE_FOLDER_ID")); +// }); +// await expect(page.getByRole("heading", {name: "Add Storage Channel"})).toBeVisible(); +// await testConnection(page); +// await expect(page.getByText("Successfully connected to storage channel")).toBeVisible(); +// await submit(page); +// await expect(page.getByText("Storage channel has been successfully created.")).toBeVisible(); +// await expect(get(page, requiredChannelName)).toBeVisible(); +// +// await testFromEdit(page, requiredChannelName); +// await expect(page.getByRole("heading", {name: "Edit Storage Channel"})).toBeVisible(); +// await expect(page.getByText("Successfully connected to storage channel")).toBeVisible(); +// await cancel(page); +// }); +// }); + +test.describe.serial("Invalid channel", () => { + test("Create and test invalid Google Drive channel", async ({page}) => { + await page.goto("/dashboard/storages/channels"); + await expect(page.getByRole("heading", {name: "Storage channels"})).toBeVisible(); + await create(page, "Google Drive", invalidChannelName, async (page) => { + await page.getByLabel(/Client ID/).fill(getEnv("E2E_STORAGE_GOOGLE_DRIVE_CLIENT_ID")); + await page.getByLabel(/Client Secret/).fill("wrong-google-drive-client-secret"); + await page.getByLabel(/Folder ID/).fill(getEnv("E2E_STORAGE_GOOGLE_DRIVE_FOLDER_ID")); + }); + await testConnection(page); + await expect(page.getByText("An error occurred while testing the storage channel")).toBeVisible(); + await submit(page); + await expect(page.getByText("Storage channel has been successfully created.")).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + }); + + test("Delete invalid Google Drive E2E channel", async ({page}) => { + await page.goto("/dashboard/storages/channels"); + await expect(page.getByRole("heading", {name: "Storage channels"})).toBeVisible(); + await expect(get(page, invalidChannelName)).toBeVisible(); + await remove(page, invalidChannelName); + await expect(page.getByText("Storage channel has been successfully removed.")).toBeVisible(); + await expect(page.getByText(invalidChannelName)).toHaveCount(0); + }); +}); diff --git a/e2e/storage/s3.spec.ts b/e2e/storage/s3.spec.ts new file mode 100644 index 00000000..8993e72e --- /dev/null +++ b/e2e/storage/s3.spec.ts @@ -0,0 +1,121 @@ +import {expect, test} from "@playwright/test"; +import {getEnv} from "../helpers/env"; +import {LOCAL_STORAGE_PATH} from "../helpers/session"; +import { + cancel, create, get, remove, submit, testConnection, testFromEdit, +} from "../helpers/storage"; + +test.use({storageState: LOCAL_STORAGE_PATH}); + +const providers = [ + { + title: "AWS S3", + requiredChannelName: "AWS S3 E2E Required", + optionalChannelName: "AWS S3 E2E Optional", + invalidChannelName: "AWS S3 E2E Invalid", + endpointUrl: getEnv("E2E_STORAGE_AWS_S3_ENDPOINT_URL"), + region: getEnv("E2E_STORAGE_AWS_S3_REGION"), + accessKey: getEnv("E2E_STORAGE_AWS_S3_ACCESS_KEY"), + secretKey: getEnv("E2E_STORAGE_AWS_S3_SECRET_KEY"), + bucketName: getEnv("E2E_STORAGE_AWS_S3_BUCKET_NAME"), + port: getEnv("E2E_STORAGE_AWS_S3_PORT"), + invalidAccessKey: "wrong-aws-access-key", + invalidSecretKey: "wrong-aws-secret-key", + }, + { + title: "Cloudflare R2", + requiredChannelName: "Cloudflare R2 E2E Required", + optionalChannelName: "Cloudflare R2 E2E Optional", + invalidChannelName: "Cloudflare R2 E2E Invalid", + endpointUrl: getEnv("E2E_STORAGE_R2_ENDPOINT_URL"), + region: getEnv("E2E_STORAGE_R2_REGION"), + accessKey: getEnv("E2E_STORAGE_R2_ACCESS_KEY"), + secretKey: getEnv("E2E_STORAGE_R2_SECRET_KEY"), + bucketName: getEnv("E2E_STORAGE_R2_BUCKET_NAME"), + port: getEnv("E2E_STORAGE_R2_PORT"), + invalidAccessKey: "wrong-r2-access-key", + invalidSecretKey: "wrong-r2-secret-key", + }, +] as const; + +for (const provider of providers) { + test.describe(provider.title, () => { + // test.describe.serial("Valid channels", () => { + // test(`Create and test a valid ${provider.title} channel`, async ({page}) => { + // await page.goto("/dashboard/storages/channels"); + // await expect(page.getByRole("heading", {name: "Storage channels"})).toBeVisible(); + // await create(page, "S3", provider.requiredChannelName, async (page) => { + // await page.getByLabel(/Endpoint URL/).fill(provider.endpointUrl); + // await page.getByLabel(/Access Key/).fill(provider.accessKey); + // await page.getByLabel(/Secret Key/).fill(provider.secretKey); + // await page.getByLabel(/Bucket name/).fill(provider.bucketName); + // }); + // await expect(page.getByRole("heading", {name: "Add Storage Channel"})).toBeVisible(); + // await testConnection(page); + // await expect(page.getByText("Successfully connected to storage channel")).toBeVisible(); + // await submit(page); + // await expect(page.getByText("Storage channel has been successfully created.")).toBeVisible(); + // await expect(get(page, provider.requiredChannelName)).toBeVisible(); + // + // await testFromEdit(page, provider.requiredChannelName); + // await expect(page.getByRole("heading", {name: "Edit Storage Channel"})).toBeVisible(); + // await expect(page.getByText("Successfully connected to storage channel")).toBeVisible(); + // await cancel(page); + // }); + // + // test(`Create and test a valid ${provider.title} channel with optional region and port`, async ({page}) => { + // await page.goto("/dashboard/storages/channels"); + // await expect(page.getByRole("heading", {name: "Storage channels"})).toBeVisible(); + // await create(page, "S3", provider.optionalChannelName, async (page) => { + // await page.getByLabel(/Endpoint URL/).fill(provider.endpointUrl); + // await page.getByLabel(/^Region$/).fill(provider.region); + // await page.getByLabel(/Access Key/).fill(provider.accessKey); + // await page.getByLabel(/Secret Key/).fill(provider.secretKey); + // await page.getByLabel(/Bucket name/).fill(provider.bucketName); + // await page.getByLabel(/^Port$/).fill(provider.port); + // }); + // await expect(page.getByRole("heading", {name: "Add Storage Channel"})).toBeVisible(); + // await testConnection(page); + // await expect(page.getByText("Successfully connected to storage channel")).toBeVisible(); + // await submit(page); + // await expect(page.getByText("Storage channel has been successfully created.")).toBeVisible(); + // await expect(get(page, provider.optionalChannelName)).toBeVisible(); + // + // await testFromEdit(page, provider.optionalChannelName); + // await expect(page.getByRole("heading", {name: "Edit Storage Channel"})).toBeVisible(); + // await expect(page.getByText("Successfully connected to storage channel")).toBeVisible(); + // await cancel(page); + // }); + // }); + + test.describe.serial("Invalid channel", () => { + test(`Create and test invalid ${provider.title} channel`, async ({page}) => { + await page.goto("/dashboard/storages/channels"); + await expect(page.getByRole("heading", {name: "Storage channels"})).toBeVisible(); + await create(page, "S3", provider.invalidChannelName, async (page) => { + await page.getByLabel(/Endpoint URL/).fill(provider.endpointUrl); + await page.getByLabel(/^Region$/).fill(provider.region); + await page.getByLabel(/Access Key/).fill(provider.invalidAccessKey); + await page.getByLabel(/Secret Key/).fill(provider.invalidSecretKey); + await page.getByLabel(/Bucket name/).fill(provider.bucketName); + await page.getByLabel(/^Port$/).fill(provider.port); + }); + await expect(page.getByRole("heading", {name: "Add Storage Channel"})).toBeVisible(); + await testConnection(page); + await expect(page.getByText("An error occurred while testing the storage channel")).toBeVisible(); + await submit(page); + await expect(page.getByText("Storage channel has been successfully created.")).toBeVisible(); + await expect(get(page, provider.invalidChannelName)).toBeVisible(); + }); + + test(`Delete invalid ${provider.title} channel`, async ({page}) => { + await page.goto("/dashboard/storages/channels"); + await expect(page.getByRole("heading", {name: "Storage channels"})).toBeVisible(); + await expect(get(page, provider.invalidChannelName)).toBeVisible(); + await remove(page, provider.invalidChannelName); + await expect(page.getByText("Storage channel has been successfully removed.")).toBeVisible(); + await expect(page.getByText(provider.invalidChannelName)).toHaveCount(0); + }); + }); + }); +} diff --git a/package.json b/package.json index 6324f3f4..c2bf40e7 100644 --- a/package.json +++ b/package.json @@ -125,8 +125,9 @@ "eslint": "^9.39.4", "eslint-config-next": "^16.2.1", "eslint-plugin-tailwindcss": "^3.18.2", - "framer-motion": "^12.38.0", - "postcss": "^8.5.8", + "framer-motion": "^12.34.3", + "node-pty": "^1.1.0", + "postcss": "^8.5.6", "release-it": "^19.2.4", "tailwindcss": "^4.2.2", "tsx": "^4.21.0", diff --git a/playwright.config.ts b/playwright.config.ts index 308f8273..cb09219d 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,12 +1,12 @@ import { defineConfig, devices } from '@playwright/test'; +import dotenv from 'dotenv'; +import path from 'path'; /** * Read environment variables from file. * https://github.com/motdotla/dotenv */ -// import dotenv from 'dotenv'; -// import path from 'path'; -// dotenv.config({ path: path.resolve(__dirname, '.env') }); +dotenv.config({ path: path.resolve(__dirname, '.env') }); /** * See https://playwright.dev/docs/test-configuration. @@ -25,55 +25,55 @@ export default defineConfig({ reporter: 'html', /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { - /* Base URL to use in actions like `await page.goto('')`. */ + ...devices['Desktop Chrome'], baseURL: process.env.PROJECT_URL, /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', }, - /* Configure projects for major browsers */ - projects: [ - { - name: 'chromium', - use: { ...devices['Desktop Chrome'] }, - }, + /* Configure projects and dependency order */ + projects: [ + { + name: 'setup', + testMatch: '**/setup.spec.ts', + }, + { + name: 'auth', + testMatch: '**/auth.spec.ts', + dependencies: ['setup'], + }, + { + name: 'access-management', + testMatch: '**/access-management.spec.ts', + dependencies: ['auth'], + }, + { + name: 'notification', + testMatch: '**/notification/**/*.spec.ts', + dependencies: ['access-management'], + }, + { + name: 'storage', + testMatch: '**/storage/**/*.spec.ts', + dependencies: ['access-management'], + }, + { + name: 'agent', + testMatch: '**/agent.spec.ts', + dependencies: ['access-management'], + }, - { - name: 'firefox', - use: { ...devices['Desktop Firefox'] }, - }, + { + name: 'project', + testMatch: '**/project.spec.ts', + dependencies: ['access-management'], + }, + { + name: 'cleanup', + testMatch: '**/cleanup.spec.ts', + dependencies: ['agent', 'storage', 'notification', 'project'], + }, + ] - { - name: 'webkit', - use: { ...devices['Desktop Safari'] }, - }, - - /* Test against mobile viewports. */ - { - name: 'Mobile Chrome', - use: { ...devices['Pixel 5'] }, - }, - { - name: 'Mobile Safari', - use: { ...devices['iPhone 12'] }, - }, - - /* Test against branded browsers. */ - // { - // name: 'Microsoft Edge', - // use: { ...devices['Desktop Edge'], channel: 'msedge' }, - // }, - // { - // name: 'Google Chrome', - // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, - // }, - ], - - /* Run your local dev server before starting the tests */ - // webServer: { - // command: 'docker compose up -d && make up', - // url: 'http://localhost:8887', - // reuseExistingServer: !process.env.CI, - // }, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 40693f40..8d4308d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,10 +10,10 @@ importers: dependencies: '@better-auth/passkey': specifier: ^1.5.6 - version: 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(better-call@1.3.2(zod@3.25.76))(nanostores@1.2.0) + version: 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(better-call@1.3.2(zod@3.25.76))(nanostores@1.2.0) '@better-auth/sso': specifier: ^1.5.6 - version: 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(better-call@1.3.2(zod@3.25.76)) + version: 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(better-call@1.3.2(zod@3.25.76)) '@hookform/resolvers': specifier: ^5.2.2 version: 5.2.2(react-hook-form@7.72.0(react@19.2.4)) @@ -109,7 +109,7 @@ importers: version: 0.13.11(typescript@5.9.3)(zod@3.25.76) '@tanstack/react-query': specifier: ^5.95.2 - version: 5.95.2(react@19.2.4) + version: 5.96.0(react@19.2.4) '@tanstack/react-table': specifier: ^8.21.3 version: 8.21.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -130,7 +130,7 @@ importers: version: 6.0.0 better-auth: specifier: 1.5.6 - version: 1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -151,10 +151,10 @@ importers: version: 16.6.1 drizzle-orm: specifier: ^0.43.1 - version: 0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)) + version: 0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)) drizzle-zod: specifier: ^0.7.1 - version: 0.7.1(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(zod@3.25.76) + version: 0.7.1(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(zod@3.25.76) embla-carousel-react: specifier: ^8.6.0 version: 8.6.0(react@19.2.4) @@ -278,7 +278,7 @@ importers: version: 1.58.2 '@react-email/preview-server': specifier: 4.3.2 - version: 4.3.2(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(postcss@8.5.8) + version: 4.3.2(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(postcss@8.5.6) '@react-email/render': specifier: ^2.0.4 version: 2.0.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -317,7 +317,7 @@ importers: version: 2.22.2(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(typescript@5.9.3)(zod@3.25.76) baseline-browser-mapping: specifier: ^2.10.12 - version: 2.10.12 + version: 2.10.13 drizzle-kit: specifier: ^0.31.10 version: 0.31.10 @@ -329,16 +329,19 @@ importers: version: 9.39.4(jiti@2.6.1) eslint-config-next: specifier: ^16.2.1 - version: 16.2.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + version: 16.2.1(@typescript-eslint/parser@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint-plugin-tailwindcss: specifier: ^3.18.2 version: 3.18.2(tailwindcss@4.2.2) framer-motion: - specifier: ^12.38.0 - version: 12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: ^12.34.3 + version: 12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + node-pty: + specifier: ^1.1.0 + version: 1.1.0 postcss: - specifier: ^8.5.8 - version: 8.5.8 + specifier: ^8.5.6 + version: 8.5.6 release-it: specifier: ^19.2.4 version: 19.2.4(@types/node@22.19.15) @@ -422,8 +425,8 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.29.2': - resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + '@babel/helpers@7.28.6': + resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} engines: {node: '>=6.9.0'} '@babel/parser@7.27.0': @@ -431,13 +434,13 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.29.2': - resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/runtime@7.29.2': - resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + '@babel/runtime@7.28.6': + resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} '@babel/template@7.28.6': @@ -582,14 +585,14 @@ packages: '@drizzle-team/brocli@0.10.2': resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} - '@emnapi/core@1.9.1': - resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} + '@emnapi/core@1.8.1': + resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} - '@emnapi/runtime@1.9.1': - resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - '@emnapi/wasi-threads@1.2.0': - resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} '@esbuild-kit/core-utils@3.3.2': resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} @@ -1237,20 +1240,20 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@floating-ui/core@1.7.5': - resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + '@floating-ui/core@1.7.4': + resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==} - '@floating-ui/dom@1.7.6': - resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + '@floating-ui/dom@1.7.5': + resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==} - '@floating-ui/react-dom@2.1.8': - resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + '@floating-ui/react-dom@2.1.7': + resolution: {integrity: sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' - '@floating-ui/utils@0.2.11': - resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} '@grpc/grpc-js@1.14.3': resolution: {integrity: sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==} @@ -1301,8 +1304,8 @@ packages: '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} - '@img/colour@1.1.0': - resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + '@img/colour@1.0.0': + resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} engines: {node: '>=18'} '@img/sharp-darwin-arm64@0.34.4': @@ -1724,6 +1727,10 @@ packages: '@types/node': optional: true + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@isaacs/cliui@9.0.0': resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} engines: {node: '>=18'} @@ -2019,6 +2026,10 @@ packages: '@pinojs/redact@0.4.0': resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@playwright/test@1.58.2': resolution: {integrity: sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==} engines: {node: '>=18'} @@ -2042,8 +2053,8 @@ packages: '@prisma/config@6.7.0': resolution: {integrity: sha512-di8QDdvSz7DLUi3OOcCHSwxRNeW7jtGRUD2+Z3SdNE3A+pPiNT8WgUJoUyOwJmUr5t+JA2W15P78C/N+8RXrOA==} - '@prisma/config@7.6.0': - resolution: {integrity: sha512-MuAz1MK4PeG5/03YzfzX3CnFVHQ6qePGwUpQRzPzX5tT0ffJ3Tzi9zJZbBc+VzEGFCM8ghW/gTVDR85Syjt+Yw==} + '@prisma/config@7.4.1': + resolution: {integrity: sha512-vteSXm8N46bo3FW9MhPGVHAj+KRgrR6TWtlSk6GqToCKjTnOexXdPZyiDyEsfVW38YhqEmVl6w/6iHN8uYVJcw==} '@prisma/debug@6.19.2': resolution: {integrity: sha512-lFnEZsLdFLmEVCVNdskLDCL8Uup41GDfU0LUfquw+ercJC8ODTuL0WNKgOKmYxCJVvFwf0OuZBzW99DuWmoH2A==} @@ -2051,8 +2062,8 @@ packages: '@prisma/debug@6.7.0': resolution: {integrity: sha512-RabHn9emKoYFsv99RLxvfG2GHzWk2ZI1BuVzqYtmMSIcuGboHY5uFt3Q3boOREM9de6z5s3bQoyKeWnq8Fz22w==} - '@prisma/debug@7.6.0': - resolution: {integrity: sha512-LpHr3qos4lQZ6sxwjStf59YBht7m9/QF7NSQsMH6qGENWZu2w3UkQUGn1h5iRkDjnWRj3VHykOu9qFhps4ADvA==} + '@prisma/debug@7.4.1': + resolution: {integrity: sha512-qEtzO8oLouRv18JDQUC3G3Gnv+fGVscHZm/x1DBB/WT+kOvPDQLM2woX6IGgWnSMYYlrxjuALshT7G/blvY0bQ==} '@prisma/dmmf@6.19.2': resolution: {integrity: sha512-ZHGDQlnrWKwFPAOvJ8hVbmIqNPdE0XXptTeYqmUGhYMDySSts60O8g3KNY1uAqr3nHiyDcpaGIpO1MBYoDW6gQ==} @@ -2060,8 +2071,8 @@ packages: '@prisma/dmmf@6.7.0': resolution: {integrity: sha512-Nabzf5H7KUwYV/1u8R5gTQ7x3ffdPIhtxVJsjhnLOjeuem8YzVu39jOgQbiOlfOvjU4sPYkV9wEXc5tIHumdUw==} - '@prisma/dmmf@7.6.0': - resolution: {integrity: sha512-OZFEOEziUnJJMx2vu3twM5jEIsEyCRDPXq2Y/2XMBNPhnscKvbDWS3DAYyWmH8jqkDn4VqyE1UCvEFt30Pqbww==} + '@prisma/dmmf@7.4.1': + resolution: {integrity: sha512-805aCBILKe+l3A/z3JF/X9cH0ZZZegTOfKzm8zRpoBcOhLy+SRM2kGJ4aIXp5a6ENdAh6FN2u7ikZ16UDCI9Kg==} '@prisma/driver-adapter-utils@6.19.2': resolution: {integrity: sha512-tkHsL3jhx81eXg2oqtJH/1IEs8uEeUb1RpqHtwYqdNb176u9D0mnHRZM1/cKca/XhLpq49Nnd9XDxdMfWcKAYA==} @@ -2069,8 +2080,8 @@ packages: '@prisma/driver-adapter-utils@6.7.0': resolution: {integrity: sha512-xYcXALWz1GsCRqwcDw0kP0R27chn99Co/HMX0nyOvIjAOo+41Tl/qcCOce/Ik1wNMGTI68N64kt3iccJ4EJoCQ==} - '@prisma/driver-adapter-utils@7.6.0': - resolution: {integrity: sha512-D8j3p0RnhLuufMaRLX6QqtGgPC5Ao3l5oFP6Q5AL0rTHi4vna+NzGEipwCsfvcSvaGFCbsH3lsTMbb4WvY+ovA==} + '@prisma/driver-adapter-utils@7.4.1': + resolution: {integrity: sha512-gEZOC2tnlHaZNbHUdbK8YvQphq2tKq/Ovu1YixJ/hPSutDAvNzC3R+xUeBuJ4AJp236eELMzwxb7rgo3UbRkTg==} '@prisma/engines-version@6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed': resolution: {integrity: sha512-EvpOFEWf1KkJpDsBCrih0kg3HdHuaCnXmMn7XFPObpFTzagK1N0Q0FMnYPsEhvARfANP5Ok11QyoTIRA2hgJTA==} @@ -2078,8 +2089,8 @@ packages: '@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': resolution: {integrity: sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==} - '@prisma/engines-version@7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711': - resolution: {integrity: sha512-r51DLcJ8bDRSrBEJF3J4cinoWyGA7rfP2mG6lD90VqIbGNOkbfcLcXalSVjq5Y6brQS3vcjrq4GbyUb1Cb7vkw==} + '@prisma/engines-version@7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3': + resolution: {integrity: sha512-fUxVd1TjOW8K4XsZ8dAm88sDW5Ry7AxWDfsYEWwScS6Fjo3caKC6hgNumUfsmsy0Il9LjDn5X0PpVXNt3iwayw==} '@prisma/engines@6.19.2': resolution: {integrity: sha512-TTkJ8r+uk/uqczX40wb+ODG0E0icVsMgwCTyTHXehaEfb0uo80M9g1aW1tEJrxmFHeOZFXdI2sTA1j1AgcHi4A==} @@ -2087,8 +2098,8 @@ packages: '@prisma/engines@6.7.0': resolution: {integrity: sha512-3wDMesnOxPrOsq++e5oKV9LmIiEazFTRFZrlULDQ8fxdub5w4NgRBoxtWbvXmj2nJVCnzuz6eFix3OhIqsZ1jw==} - '@prisma/engines@7.6.0': - resolution: {integrity: sha512-Sn5edRzhHqgRV2M+A0eIbY442B4mReWWf3pKs/LKreYgW7oa/up8JtK/s4iv/EQA097cyboZ08mmkpbLp+tZ3w==} + '@prisma/engines@7.4.1': + resolution: {integrity: sha512-BZEBdHvNJx5PzIG37EI/Zi5UUI5hGWjkYsQmKa7OIK6evAvebOTwutjS/VRI6cA6grmA52eLZR+oekGRMqkKxQ==} '@prisma/fetch-engine@6.19.2': resolution: {integrity: sha512-h4Ff4Pho+SR1S8XerMCC12X//oY2bG3Iug/fUnudfcXEUnIeRiBdXHFdGlGOgQ3HqKgosTEhkZMvGM9tWtYC+Q==} @@ -2096,8 +2107,8 @@ packages: '@prisma/fetch-engine@6.7.0': resolution: {integrity: sha512-zLlAGnrkmioPKJR4Yf7NfW3hftcvqeNNEHleMZK9yX7RZSkhmxacAYyfGsCcqRt47jiZ7RKdgE0Wh2fWnm7WsQ==} - '@prisma/fetch-engine@7.6.0': - resolution: {integrity: sha512-N575Ni95c3FkduWY/eKTHqNYgNbceZ1tQaSknVtJjpKmiiBXmniESn/GTxsDvICC4ZeiNrXxioGInzQrCdx16w==} + '@prisma/fetch-engine@7.4.1': + resolution: {integrity: sha512-Z9kbuxX2bvEsyeS3LZEiEnxG0lVtZbpYgaAnPj69N+A9f2De8Lta0EoFtld9zhfERVPIQWhSWUc8himky3qYdA==} '@prisma/generator-helper@6.19.2': resolution: {integrity: sha512-vSjDbHhtKjRDgywTDYyAJLEe+kMxq4DNLNiurk/tGca8W/H7duX4Z4UdvYXcv3kWmmgJJmdndh41dgIsrewa3w==} @@ -2105,8 +2116,8 @@ packages: '@prisma/generator-helper@6.7.0': resolution: {integrity: sha512-z4ey7n8eUFx7Ol7RJCoEo9SVK2roy80qLXdrUFlmswcs0e/z03wDl4tpaA02BE2Yi9KCZl2Tkd6oMes81vUefA==} - '@prisma/generator-helper@7.6.0': - resolution: {integrity: sha512-Wnb7NypN2581AXsaDdfGM6Guvfg6ahs0ooWHhFwD+/mrE3rI122cNRWMV9W1hqyt5OITs+3TV2M6GZZ16NcwjQ==} + '@prisma/generator-helper@7.4.1': + resolution: {integrity: sha512-moKkU9xHt3S3QAgh4AhVYpAjXSVH3P8N1CBmZ/hepGHSKdVn8aq+viGL942HH+5/t//1bZ0Gd9hUlCjttAn1FQ==} '@prisma/generator@6.19.2': resolution: {integrity: sha512-2xDQQUJh2s6Ty9I9CIGRz7Z8pEGxKxjU/lkFyLI5f83fDoISUaGhWQZGW35xMqKVDoNRM93w1ghm+1ScRy0mAA==} @@ -2114,8 +2125,8 @@ packages: '@prisma/generator@6.7.0': resolution: {integrity: sha512-wCsD7QJn1JBKJfv5uOMhwBCvZPGerPJ3EC2HocFPFaHSzVIXLi/zNb/8gpBxervOXTbQRJ2dpqvMsJnwAnPi8A==} - '@prisma/generator@7.6.0': - resolution: {integrity: sha512-F09ZN/QVlKuvoAKEnHZB3LBbooKQTrio7NrKhI7tf0C9XZuCoALP/F7gADpTayXDmPaII1Klit3SJmJsfantEw==} + '@prisma/generator@7.4.1': + resolution: {integrity: sha512-UO9DHDWLvZxAhOZmutOKJUVKLHCqkQze4ZzdOQpO2rbz9s4p7sa/kT1kFKGODIDaGc04T6MziKjsauQVwjKqOQ==} '@prisma/get-platform@6.19.2': resolution: {integrity: sha512-PGLr06JUSTqIvztJtAzIxOwtWKtJm5WwOG6xpsgD37Rc84FpfUBGLKz65YpJBGtkRQGXTYEFie7pYALocC3MtA==} @@ -2123,8 +2134,8 @@ packages: '@prisma/get-platform@6.7.0': resolution: {integrity: sha512-i9IH5lO4fQwnMLvQLYNdgVh9TK3PuWBfQd7QLk/YurnAIg+VeADcZDbmhAi4XBBDD+hDif9hrKyASu0hbjwabw==} - '@prisma/get-platform@7.6.0': - resolution: {integrity: sha512-ohZDwXvtmnbzOcutR2D13lDWpZP1wQjmPyztmt0AwXLzQI7q95EE7NYCvS+M6N6SivT+BM0NOqLmTH3wms4L3A==} + '@prisma/get-platform@7.4.1': + resolution: {integrity: sha512-kN4tmkQzlgm/KtE+jTNSYjsDxxe/5i6GApPI32BN9T0tlgsgSBtDJbjGBICttkAIjsh73dXf8raPKxO/2n2UUg==} '@prisma/internals@6.19.2': resolution: {integrity: sha512-ciXNy15WKIg4rjuA0dNZ03CMJEneoEi47a3E6Yp59KI90M7r/nieaiqSRtWakl9nKj2YKfRX6nraYC3zaeSQXQ==} @@ -2142,8 +2153,8 @@ packages: typescript: optional: true - '@prisma/internals@7.6.0': - resolution: {integrity: sha512-0Q5B32twK3csXNiu+frqsrRODQJxYdMxdYeLSKpjCwWkTZyHRkIv+/zhUxp85zAHOM56H1Q0eieIcK7hKqPhnA==} + '@prisma/internals@7.4.1': + resolution: {integrity: sha512-P57Go0nC3LVYjqEs/WT+jfak9OcdMIgAUXrIQXvMlB/tggsgVYuSCoBiOXw6o8B//D/HS/E9QMVlb3K7o/utPg==} peerDependencies: typescript: '>=5.4.0' peerDependenciesMeta: @@ -2156,8 +2167,8 @@ packages: '@prisma/prisma-schema-wasm@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': resolution: {integrity: sha512-/5JrsJQAOIWSl+9WMM/0ugd737kT9zdMNr7EFaP7ogeMxAhxQ78uaOV6JYGEocD8LC0gZx7MXmVE/CTfYdJ2iA==} - '@prisma/prisma-schema-wasm@7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711': - resolution: {integrity: sha512-sGWZsHVJlxX/lDZiwFg00kyZGwZo3vwN4v5jaMus+7j1763SsXjrW1MSykDUZoy8W1Ent9kCyPRpu9dy/ajnIg==} + '@prisma/prisma-schema-wasm@7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3': + resolution: {integrity: sha512-7J7kF0YCsY4blgM+VFq3rG1+mgFS8drZiKRKah1wsLN77t4ZS+6VwI89qTN6SlMakzlkd3giwQqDxr/utPgFXw==} '@prisma/schema-engine-wasm@6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed': resolution: {integrity: sha512-BMdbaajhV46xPBEqwV/7pxYR67hA02ywUcKDKTIULhaofdbhCUee/O0zqoG4TmgsQZc3DUdwK7nmh2U7Ndj3fA==} @@ -2165,8 +2176,8 @@ packages: '@prisma/schema-engine-wasm@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': resolution: {integrity: sha512-mXtzeePkSdqpr/HAIclqzQEf+tBzLawy7NQ9AaRCfg8N/cruavpsocgbSwOOfV7JTk9JubyzKuR3tp2bNNuWbQ==} - '@prisma/schema-engine-wasm@7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711': - resolution: {integrity: sha512-FNs45iHWzdmWL7NzZx2L1GUX1bIQuTjGBlLwDzlgwFx4jWZ3D3y7e5zDWq8MYY2GZzbRDfH2eTVzD0cKhLp5BQ==} + '@prisma/schema-engine-wasm@7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3': + resolution: {integrity: sha512-R95Js2Kk+iPVEAan8D+aBQgSSJJIrvsDzNVwBNjsYuTd42YRoZJnJP6YJ/YNBMfNyWnjx7ulQ20Ol1ubA72xGg==} '@prisma/schema-files-loader@6.19.2': resolution: {integrity: sha512-v4dHwmYn0rsn6E6Lo6EH4oT7rYVlbJTKWUL3j4gjX0AyQefm3NIITFdYuonDy1S4y2Z/3D1r8gCVjFLskKfK/A==} @@ -2174,8 +2185,8 @@ packages: '@prisma/schema-files-loader@6.7.0': resolution: {integrity: sha512-JaAu/hcMAX6rEhB48wTTyTqo7BNS2Cw8ReTGdqIHXJlBHz4p1HxvoqYcmJw/WEsjUx07J0L7RgQJhhbJpo1cdQ==} - '@prisma/schema-files-loader@7.6.0': - resolution: {integrity: sha512-D5JZLfDQyWPqit3lxNbGCxHSTQwJ2bB9lY6navoYYdL6lulPgsMj5+atAYaWF5hP4Akibr33CS3HZFZlUfH8IQ==} + '@prisma/schema-files-loader@7.4.1': + resolution: {integrity: sha512-w67qWHGPKvmemfk7BjMaOqzMZGc0d4BByxoQsP0B93svH/O3NwnC4gfFN4RG7T/IYgnpn6i7xAQQtPx2cyI6hQ==} '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -3036,11 +3047,11 @@ packages: resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==} engines: {node: '>=18'} - '@simplewebauthn/browser@13.3.0': - resolution: {integrity: sha512-BE/UWv6FOToAdVk0EokzkqQQDOWtNydYlY6+OrmiZ5SCNmb41VehttboTetUM3T/fr6EAFYVXjz4My2wg230rQ==} + '@simplewebauthn/browser@13.2.2': + resolution: {integrity: sha512-FNW1oLQpTJyqG5kkDg5ZsotvWgmBaC6jCHR7Ej0qUNep36Wl9tj2eZu7J5rP+uhXgHaLk+QQ3lqcw2vS5MX1IA==} - '@simplewebauthn/server@13.3.0': - resolution: {integrity: sha512-MLHYFrYG8/wK2i+86XMhiecK72nMaHKKt4bo+7Q1TbuG9iGjlSdfkPWKO5ZFE/BX+ygCJ7pr8H/AJeyAj1EaTQ==} + '@simplewebauthn/server@13.2.3': + resolution: {integrity: sha512-ZhcVBOw63birYx9jVfbhK6rTehckVes8PeWV324zpmdxr0BUfylospwMzcrxrdMcOi48MHWj2LCA+S528LnGvg==} engines: {node: '>=20.0.0'} '@socket.io/component-emitter@3.1.2': @@ -3052,9 +3063,6 @@ packages: '@standard-schema/utils@0.3.0': resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} - '@streamparser/json@0.0.22': - resolution: {integrity: sha512-b6gTSBjJ8G8SuO3Gbbj+zXbVx8NSs1EbpbMKpzGLWMdkR+98McH9bEjSz3+0mPJf68c5nxa3CrJHp5EQNXM6zQ==} - '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -3184,11 +3192,11 @@ packages: '@tailwindcss/postcss@4.2.2': resolution: {integrity: sha512-n4goKQbW8RVXIbNKRB/45LzyUqN451deQK0nzIeauVEqjlI49slUlgKYJM2QyUzap/PcpnS7kzSUmPb1sCRvYQ==} - '@tanstack/query-core@5.95.2': - resolution: {integrity: sha512-o4T8vZHZET4Bib3jZ/tCW9/7080urD4c+0/AUaYVpIqOsr7y0reBc1oX3ttNaSW5mYyvZHctiQ/UOP2PfdmFEQ==} + '@tanstack/query-core@5.96.0': + resolution: {integrity: sha512-sfO3uQeol1BU7cRP6NYY7nAiX3GiNY20lI/dtSbKLwcIkYw/X+w/tEsQAkc544AfIhBX/IvH/QYtPHrPhyAKGw==} - '@tanstack/react-query@5.95.2': - resolution: {integrity: sha512-/wGkvLj/st5Ud1Q76KF1uFxScV7WeqN1slQx5280ycwAyYkIPGaRZAEgHxe3bjirSd5Zpwkj6zNcR4cqYni/ZA==} + '@tanstack/react-query@5.96.0': + resolution: {integrity: sha512-6qbjdm1K5kizVKv9TNqhIN3doq2anRhdF2XaFMFSn4m8L22S69RV+FilvlyVT4RoJyMxtPU5rs4RpdFa/PEC7A==} peerDependencies: react: ^18 || ^19 @@ -3266,8 +3274,8 @@ packages: '@types/node-forge@1.3.14': resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} - '@types/node@20.19.37': - resolution: {integrity: sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==} + '@types/node@20.19.33': + resolution: {integrity: sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==} '@types/node@22.14.1': resolution: {integrity: sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==} @@ -3316,63 +3324,63 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@typescript-eslint/eslint-plugin@8.57.2': - resolution: {integrity: sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==} + '@typescript-eslint/eslint-plugin@8.56.1': + resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.57.2 + '@typescript-eslint/parser': ^8.56.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.57.2': - resolution: {integrity: sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==} + '@typescript-eslint/parser@8.56.1': + resolution: {integrity: sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.57.2': - resolution: {integrity: sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==} + '@typescript-eslint/project-service@8.56.1': + resolution: {integrity: sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.57.2': - resolution: {integrity: sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==} + '@typescript-eslint/scope-manager@8.56.1': + resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.57.2': - resolution: {integrity: sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==} + '@typescript-eslint/tsconfig-utils@8.56.1': + resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.57.2': - resolution: {integrity: sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==} + '@typescript-eslint/type-utils@8.56.1': + resolution: {integrity: sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.57.2': - resolution: {integrity: sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==} + '@typescript-eslint/types@8.56.1': + resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.57.2': - resolution: {integrity: sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==} + '@typescript-eslint/typescript-estree@8.56.1': + resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.57.2': - resolution: {integrity: sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==} + '@typescript-eslint/utils@8.56.1': + resolution: {integrity: sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.57.2': - resolution: {integrity: sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==} + '@typescript-eslint/visitor-keys@8.56.1': + resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -3530,6 +3538,7 @@ packages: '@xmldom/xmldom@0.8.11': resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==} engines: {node: '>=10.0.0'} + deprecated: this version has critical issues, please update to the latest version '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -3643,6 +3652,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -3772,8 +3785,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.10.12: - resolution: {integrity: sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==} + baseline-browser-mapping@2.10.13: + resolution: {integrity: sha512-BL2sTuHOdy0YT1lYieUxTw/QMtPBC3pmlJC6xk8BBYVv6vcw3SGdKemQ+Xsx9ik2F/lYDO9tqsFQH1r9PFuHKw==} engines: {node: '>=6.0.0'} hasBin: true @@ -3880,14 +3893,14 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - brace-expansion@1.1.13: - resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - brace-expansion@2.0.3: - resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - brace-expansion@5.0.5: - resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + brace-expansion@5.0.3: + resolution: {integrity: sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==} engines: {node: 18 || 20 || >=22} braces@3.0.3: @@ -3965,12 +3978,12 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - camelcase@9.0.0: - resolution: {integrity: sha512-TO9xmyXTZ9HUHI8M1OnvExxYB0eYVS/1e5s7IDMTAoIcwUd+aNcFODs6Xk83mobk0velyHFQgA1yIrvYc6wclw==} - engines: {node: '>=20'} + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} - caniuse-lite@1.0.30001781: - resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==} + caniuse-lite@1.0.30001774: + resolution: {integrity: sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==} capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} @@ -4132,20 +4145,20 @@ packages: constant-case@3.0.4: resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} - conventional-changelog-angular@8.3.0: - resolution: {integrity: sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA==} + conventional-changelog-angular@8.3.1: + resolution: {integrity: sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==} engines: {node: '>=18'} - conventional-changelog-conventionalcommits@9.3.0: - resolution: {integrity: sha512-kYFx6gAyjSIMwNtASkI3ZE99U1fuVDJr0yTYgVy+I2QG46zNZfl2her+0+eoviG82c5WQvW1jMt1eOQTeJLodA==} + conventional-changelog-conventionalcommits@9.3.1: + resolution: {integrity: sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw==} engines: {node: '>=18'} conventional-changelog-preset-loader@5.0.0: resolution: {integrity: sha512-SetDSntXLk8Jh1NOAl1Gu5uLiCNSYenB5tm0YVeZKePRIgDW9lQImromTwLa3c/Gae298tsgOM+/CYT9XAl0NA==} engines: {node: '>=18'} - conventional-changelog-writer@8.4.0: - resolution: {integrity: sha512-HHBFkk1EECxxmCi4CTu091iuDpQv5/OavuCUAuZmrkWpmYfyD816nom1CvtfXJ/uYfAAjavgHvXHX291tSLK8g==} + conventional-changelog-writer@8.3.0: + resolution: {integrity: sha512-l5hDOHjcTUVtnZJapoqXMCJ3IbyF6oV/vnxKL13AHulFH7mDp4PMJARxI7LWzob6UDDvhxIUWGTNUPW84JabQg==} engines: {node: '>=18'} hasBin: true @@ -4529,17 +4542,17 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} effect@3.18.4: resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} - effect@3.20.0: - resolution: {integrity: sha512-qMLfDJscrNG8p/aw+IkT9W7fgj50Z4wG5bLBy0Txsxz8iUHjDIkOgO3SV0WZfnQbNG2VJYb0b+rDLMrhM4+Krw==} - - electron-to-chromium@1.5.328: - resolution: {integrity: sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==} + electron-to-chromium@1.5.302: + resolution: {integrity: sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==} embla-carousel-react@8.6.0: resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} @@ -4583,12 +4596,12 @@ packages: resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} engines: {node: '>=10.0.0'} - engine.io@6.6.6: - resolution: {integrity: sha512-U2SN0w3OpjFRVlrc17E6TMDmH58Xl9rai1MblNjAdwWp07Kk+llmzX0hjDpQdrDGzwmvOtgM5yI+meYX6iZ2xA==} + engine.io@6.6.5: + resolution: {integrity: sha512-2RZdgEbXmp5+dVbRm0P7HQUImZpICccJy7rN7Tv+SFa55pH+lxnuw6/K1ZxxBfHoYpSkHLAO92oa8O4SwFXA2A==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.20.1: - resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} engines: {node: '>=10.13.0'} entities@4.5.0: @@ -4615,8 +4628,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-iterator-helpers@1.3.1: - resolution: {integrity: sha512-zWwRvqWiuBPr0muUG/78cW3aHROFCNIQ3zpmYDpwdbnt2m+xlNyRWpHBpa2lJjSBit7BQ+RXA1iwbSmu5yJ/EQ==} + es-iterator-helpers@1.2.2: + resolution: {integrity: sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==} engines: {node: '>= 0.4'} es-module-lexer@2.0.0: @@ -4885,6 +4898,10 @@ packages: fast-xml-builder@1.1.4: resolution: {integrity: sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==} + fast-xml-parser@5.3.9: + resolution: {integrity: sha512-zU0KUuO9U+fLGduTDdxQ6qsQLIxRg4EK5AMduwBNGNCSfCGRSbNS7OpH343NFQlLDg1jxoH68JSbOPAGksIGvg==} + hasBin: true + fast-xml-parser@5.5.9: resolution: {integrity: sha512-jldvxr1MC6rtiZKgrFnDSvT8xuH+eJqxqOBThUVjYrxssYTo1avZLGql5l0a0BAERR01CadYzZ83kVEkbyDg+g==} hasBin: true @@ -4935,8 +4952,8 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} @@ -4971,6 +4988,20 @@ packages: react-dom: optional: true + framer-motion@12.34.3: + resolution: {integrity: sha512-v81ecyZKYO/DfpTwHivqkxSUBzvceOpoI+wLfgCgoUIKxlFKEXdg0oR9imxwXumT4SFy8vRk9xzJ5l3/Du/55Q==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + framer-motion@12.38.0: resolution: {integrity: sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==} peerDependencies: @@ -5012,8 +5043,8 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - gaxios@7.1.4: - resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} + gaxios@7.1.3: + resolution: {integrity: sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==} engines: {node: '>=18'} gcp-metadata@8.1.2: @@ -5056,8 +5087,8 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.13.7: - resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==} + get-tsconfig@4.13.6: + resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} get-uri@6.0.5: resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} @@ -5084,6 +5115,11 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + glob@11.1.0: resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} engines: {node: 20 || >=22} @@ -5106,8 +5142,8 @@ packages: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} - google-auth-library@10.6.2: - resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} + google-auth-library@10.6.1: + resolution: {integrity: sha512-5awwuLrzNol+pFDmKJd0dKtZ0fPLAtoA5p7YO4ODsDu6ONJUVqbYwvv8y2ZBO5MBNp9TJXigB19710kYpBPdtA==} engines: {node: '>=18'} google-logging-utils@1.1.3: @@ -5129,8 +5165,8 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - handlebars@4.7.9: - resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} engines: {node: '>=0.4.7'} hasBin: true @@ -5453,6 +5489,9 @@ packages: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@4.2.3: resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} engines: {node: 20 || >=22} @@ -5473,8 +5512,8 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true - jose@6.2.2: - resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + jose@6.1.3: + resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==} joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} @@ -5510,8 +5549,8 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json-with-bigint@3.5.8: - resolution: {integrity: sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==} + json-with-bigint@3.5.7: + resolution: {integrity: sha512-7ei3MdAI5+fJPVnKlW77TKNKwQ5ppSzWvhPuSuINT/GYW9ZOC1eRKOuhV9yHG5aEsUPj9BBx5JIekkmoLHxZOw==} json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} @@ -5542,8 +5581,8 @@ packages: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} - kysely@0.28.14: - resolution: {integrity: sha512-SU3lgh0rPvq7upc6vvdVrCsSMUG1h3ChvHVOY7wJ2fw4C9QEB7X3d5eyYEyULUX7UQtxZJtZXGuT6U2US72UYA==} + kysely@0.28.15: + resolution: {integrity: sha512-r2clcf7HLWvDXaVUEvQymXJY4i3bSOIV3xsL/Upy3ZfSv5HeKsk9tsqbBptLvth5qHEIhxeHTA2jNLyQABkLBA==} engines: {node: '>=20.0.0'} langium@1.3.1: @@ -5721,8 +5760,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.2.7: - resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==} + lru-cache@11.2.6: + resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -5801,17 +5840,24 @@ packages: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} - minimatch@10.2.4: - resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + minimatch@10.2.3: + resolution: {integrity: sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==} engines: {node: 18 || 20 || >=22} + minimatch@3.1.4: + resolution: {integrity: sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==} + minimatch@3.1.5: resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - minimatch@5.1.9: - resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + minimatch@5.1.8: + resolution: {integrity: sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==} engines: {node: '>=10'} + minimatch@9.0.7: + resolution: {integrity: sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -5835,9 +5881,15 @@ packages: engines: {node: '>=10'} hasBin: true + motion-dom@12.34.3: + resolution: {integrity: sha512-sYgFe+pR9aIM7o4fhs2aXtOI+oqlUd33N9Yoxcgo1Fv7M20sRkHtCmzE/VRNIcq7uNJ+qio+Xubt1FXH3pQ+eQ==} + motion-dom@12.38.0: resolution: {integrity: sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==} + motion-utils@12.29.2: + resolution: {integrity: sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==} + motion-utils@12.36.0: resolution: {integrity: sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==} @@ -5865,8 +5917,8 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nan@2.26.2: - resolution: {integrity: sha512-0tTvBTYkt3tdGw22nrAy50x7gpbGCCFH3AFcyS5WiUu7Eu4vWlri1woE6qHBSfy11vksDqkiwjOnlR7WV8G1Hw==} + nan@2.25.0: + resolution: {integrity: sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==} nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} @@ -5973,8 +6025,11 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - node-addon-api@8.7.0: - resolution: {integrity: sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==} + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-addon-api@8.5.0: + resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==} engines: {node: ^18 || ^20 || >= 21} node-cron@4.2.1: @@ -6017,8 +6072,11 @@ packages: node-html-parser@7.0.1: resolution: {integrity: sha512-KGtmPY2kS0thCWGK0VuPyOS+pBKhhe8gXztzA2ilAOhbUbxa9homF1bOyKvhGzMLXUoRds9IOmr/v5lr/lqNmA==} - node-releases@2.0.36: - resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} + node-pty@1.1.0: + resolution: {integrity: sha512-20JqtutY6JPXTUnL0ij1uad7Qe1baT46lyolh2sSENDd4sTzKZ4nmAFkeAARDKwmlLjPx6XKRlwRUxwjOy+lUg==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} node-rsa@1.1.1: resolution: {integrity: sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==} @@ -6169,6 +6227,9 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} @@ -6223,6 +6284,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.2: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} @@ -6254,6 +6319,9 @@ packages: peerDependencies: pg: '>=8.0' + pg-protocol@1.11.0: + resolution: {integrity: sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==} + pg-protocol@1.13.0: resolution: {integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==} @@ -6276,12 +6344,12 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} pify@2.3.0: @@ -6368,8 +6436,8 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: @@ -6448,8 +6516,8 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - pump@3.0.4: - resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} @@ -6482,6 +6550,9 @@ packages: quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + rc9@2.1.2: resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} @@ -6693,6 +6764,10 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + rou3@0.7.12: resolution: {integrity: sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg==} @@ -6735,11 +6810,11 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - samlify@2.11.0: - resolution: {integrity: sha512-1C9ukjlf0rRsuyqdzztqikdItqa33j9NCCDZgeBiWk0etU6vxNB+SWJKW4Flk07ZlhXeev/twALEKrPhIAyfDg==} + samlify@2.10.2: + resolution: {integrity: sha512-y5s1cHwclqwP8h7K2Wj9SfP1q+1S9+jrs5OAegYTLAiuFi7nDvuKqbiXLmUTvYPMpzHcX94wTY2+D604jgTKvA==} - sax@1.6.0: - resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + sax@1.4.4: + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} engines: {node: '>=11.0.0'} scheduler@0.25.0: @@ -6775,6 +6850,9 @@ packages: sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + set-cookie-parser@3.1.0: resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==} @@ -6853,8 +6931,8 @@ packages: resolution: {integrity: sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==} engines: {node: '>=10.0.0'} - socket.io-parser@4.2.6: - resolution: {integrity: sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==} + socket.io-parser@4.2.5: + resolution: {integrity: sha512-bPMmpy/5WWKHea5Y/jYAP6k74A+hvmRCQaJuJB6I/ML5JZq/KfNieUVo/3Mh7SAqn7TyFdIo6wqYHInG1MU1bQ==} engines: {node: '>=10.0.0'} socket.io@4.8.3: @@ -6954,6 +7032,10 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string-width@7.2.0: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} @@ -6992,8 +7074,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.2.0: - resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} strip-bom@3.0.0: @@ -7016,6 +7098,9 @@ packages: resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} engines: {node: '>=14.16'} + strnum@2.1.2: + resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + strnum@2.2.2: resolution: {integrity: sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==} @@ -7075,8 +7160,8 @@ packages: tailwindcss@4.2.2: resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} - tapable@2.3.2: - resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} tar-fs@2.1.4: @@ -7090,8 +7175,8 @@ packages: resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} engines: {node: '>=8'} - terser-webpack-plugin@5.4.0: - resolution: {integrity: sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==} + terser-webpack-plugin@5.3.16: + resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -7106,8 +7191,8 @@ packages: uglify-js: optional: true - terser@5.46.1: - resolution: {integrity: sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==} + terser@5.46.0: + resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} engines: {node: '>=10'} hasBin: true @@ -7131,8 +7216,8 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyexec@1.0.4: - resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} engines: {node: '>=18'} tinyglobby@0.2.15: @@ -7157,8 +7242,8 @@ packages: resolution: {integrity: sha512-vxXDZg8/+p3gblxB6BhhG5yWVn1kGRlaL8O78UDXc3wRnPizB5g83dcvWV1jpDMIPnjZjOFuxlMmE82XJ4407w==} engines: {node: '>= 0.4'} - ts-api-utils@2.5.0: - resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -7242,8 +7327,8 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@8.57.2: - resolution: {integrity: sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A==} + typescript-eslint@8.56.1: + resolution: {integrity: sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -7273,8 +7358,8 @@ packages: resolution: {integrity: sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==} engines: {node: '>=18.17'} - undici@7.24.6: - resolution: {integrity: sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==} + undici@7.22.0: + resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} engines: {node: '>=20.18.1'} universal-user-agent@7.0.3: @@ -7351,6 +7436,10 @@ packages: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -7438,8 +7527,8 @@ packages: resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} engines: {node: '>=10.13.0'} - webpack@5.105.4: - resolution: {integrity: sha512-jTywjboN9aHxFlToqb0K0Zs9SbBoW4zRUlGzI2tYNxVYcEi/IPpn+Xi4ye5jTLvX2YeLuic/IvxNot+Q1jMoOw==} + webpack@5.105.2: + resolution: {integrity: sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -7503,6 +7592,10 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -7564,10 +7657,6 @@ packages: resolution: {integrity: sha512-NNXnzrkDrAzalLhIUc01jO2mOzXGXh1JwPgkihcLLzw98c0WgYDmmjSh1Kl3wzaxSVWMuA+fe0WTWOBDWCBmNA==} engines: {node: '>=0.6.0'} - xpath@0.0.34: - resolution: {integrity: sha512-FxF6+rkr1rNSQrhUNYrAFJpRXNzlDoMxeXN5qI84939ylEv3qqPFKa85Oxr6tDaJKqwW6KKyo2v26TSv3k6LeA==} - engines: {node: '>=0.6.0'} - xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -7579,8 +7668,8 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.8.3: - resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} engines: {node: '>= 14.6'} hasBin: true @@ -7662,7 +7751,7 @@ snapshots: '@babel/generator': 7.29.1 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.26.10) - '@babel/helpers': 7.29.2 + '@babel/helpers': 7.28.6 '@babel/parser': 7.27.0 '@babel/template': 7.28.6 '@babel/traverse': 7.27.0 @@ -7681,8 +7770,8 @@ snapshots: '@babel/generator': 7.29.1 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.29.2 - '@babel/parser': 7.29.2 + '@babel/helpers': 7.28.6 + '@babel/parser': 7.29.0 '@babel/template': 7.28.6 '@babel/traverse': 7.29.0 '@babel/types': 7.29.0 @@ -7697,7 +7786,7 @@ snapshots: '@babel/generator@7.29.1': dependencies: - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.0 '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 @@ -7744,7 +7833,7 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.29.2': + '@babel/helpers@7.28.6': dependencies: '@babel/template': 7.28.6 '@babel/types': 7.29.0 @@ -7753,16 +7842,16 @@ snapshots: dependencies: '@babel/types': 7.29.0 - '@babel/parser@7.29.2': + '@babel/parser@7.29.0': dependencies: '@babel/types': 7.29.0 - '@babel/runtime@7.29.2': {} + '@babel/runtime@7.28.6': {} '@babel/template@7.28.6': dependencies: '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.0 '@babel/types': 7.29.0 '@babel/traverse@7.27.0': @@ -7782,7 +7871,7 @@ snapshots: '@babel/code-frame': 7.29.0 '@babel/generator': 7.29.1 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.0 '@babel/template': 7.28.6 '@babel/types': 7.29.0 debug: 4.4.3 @@ -7796,7 +7885,7 @@ snapshots: '@balena/dockerignore@1.0.2': {} - '@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0)': + '@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0)': dependencies: '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 @@ -7804,71 +7893,71 @@ snapshots: '@opentelemetry/semantic-conventions': 1.40.0 '@standard-schema/spec': 1.1.0 better-call: 1.3.2(zod@3.25.76) - jose: 6.2.2 - kysely: 0.28.14 + jose: 6.1.3 + kysely: 0.28.15 nanostores: 1.2.0 zod: 4.3.6 - '@better-auth/drizzle-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))': + '@better-auth/drizzle-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 optionalDependencies: - drizzle-orm: 0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)) + drizzle-orm: 0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)) - '@better-auth/kysely-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.14)': + '@better-auth/kysely-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.15)': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 optionalDependencies: - kysely: 0.28.14 + kysely: 0.28.15 - '@better-auth/memory-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/memory-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/mongo-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': + '@better-auth/mongo-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 - '@better-auth/passkey@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(better-call@1.3.2(zod@3.25.76))(nanostores@1.2.0)': + '@better-auth/passkey@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(better-call@1.3.2(zod@3.25.76))(nanostores@1.2.0)': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 - '@simplewebauthn/browser': 13.3.0 - '@simplewebauthn/server': 13.3.0 - better-auth: 1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@simplewebauthn/browser': 13.2.2 + '@simplewebauthn/server': 13.2.3 + better-auth: 1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) better-call: 1.3.2(zod@3.25.76) nanostores: 1.2.0 zod: 4.3.6 - '@better-auth/prisma-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(prisma@6.7.0(typescript@5.9.3))': + '@better-auth/prisma-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(prisma@6.7.0(typescript@5.9.3))': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 optionalDependencies: '@prisma/client': 6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3) prisma: 6.7.0(typescript@5.9.3) - '@better-auth/sso@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(better-call@1.3.2(zod@3.25.76))': + '@better-auth/sso@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(better-call@1.3.2(zod@3.25.76))': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 - better-auth: 1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + better-auth: 1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) better-call: 1.3.2(zod@3.25.76) fast-xml-parser: 5.5.9 - jose: 6.2.2 - samlify: 2.11.0 + jose: 6.1.3 + samlify: 2.10.2 tldts: 6.1.86 zod: 4.3.6 - '@better-auth/telemetry@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))': + '@better-auth/telemetry@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))': dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) + '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 @@ -7904,18 +7993,18 @@ snapshots: '@drizzle-team/brocli@0.10.2': {} - '@emnapi/core@1.9.1': + '@emnapi/core@1.8.1': dependencies: - '@emnapi/wasi-threads': 1.2.0 + '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.9.1': + '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.2.0': + '@emnapi/wasi-threads@1.1.0': dependencies: tslib: 2.8.1 optional: true @@ -7928,7 +8017,7 @@ snapshots: '@esbuild-kit/esm-loader@2.6.5': dependencies: '@esbuild-kit/core-utils': 3.3.2 - get-tsconfig: 4.13.7 + get-tsconfig: 4.13.6 '@esbuild/aix-ppc64@0.25.10': optional: true @@ -8276,28 +8365,28 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 - '@floating-ui/core@1.7.5': + '@floating-ui/core@1.7.4': dependencies: - '@floating-ui/utils': 0.2.11 + '@floating-ui/utils': 0.2.10 - '@floating-ui/dom@1.7.6': + '@floating-ui/dom@1.7.5': dependencies: - '@floating-ui/core': 1.7.5 - '@floating-ui/utils': 0.2.11 + '@floating-ui/core': 1.7.4 + '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.8(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@floating-ui/react-dom@2.1.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@floating-ui/dom': 1.7.6 + '@floating-ui/dom': 1.7.5 react: 19.0.0 react-dom: 19.0.0(react@19.0.0) - '@floating-ui/react-dom@2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@floating-ui/react-dom@2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@floating-ui/dom': 1.7.6 + '@floating-ui/dom': 1.7.5 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@floating-ui/utils@0.2.11': {} + '@floating-ui/utils@0.2.10': {} '@grpc/grpc-js@1.14.3': dependencies: @@ -8345,7 +8434,7 @@ snapshots: '@iconify/types@2.0.0': {} - '@img/colour@1.1.0': {} + '@img/colour@1.0.0': {} '@img/sharp-darwin-arm64@0.34.4': optionalDependencies: @@ -8501,12 +8590,12 @@ snapshots: '@img/sharp-wasm32@0.34.4': dependencies: - '@emnapi/runtime': 1.9.1 + '@emnapi/runtime': 1.8.1 optional: true '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.9.1 + '@emnapi/runtime': 1.8.1 optional: true '@img/sharp-win32-arm64@0.34.4': @@ -8652,6 +8741,15 @@ snapshots: optionalDependencies: '@types/node': 22.19.15 + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/cliui@9.0.0': {} '@jridgewell/gen-mapping@0.3.13': @@ -8691,8 +8789,8 @@ snapshots: '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.9.1 - '@emnapi/runtime': 1.9.1 + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 '@tybys/wasm-util': 0.10.1 optional: true @@ -8825,7 +8923,7 @@ snapshots: '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 fast-content-type-parse: 3.0.0 - json-with-bigint: 3.5.8 + json-with-bigint: 3.5.7 universal-user-agent: 7.0.3 '@octokit/rest@22.0.1': @@ -8949,6 +9047,9 @@ snapshots: '@pinojs/redact@0.4.0': {} + '@pkgjs/parseargs@0.11.0': + optional: true + '@playwright/test@1.58.2': dependencies: playwright: 1.58.2 @@ -8974,11 +9075,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@prisma/config@7.6.0': + '@prisma/config@7.4.1': dependencies: c12: 3.1.0 deepmerge-ts: 7.1.5 - effect: 3.20.0 + effect: 3.18.4 empathic: 2.0.0 transitivePeerDependencies: - magicast @@ -8987,13 +9088,13 @@ snapshots: '@prisma/debug@6.7.0': {} - '@prisma/debug@7.6.0': {} + '@prisma/debug@7.4.1': {} '@prisma/dmmf@6.19.2': {} '@prisma/dmmf@6.7.0': {} - '@prisma/dmmf@7.6.0': {} + '@prisma/dmmf@7.4.1': {} '@prisma/driver-adapter-utils@6.19.2': dependencies: @@ -9003,15 +9104,15 @@ snapshots: dependencies: '@prisma/debug': 6.7.0 - '@prisma/driver-adapter-utils@7.6.0': + '@prisma/driver-adapter-utils@7.4.1': dependencies: - '@prisma/debug': 7.6.0 + '@prisma/debug': 7.4.1 '@prisma/engines-version@6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed': {} '@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': {} - '@prisma/engines-version@7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711': {} + '@prisma/engines-version@7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3': {} '@prisma/engines@6.19.2': dependencies: @@ -9027,12 +9128,12 @@ snapshots: '@prisma/fetch-engine': 6.7.0 '@prisma/get-platform': 6.7.0 - '@prisma/engines@7.6.0': + '@prisma/engines@7.4.1': dependencies: - '@prisma/debug': 7.6.0 - '@prisma/engines-version': 7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711 - '@prisma/fetch-engine': 7.6.0 - '@prisma/get-platform': 7.6.0 + '@prisma/debug': 7.4.1 + '@prisma/engines-version': 7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3 + '@prisma/fetch-engine': 7.4.1 + '@prisma/get-platform': 7.4.1 '@prisma/fetch-engine@6.19.2': dependencies: @@ -9046,11 +9147,11 @@ snapshots: '@prisma/engines-version': 6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed '@prisma/get-platform': 6.7.0 - '@prisma/fetch-engine@7.6.0': + '@prisma/fetch-engine@7.4.1': dependencies: - '@prisma/debug': 7.6.0 - '@prisma/engines-version': 7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711 - '@prisma/get-platform': 7.6.0 + '@prisma/debug': 7.4.1 + '@prisma/engines-version': 7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3 + '@prisma/get-platform': 7.4.1 '@prisma/generator-helper@6.19.2': dependencies: @@ -9064,17 +9165,17 @@ snapshots: '@prisma/dmmf': 6.7.0 '@prisma/generator': 6.7.0 - '@prisma/generator-helper@7.6.0': + '@prisma/generator-helper@7.4.1': dependencies: - '@prisma/debug': 7.6.0 - '@prisma/dmmf': 7.6.0 - '@prisma/generator': 7.6.0 + '@prisma/debug': 7.4.1 + '@prisma/dmmf': 7.4.1 + '@prisma/generator': 7.4.1 '@prisma/generator@6.19.2': {} '@prisma/generator@6.7.0': {} - '@prisma/generator@7.6.0': {} + '@prisma/generator@7.4.1': {} '@prisma/get-platform@6.19.2': dependencies: @@ -9084,9 +9185,9 @@ snapshots: dependencies: '@prisma/debug': 6.7.0 - '@prisma/get-platform@7.6.0': + '@prisma/get-platform@7.4.1': dependencies: - '@prisma/debug': 7.6.0 + '@prisma/debug': 7.4.1 '@prisma/internals@6.19.2(typescript@5.9.3)': dependencies: @@ -9130,21 +9231,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@prisma/internals@7.6.0(typescript@5.9.3)': + '@prisma/internals@7.4.1(typescript@5.9.3)': dependencies: - '@prisma/config': 7.6.0 - '@prisma/debug': 7.6.0 - '@prisma/dmmf': 7.6.0 - '@prisma/driver-adapter-utils': 7.6.0 - '@prisma/engines': 7.6.0 - '@prisma/fetch-engine': 7.6.0 - '@prisma/generator': 7.6.0 - '@prisma/generator-helper': 7.6.0 - '@prisma/get-platform': 7.6.0 - '@prisma/prisma-schema-wasm': 7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711 - '@prisma/schema-engine-wasm': 7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711 - '@prisma/schema-files-loader': 7.6.0 - '@streamparser/json': 0.0.22 + '@prisma/config': 7.4.1 + '@prisma/debug': 7.4.1 + '@prisma/dmmf': 7.4.1 + '@prisma/driver-adapter-utils': 7.4.1 + '@prisma/engines': 7.4.1 + '@prisma/fetch-engine': 7.4.1 + '@prisma/generator': 7.4.1 + '@prisma/generator-helper': 7.4.1 + '@prisma/get-platform': 7.4.1 + '@prisma/prisma-schema-wasm': 7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3 + '@prisma/schema-engine-wasm': 7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3 + '@prisma/schema-files-loader': 7.4.1 arg: 5.0.2 prompts: 2.4.2 optionalDependencies: @@ -9156,13 +9256,13 @@ snapshots: '@prisma/prisma-schema-wasm@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': {} - '@prisma/prisma-schema-wasm@7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711': {} + '@prisma/prisma-schema-wasm@7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3': {} '@prisma/schema-engine-wasm@6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed': {} '@prisma/schema-engine-wasm@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': {} - '@prisma/schema-engine-wasm@7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711': {} + '@prisma/schema-engine-wasm@7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3': {} '@prisma/schema-files-loader@6.19.2': dependencies: @@ -9174,9 +9274,9 @@ snapshots: '@prisma/prisma-schema-wasm': 6.7.0-36.3cff47a7f5d65c3ea74883f1d736e41d68ce91ed fs-extra: 11.3.0 - '@prisma/schema-files-loader@7.6.0': + '@prisma/schema-files-loader@7.4.1': dependencies: - '@prisma/prisma-schema-wasm': 7.6.0-1.75cbdc1eb7150937890ad5465d861175c6624711 + '@prisma/prisma-schema-wasm': 7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3 fs-extra: 11.3.0 '@protobufjs/aspromise@1.1.2': {} @@ -9703,7 +9803,7 @@ snapshots: '@radix-ui/react-popper@1.2.8(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': dependencies: - '@floating-ui/react-dom': 2.1.8(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@floating-ui/react-dom': 2.1.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.10)(react@19.0.0) '@radix-ui/react-context': 1.1.2(@types/react@19.0.10)(react@19.0.0) @@ -9721,7 +9821,7 @@ snapshots: '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@floating-ui/react-dom': 2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@floating-ui/react-dom': 2.1.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.4) @@ -10333,7 +10433,7 @@ snapshots: md-to-react-email: 5.0.5(react@19.2.4) react: 19.2.4 - '@react-email/preview-server@4.3.2(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(postcss@8.5.8)': + '@react-email/preview-server@4.3.2(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(postcss@8.5.6)': dependencies: '@babel/core': 7.26.10 '@babel/parser': 7.27.0 @@ -10352,7 +10452,7 @@ snapshots: '@types/react': 19.0.10 '@types/react-dom': 19.0.4(@types/react@19.0.10) '@types/webpack': 5.28.5(esbuild@0.25.10) - autoprefixer: 10.4.21(postcss@8.5.8) + autoprefixer: 10.4.21(postcss@8.5.6) clsx: 2.1.1 esbuild: 0.25.10 framer-motion: 12.23.22(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -10444,8 +10544,8 @@ snapshots: '@conventional-changelog/git-client': 2.6.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.3.0) concat-stream: 2.0.0 conventional-changelog: 7.2.0(conventional-commits-filter@5.0.0) - conventional-changelog-angular: 8.3.0 - conventional-changelog-conventionalcommits: 9.3.0 + conventional-changelog-angular: 8.3.1 + conventional-changelog-conventionalcommits: 9.3.1 conventional-recommended-bump: 11.2.0 release-it: 19.2.4(@types/node@22.19.15) semver: 7.7.4 @@ -10468,9 +10568,9 @@ snapshots: '@simple-libs/stream-utils@1.2.0': {} - '@simplewebauthn/browser@13.3.0': {} + '@simplewebauthn/browser@13.2.2': {} - '@simplewebauthn/server@13.3.0': + '@simplewebauthn/server@13.2.3': dependencies: '@hexagon/base64': 1.1.28 '@levischuck/tiny-cbor': 0.2.11 @@ -10487,8 +10587,6 @@ snapshots: '@standard-schema/utils@0.3.0': {} - '@streamparser/json@0.0.22': {} - '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -10508,7 +10606,7 @@ snapshots: '@tailwindcss/node@4.2.2': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.20.1 + enhanced-resolve: 5.19.0 jiti: 2.6.1 lightningcss: 1.32.0 magic-string: 0.30.21 @@ -10571,14 +10669,14 @@ snapshots: '@alloc/quick-lru': 5.2.0 '@tailwindcss/node': 4.2.2 '@tailwindcss/oxide': 4.2.2 - postcss: 8.5.8 + postcss: 8.5.6 tailwindcss: 4.2.2 - '@tanstack/query-core@5.95.2': {} + '@tanstack/query-core@5.96.0': {} - '@tanstack/react-query@5.95.2(react@19.2.4)': + '@tanstack/react-query@5.96.0(react@19.2.4)': dependencies: - '@tanstack/query-core': 5.95.2 + '@tanstack/query-core': 5.96.0 react: 19.2.4 '@tanstack/react-table@8.21.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': @@ -10594,14 +10692,14 @@ snapshots: '@ts-morph/common@0.17.0': dependencies: fast-glob: 3.3.3 - minimatch: 5.1.9 + minimatch: 5.1.8 mkdirp: 1.0.4 path-browserify: 1.0.1 '@ts-morph/common@0.27.0': dependencies: fast-glob: 3.3.3 - minimatch: 10.2.4 + minimatch: 10.2.3 path-browserify: 1.0.1 '@tybys/wasm-util@0.10.1': @@ -10661,7 +10759,7 @@ snapshots: dependencies: '@types/node': 22.19.15 - '@types/node@20.19.37': + '@types/node@20.19.33': dependencies: undici-types: 6.21.0 @@ -10688,7 +10786,7 @@ snapshots: '@types/pg@8.20.0': dependencies: '@types/node': 22.19.15 - pg-protocol: 1.13.0 + pg-protocol: 1.11.0 pg-types: 2.2.0 '@types/prismjs@1.26.6': {} @@ -10712,8 +10810,8 @@ snapshots: '@types/webpack@5.28.5(esbuild@0.25.10)': dependencies: '@types/node': 22.19.15 - tapable: 2.3.2 - webpack: 5.105.4(esbuild@0.25.10) + tapable: 2.3.0 + webpack: 5.105.2(esbuild@0.25.10) transitivePeerDependencies: - '@swc/core' - esbuild @@ -10724,95 +10822,95 @@ snapshots: dependencies: '@types/node': 22.19.15 - '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.2 - '@typescript-eslint/type-utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.2 + '@typescript-eslint/parser': 8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.56.1 + '@typescript-eslint/type-utils': 8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.56.1 eslint: 9.39.4(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.5.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.57.2 - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.2 + '@typescript-eslint/scope-manager': 8.56.1 + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.56.1 debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.57.2(typescript@5.9.3)': + '@typescript-eslint/project-service@8.56.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.9.3) - '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) + '@typescript-eslint/types': 8.56.1 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.57.2': + '@typescript-eslint/scope-manager@8.56.1': dependencies: - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/visitor-keys': 8.57.2 + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/visitor-keys': 8.56.1 - '@typescript-eslint/tsconfig-utils@8.57.2(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.56.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) - ts-api-utils: 2.5.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.57.2': {} + '@typescript-eslint/types@8.56.1': {} - '@typescript-eslint/typescript-estree@8.57.2(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.56.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.57.2(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.9.3) - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/visitor-keys': 8.57.2 + '@typescript-eslint/project-service': 8.56.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.56.1(typescript@5.9.3) + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/visitor-keys': 8.56.1 debug: 4.4.3 - minimatch: 10.2.4 + minimatch: 10.2.3 semver: 7.7.4 tinyglobby: 0.2.15 - ts-api-utils: 2.5.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.57.2 - '@typescript-eslint/types': 8.57.2 - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.56.1 + '@typescript-eslint/types': 8.56.1 + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.57.2': + '@typescript-eslint/visitor-keys@8.56.1': dependencies: - '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/types': 8.56.1 eslint-visitor-keys: 5.0.1 '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -10977,7 +11075,7 @@ snapshots: openapi-types: 12.1.3 semver: 7.7.4 ts-pattern: 4.3.0 - yaml: 2.8.3 + yaml: 2.8.2 zod: 3.25.76 zod-validation-error: 4.0.2(zod@3.25.76) transitivePeerDependencies: @@ -11082,7 +11180,7 @@ snapshots: dependencies: '@prisma/generator-helper': 6.19.2 '@prisma/internals': 6.19.2(typescript@5.9.3) - '@prisma/internals-v7': '@prisma/internals@7.6.0(typescript@5.9.3)' + '@prisma/internals-v7': '@prisma/internals@7.4.1(typescript@5.9.3)' '@zenstackhq/language': 2.22.2 '@zenstackhq/runtime': 2.22.2(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(zod@3.25.76) langium: 1.3.1 @@ -11168,19 +11266,21 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@6.2.3: {} + any-promise@1.3.0: {} anymatch@3.1.3: dependencies: normalize-path: 3.0.0 - picomatch: 2.3.2 + picomatch: 2.3.1 arg@5.0.2: {} argon2@0.43.1: dependencies: '@phc/format': 1.0.0 - node-addon-api: 8.7.0 + node-addon-api: 8.5.0 node-gyp-build: 4.8.4 argparse@2.0.1: {} @@ -11290,14 +11390,14 @@ snapshots: attr-accept@2.2.5: {} - autoprefixer@10.4.21(postcss@8.5.8): + autoprefixer@10.4.21(postcss@8.5.6): dependencies: browserslist: 4.28.1 - caniuse-lite: 1.0.30001781 + caniuse-lite: 1.0.30001774 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 - postcss: 8.5.8 + postcss: 8.5.6 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: @@ -11316,7 +11416,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.10.12: {} + baseline-browser-mapping@2.10.13: {} basic-ftp@5.2.0: {} @@ -11326,36 +11426,36 @@ snapshots: bcrypt@6.0.0: dependencies: - node-addon-api: 8.7.0 + node-addon-api: 8.5.0 node-gyp-build: 4.8.4 bcryptjs@2.4.3: {} before-after-hook@4.0.0: {} - better-auth@1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + better-auth@1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(drizzle-kit@0.31.10)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0) - '@better-auth/drizzle-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))) - '@better-auth/kysely-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.14) - '@better-auth/memory-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/mongo-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1) - '@better-auth/prisma-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(prisma@6.7.0(typescript@5.9.3)) - '@better-auth/telemetry': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0)) + '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0) + '@better-auth/drizzle-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3))) + '@better-auth/kysely-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.15) + '@better-auth/memory-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/mongo-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1) + '@better-auth/prisma-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(prisma@6.7.0(typescript@5.9.3)) + '@better-auth/telemetry': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.1)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0)) '@better-auth/utils': 0.3.1 '@better-fetch/fetch': 1.1.21 '@noble/ciphers': 2.1.1 '@noble/hashes': 2.0.1 better-call: 1.3.2(zod@4.3.6) defu: 6.1.4 - jose: 6.2.2 - kysely: 0.28.14 + jose: 6.1.3 + kysely: 0.28.15 nanostores: 1.2.0 zod: 4.3.6 optionalDependencies: '@prisma/client': 6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3) drizzle-kit: 0.31.10 - drizzle-orm: 0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)) + drizzle-orm: 0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)) next: 16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.1)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) pg: 8.20.0 prisma: 6.7.0(typescript@5.9.3) @@ -11399,16 +11499,16 @@ snapshots: boolbase@1.0.0: {} - brace-expansion@1.1.13: + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.3: + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.5: + brace-expansion@5.0.3: dependencies: balanced-match: 4.0.4 @@ -11420,10 +11520,10 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.10.12 - caniuse-lite: 1.0.30001781 - electron-to-chromium: 1.5.328 - node-releases: 2.0.36 + baseline-browser-mapping: 2.10.13 + caniuse-lite: 1.0.30001774 + electron-to-chromium: 1.5.302 + node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) buffer-crc32@1.0.0: {} @@ -11505,9 +11605,9 @@ snapshots: camelcase-css@2.0.1: {} - camelcase@9.0.0: {} + camelcase@6.3.0: {} - caniuse-lite@1.0.30001781: {} + caniuse-lite@1.0.30001774: {} capital-case@1.0.4: dependencies: @@ -11559,7 +11659,7 @@ snapshots: parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 - undici: 7.24.6 + undici: 7.22.0 whatwg-mimetype: 4.0.0 chevrotain-allstar@0.1.7(chevrotain@10.4.2): @@ -11696,21 +11796,21 @@ snapshots: tslib: 2.8.1 upper-case: 2.0.2 - conventional-changelog-angular@8.3.0: + conventional-changelog-angular@8.3.1: dependencies: compare-func: 2.0.0 - conventional-changelog-conventionalcommits@9.3.0: + conventional-changelog-conventionalcommits@9.3.1: dependencies: compare-func: 2.0.0 conventional-changelog-preset-loader@5.0.0: {} - conventional-changelog-writer@8.4.0: + conventional-changelog-writer@8.3.0: dependencies: '@simple-libs/stream-utils': 1.2.0 conventional-commits-filter: 5.0.0 - handlebars: 4.7.9 + handlebars: 4.7.8 meow: 13.2.0 semver: 7.7.4 @@ -11720,7 +11820,7 @@ snapshots: '@simple-libs/hosted-git-info': 1.0.2 '@types/normalize-package-data': 2.4.4 conventional-changelog-preset-loader: 5.0.0 - conventional-changelog-writer: 8.4.0 + conventional-changelog-writer: 8.3.0 conventional-commits-parser: 6.3.0 fd-package-json: 2.0.0 meow: 13.2.0 @@ -11759,7 +11859,7 @@ snapshots: cpu-features@0.0.10: dependencies: buildcheck: 0.0.7 - nan: 2.26.2 + nan: 2.25.0 optional: true cross-fetch@4.1.0: @@ -11952,7 +12052,7 @@ snapshots: dom-helpers@5.2.1: dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.28.6 csstype: 3.2.3 dom-serializer@2.0.0: @@ -11993,18 +12093,18 @@ snapshots: esbuild: 0.25.12 tsx: 4.21.0 - drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)): + drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)): optionalDependencies: '@opentelemetry/api': 1.9.1 '@prisma/client': 6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3) '@types/pg': 8.20.0 - kysely: 0.28.14 + kysely: 0.28.15 pg: 8.20.0 prisma: 6.7.0(typescript@5.9.3) - drizzle-zod@0.7.1(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(zod@3.25.76): + drizzle-zod@0.7.1(drizzle-orm@0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)))(zod@3.25.76): dependencies: - drizzle-orm: 0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.14)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)) + drizzle-orm: 0.43.1(@opentelemetry/api@1.9.1)(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(@types/pg@8.20.0)(kysely@0.28.15)(pg@8.20.0)(prisma@6.7.0(typescript@5.9.3)) zod: 3.25.76 dunder-proto@1.0.1: @@ -12013,6 +12113,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + eastasianwidth@0.2.0: {} + ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer: 5.2.1 @@ -12022,12 +12124,7 @@ snapshots: '@standard-schema/spec': 1.1.0 fast-check: 3.23.2 - effect@3.20.0: - dependencies: - '@standard-schema/spec': 1.1.0 - fast-check: 3.23.2 - - electron-to-chromium@1.5.328: {} + electron-to-chromium@1.5.302: {} embla-carousel-react@8.6.0(react@19.2.4): dependencies: @@ -12078,11 +12175,10 @@ snapshots: engine.io-parser@5.2.3: {} - engine.io@6.6.6: + engine.io@6.6.5: dependencies: '@types/cors': 2.8.19 '@types/node': 22.19.15 - '@types/ws': 8.18.1 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -12095,10 +12191,10 @@ snapshots: - supports-color - utf-8-validate - enhanced-resolve@5.20.1: + enhanced-resolve@5.19.0: dependencies: graceful-fs: 4.2.11 - tapable: 2.3.2 + tapable: 2.3.0 entities@4.5.0: {} @@ -12167,7 +12263,7 @@ snapshots: es-errors@1.3.0: {} - es-iterator-helpers@1.3.1: + es-iterator-helpers@1.2.2: dependencies: call-bind: 1.0.8 call-bound: 1.0.4 @@ -12184,7 +12280,6 @@ snapshots: has-symbols: 1.1.0 internal-slot: 1.1.0 iterator.prototype: 1.1.5 - math-intrinsics: 1.1.0 safe-array-concat: 1.1.3 es-module-lexer@2.0.0: {} @@ -12343,18 +12438,18 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-next@16.2.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): + eslint-config-next@16.2.1(@typescript-eslint/parser@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: '@next/eslint-plugin-next': 16.2.1 eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.39.4(jiti@2.6.1)) eslint-plugin-react-hooks: 7.0.1(eslint@9.39.4(jiti@2.6.1)) globals: 16.4.0 - typescript-eslint: 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + typescript-eslint: 8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -12376,28 +12471,28 @@ snapshots: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 eslint: 9.39.4(jiti@2.6.1) - get-tsconfig: 4.13.7 + get-tsconfig: 4.13.6 is-bun-module: 2.0.0 stable-hash: 0.0.5 tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -12408,11 +12503,11 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.4(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 - minimatch: 3.1.5 + minimatch: 3.1.4 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 @@ -12420,7 +12515,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -12440,7 +12535,7 @@ snapshots: hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 - minimatch: 3.1.5 + minimatch: 3.1.4 object.fromentries: 2.0.8 safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 @@ -12448,7 +12543,7 @@ snapshots: eslint-plugin-react-hooks@7.0.1(eslint@9.39.4(jiti@2.6.1)): dependencies: '@babel/core': 7.29.0 - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.0 eslint: 9.39.4(jiti@2.6.1) hermes-parser: 0.25.1 zod: 3.25.76 @@ -12463,12 +12558,12 @@ snapshots: array.prototype.flatmap: 1.3.3 array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 - es-iterator-helpers: 1.3.1 + es-iterator-helpers: 1.2.2 eslint: 9.39.4(jiti@2.6.1) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 - minimatch: 3.1.5 + minimatch: 3.1.4 object.entries: 1.1.9 object.fromentries: 2.0.8 object.values: 1.2.1 @@ -12481,7 +12576,7 @@ snapshots: eslint-plugin-tailwindcss@3.18.2(tailwindcss@4.2.2): dependencies: fast-glob: 3.3.3 - postcss: 8.5.8 + postcss: 8.5.6 tailwindcss: 4.2.2 eslint-scope@5.1.1: @@ -12629,6 +12724,10 @@ snapshots: dependencies: path-expression-matcher: 1.2.0 + fast-xml-parser@5.3.9: + dependencies: + strnum: 2.1.2 + fast-xml-parser@5.5.9: dependencies: fast-xml-builder: 1.1.4 @@ -12647,9 +12746,9 @@ snapshots: dependencies: walk-up-path: 4.0.0 - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.3 fetch-blob@3.2.0: dependencies: @@ -12677,10 +12776,10 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.4.2 + flatted: 3.3.3 keyv: 4.5.4 - flatted@3.4.2: {} + flatted@3.3.3: {} for-each@0.3.5: dependencies: @@ -12701,13 +12800,22 @@ snapshots: framer-motion@12.23.22(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: - motion-dom: 12.38.0 - motion-utils: 12.36.0 + motion-dom: 12.34.3 + motion-utils: 12.29.2 tslib: 2.8.1 optionalDependencies: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) + framer-motion@12.34.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + motion-dom: 12.34.3 + motion-utils: 12.29.2 + tslib: 2.8.1 + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + framer-motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: motion-dom: 12.38.0 @@ -12744,17 +12852,18 @@ snapshots: functions-have-names@1.2.3: {} - gaxios@7.1.4: + gaxios@7.1.3: dependencies: extend: 3.0.2 https-proxy-agent: 7.0.6 node-fetch: 3.3.2 + rimraf: 5.0.10 transitivePeerDependencies: - supports-color gcp-metadata@8.1.2: dependencies: - gaxios: 7.1.4 + gaxios: 7.1.3 google-logging-utils: 1.1.3 json-bigint: 1.0.0 transitivePeerDependencies: @@ -12796,7 +12905,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@4.13.7: + get-tsconfig@4.13.6: dependencies: resolve-pkg-maps: 1.0.0 @@ -12836,11 +12945,20 @@ snapshots: glob-to-regexp@0.4.1: {} + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.7 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + glob@11.1.0: dependencies: foreground-child: 3.3.1 jackspeak: 4.2.3 - minimatch: 10.2.4 + minimatch: 10.2.3 minipass: 7.1.3 package-json-from-dist: 1.0.1 path-scurry: 2.0.2 @@ -12856,11 +12974,11 @@ snapshots: define-properties: 1.2.1 gopd: 1.2.0 - google-auth-library@10.6.2: + google-auth-library@10.6.1: dependencies: base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 - gaxios: 7.1.4 + gaxios: 7.1.3 gcp-metadata: 8.1.2 google-logging-utils: 1.1.3 jws: 4.0.1 @@ -12872,8 +12990,8 @@ snapshots: googleapis-common@8.0.1: dependencies: extend: 3.0.2 - gaxios: 7.1.4 - google-auth-library: 10.6.2 + gaxios: 7.1.3 + google-auth-library: 10.6.1 qs: 6.15.0 url-template: 2.0.8 transitivePeerDependencies: @@ -12881,7 +12999,7 @@ snapshots: googleapis@170.1.0: dependencies: - google-auth-library: 10.6.2 + google-auth-library: 10.6.1 googleapis-common: 8.0.1 transitivePeerDependencies: - supports-color @@ -12890,7 +13008,7 @@ snapshots: graceful-fs@4.2.11: {} - handlebars@4.7.9: + handlebars@4.7.8: dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -13212,6 +13330,12 @@ snapshots: has-symbols: 1.1.0 set-function-name: 2.0.2 + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jackspeak@4.2.3: dependencies: '@isaacs/cliui': 9.0.0 @@ -13228,7 +13352,7 @@ snapshots: jiti@2.6.1: {} - jose@6.2.2: {} + jose@6.1.3: {} joycon@3.1.1: {} @@ -13254,7 +13378,7 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} - json-with-bigint@3.5.8: {} + json-with-bigint@3.5.7: {} json5@1.0.2: dependencies: @@ -13292,7 +13416,7 @@ snapshots: kleur@3.0.3: {} - kysely@0.28.14: {} + kysely@0.28.15: {} langium@1.3.1: dependencies: @@ -13436,7 +13560,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.2.7: {} + lru-cache@11.2.6: {} lru-cache@5.1.1: dependencies: @@ -13472,7 +13596,7 @@ snapshots: micromatch@4.0.8: dependencies: braces: 3.0.3 - picomatch: 2.3.2 + picomatch: 2.3.1 mime-db@1.52.0: {} @@ -13492,17 +13616,25 @@ snapshots: mimic-function@5.0.1: {} - minimatch@10.2.4: + minimatch@10.2.3: dependencies: - brace-expansion: 5.0.5 + brace-expansion: 5.0.3 + + minimatch@3.1.4: + dependencies: + brace-expansion: 1.1.12 minimatch@3.1.5: dependencies: - brace-expansion: 1.1.13 + brace-expansion: 1.1.12 - minimatch@5.1.9: + minimatch@5.1.8: dependencies: - brace-expansion: 2.0.3 + brace-expansion: 2.0.2 + + minimatch@9.0.7: + dependencies: + brace-expansion: 5.0.3 minimist@1.2.8: {} @@ -13513,7 +13645,7 @@ snapshots: browser-or-node: 2.1.1 buffer-crc32: 1.0.0 eventemitter3: 5.0.4 - fast-xml-parser: 5.5.9 + fast-xml-parser: 5.3.9 ipaddr.js: 2.3.0 lodash: 4.17.23 mime-types: 2.1.35 @@ -13534,10 +13666,16 @@ snapshots: mkdirp@1.0.4: {} + motion-dom@12.34.3: + dependencies: + motion-utils: 12.29.2 + motion-dom@12.38.0: dependencies: motion-utils: 12.36.0 + motion-utils@12.29.2: {} + motion-utils@12.36.0: {} motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): @@ -13558,7 +13696,7 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nan@2.26.2: + nan@2.25.0: optional: true nanoid@3.3.11: {} @@ -13596,7 +13734,7 @@ snapshots: dependencies: '@next/env': 15.5.2 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001781 + caniuse-lite: 1.0.30001774 postcss: 8.4.31 react: 19.0.0 react-dom: 19.0.0(react@19.0.0) @@ -13621,8 +13759,8 @@ snapshots: dependencies: '@next/env': 16.2.1 '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.10.12 - caniuse-lite: 1.0.30001781 + baseline-browser-mapping: 2.10.13 + caniuse-lite: 1.0.30001774 postcss: 8.4.31 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -13648,7 +13786,9 @@ snapshots: lower-case: 2.0.2 tslib: 2.8.1 - node-addon-api@8.7.0: {} + node-addon-api@7.1.1: {} + + node-addon-api@8.5.0: {} node-cron@4.2.1: {} @@ -13682,7 +13822,11 @@ snapshots: css-select: 5.2.2 he: 1.2.0 - node-releases@2.0.36: {} + node-pty@1.1.0: + dependencies: + node-addon-api: 7.1.1 + + node-releases@2.0.27: {} node-rsa@1.1.1: dependencies: @@ -13722,7 +13866,7 @@ snapshots: dependencies: citty: 0.2.1 pathe: 2.0.3 - tinyexec: 1.0.4 + tinyexec: 1.0.2 object-assign@4.1.1: {} @@ -13828,7 +13972,7 @@ snapshots: log-symbols: 6.0.0 stdin-discarder: 0.2.2 string-width: 7.2.0 - strip-ansi: 7.2.0 + strip-ansi: 7.1.2 ora@9.0.0: dependencies: @@ -13840,7 +13984,7 @@ snapshots: log-symbols: 7.0.1 stdin-discarder: 0.2.2 string-width: 8.2.0 - strip-ansi: 7.2.0 + strip-ansi: 7.1.2 os-name@6.1.0: dependencies: @@ -13881,6 +14025,8 @@ snapshots: package-json-from-dist@1.0.1: {} + pako@1.0.11: {} + param-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -13939,9 +14085,14 @@ snapshots: path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + path-scurry@2.0.2: dependencies: - lru-cache: 11.2.7 + lru-cache: 11.2.6 minipass: 7.1.3 pathe@2.0.3: {} @@ -13963,6 +14114,8 @@ snapshots: dependencies: pg: 8.20.0 + pg-protocol@1.11.0: {} + pg-protocol@1.13.0: {} pg-types@2.2.0: @@ -13989,9 +14142,9 @@ snapshots: picocolors@1.1.1: {} - picomatch@2.3.2: {} + picomatch@2.3.1: {} - picomatch@4.0.4: {} + picomatch@4.0.3: {} pify@2.3.0: {} @@ -14010,7 +14163,7 @@ snapshots: minimist: 1.2.8 on-exit-leak-free: 2.1.2 pino-abstract-transport: 3.0.0 - pump: 3.0.4 + pump: 3.0.3 secure-json-parse: 4.1.0 sonic-boom: 4.2.1 strip-json-comments: 5.0.3 @@ -14051,28 +14204,28 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-import@15.1.0(postcss@8.5.8): + postcss-import@15.1.0(postcss@8.5.6): dependencies: - postcss: 8.5.8 + postcss: 8.5.6 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.11 - postcss-js@4.1.0(postcss@8.5.8): + postcss-js@4.1.0(postcss@8.5.6): dependencies: camelcase-css: 2.0.1 - postcss: 8.5.8 + postcss: 8.5.6 - postcss-load-config@4.0.2(postcss@8.5.8): + postcss-load-config@4.0.2(postcss@8.5.6): dependencies: lilconfig: 3.1.3 - yaml: 2.8.3 + yaml: 2.8.2 optionalDependencies: - postcss: 8.5.8 + postcss: 8.5.6 - postcss-nested@6.2.0(postcss@8.5.8): + postcss-nested@6.2.0(postcss@8.5.6): dependencies: - postcss: 8.5.8 + postcss: 8.5.6 postcss-selector-parser: 6.1.2 postcss-selector-parser@6.1.2: @@ -14088,7 +14241,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.5.8: + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -14180,7 +14333,7 @@ snapshots: proxy-from-env@1.1.0: {} - pump@3.0.4: + pump@3.0.3: dependencies: end-of-stream: 1.4.5 once: 1.4.0 @@ -14212,6 +14365,10 @@ snapshots: quick-format-unescaped@4.0.4: {} + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + rc9@2.1.2: dependencies: defu: 6.1.4 @@ -14243,7 +14400,7 @@ snapshots: react-email@4.3.2: dependencies: - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.0 '@babel/traverse': 7.29.0 chokidar: 4.0.3 commander: 13.1.0 @@ -14351,7 +14508,7 @@ snapshots: react-transition-group@4.4.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.28.6 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 @@ -14388,7 +14545,7 @@ snapshots: readdirp@3.6.0: dependencies: - picomatch: 2.3.2 + picomatch: 2.3.1 readdirp@4.1.2: {} @@ -14504,6 +14661,10 @@ snapshots: reusify@1.1.0: {} + rimraf@5.0.10: + dependencies: + glob: 10.5.0 + rou3@0.7.12: {} run-applescript@7.1.0: {} @@ -14545,18 +14706,21 @@ snapshots: safer-buffer@2.1.2: {} - samlify@2.11.0: + samlify@2.10.2: dependencies: '@authenio/xml-encryption': 2.0.2 '@xmldom/xmldom': 0.8.11 - camelcase: 9.0.0 + camelcase: 6.3.0 + node-forge: 1.4.0 node-rsa: 1.1.1 + pako: 1.0.11 + uuid: 8.3.2 xml: 1.0.1 xml-crypto: 6.1.2 xml-escape: 1.1.0 - xpath: 0.0.34 + xpath: 0.0.32 - sax@1.6.0: {} + sax@1.4.4: {} scheduler@0.25.0: {} @@ -14587,6 +14751,10 @@ snapshots: tslib: 2.8.1 upper-case-first: 2.0.2 + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + set-cookie-parser@3.1.0: {} set-function-length@1.2.2: @@ -14613,7 +14781,7 @@ snapshots: sharp@0.34.4: dependencies: - '@img/colour': 1.1.0 + '@img/colour': 1.0.0 detect-libc: 2.1.2 semver: 7.7.4 optionalDependencies: @@ -14642,7 +14810,7 @@ snapshots: sharp@0.34.5: dependencies: - '@img/colour': 1.1.0 + '@img/colour': 1.0.0 detect-libc: 2.1.2 semver: 7.7.4 optionalDependencies: @@ -14734,7 +14902,7 @@ snapshots: '@socket.io/component-emitter': 3.1.2 debug: 4.3.7 engine.io-client: 6.6.4 - socket.io-parser: 4.2.6 + socket.io-parser: 4.2.5 transitivePeerDependencies: - bufferutil - supports-color @@ -14745,13 +14913,13 @@ snapshots: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3 engine.io-client: 6.6.4 - socket.io-parser: 4.2.6 + socket.io-parser: 4.2.5 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - socket.io-parser@4.2.6: + socket.io-parser@4.2.5: dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3 @@ -14764,9 +14932,9 @@ snapshots: base64id: 2.0.0 cors: 2.8.6 debug: 4.4.3 - engine.io: 6.6.6 + engine.io: 6.6.5 socket.io-adapter: 2.5.6 - socket.io-parser: 4.2.6 + socket.io-parser: 4.2.5 transitivePeerDependencies: - bufferutil - supports-color @@ -14836,7 +15004,7 @@ snapshots: bcrypt-pbkdf: 1.0.2 optionalDependencies: cpu-features: 0.0.10 - nan: 2.26.2 + nan: 2.25.0 stable-hash@0.0.5: {} @@ -14865,16 +15033,22 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + string-width@7.2.0: dependencies: emoji-regex: 10.6.0 get-east-asian-width: 1.5.0 - strip-ansi: 7.2.0 + strip-ansi: 7.1.2 string-width@8.2.0: dependencies: get-east-asian-width: 1.5.0 - strip-ansi: 7.2.0 + strip-ansi: 7.1.2 string.prototype.includes@2.0.1: dependencies: @@ -14934,7 +15108,7 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.2.0: + strip-ansi@7.1.2: dependencies: ansi-regex: 6.2.2 @@ -14948,6 +15122,8 @@ snapshots: strip-json-comments@5.0.3: {} + strnum@2.1.2: {} + strnum@2.2.2: {} styled-jsx@5.1.6(@babel/core@7.26.10)(react@19.0.0): @@ -15015,11 +15191,11 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.8 - postcss-import: 15.1.0(postcss@8.5.8) - postcss-js: 4.1.0(postcss@8.5.8) - postcss-load-config: 4.0.2(postcss@8.5.8) - postcss-nested: 6.2.0(postcss@8.5.8) + postcss: 8.5.6 + postcss-import: 15.1.0(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) + postcss-load-config: 4.0.2(postcss@8.5.6) + postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 resolve: 1.22.11 sucrase: 3.35.1 @@ -15028,13 +15204,13 @@ snapshots: tailwindcss@4.2.2: {} - tapable@2.3.2: {} + tapable@2.3.0: {} tar-fs@2.1.4: dependencies: chownr: 1.1.4 mkdirp-classic: 0.5.3 - pump: 3.0.4 + pump: 3.0.3 tar-stream: 2.2.0 tar-stream@2.2.0: @@ -15050,17 +15226,18 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 - terser-webpack-plugin@5.4.0(esbuild@0.25.10)(webpack@5.105.4(esbuild@0.27.4)): + terser-webpack-plugin@5.3.16(esbuild@0.25.10)(webpack@5.105.2(esbuild@0.27.4)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.46.1 - webpack: 5.105.4(esbuild@0.25.10) + serialize-javascript: 6.0.2 + terser: 5.46.0 + webpack: 5.105.2(esbuild@0.25.10) optionalDependencies: esbuild: 0.25.10 - terser@5.46.1: + terser@5.46.0: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.16.0 @@ -15087,12 +15264,12 @@ snapshots: tinyexec@0.3.2: {} - tinyexec@1.0.4: {} + tinyexec@1.0.2: {} tinyglobby@0.2.15: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 tldts-core@6.1.86: {} @@ -15112,7 +15289,7 @@ snapshots: typedarray.prototype.slice: 1.0.5 which-typed-array: 1.1.20 - ts-api-utils@2.5.0(typescript@5.9.3): + ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -15150,7 +15327,7 @@ snapshots: tsx@4.21.0: dependencies: esbuild: 0.27.4 - get-tsconfig: 4.13.7 + get-tsconfig: 4.13.6 optionalDependencies: fsevents: 2.3.3 @@ -15218,12 +15395,12 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.56.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.56.1(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.4(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -15247,7 +15424,7 @@ snapshots: undici@6.23.0: {} - undici@7.24.6: {} + undici@7.22.0: {} universal-user-agent@7.0.3: {} @@ -15343,6 +15520,8 @@ snapshots: uuid@11.1.0: {} + uuid@8.3.2: {} + uuid@9.0.1: {} validate-npm-package-license@3.0.4: @@ -15386,7 +15565,7 @@ snapshots: vscode-languageclient@8.1.0: dependencies: - minimatch: 5.1.9 + minimatch: 5.1.8 semver: 7.7.4 vscode-languageserver-protocol: 3.17.3 @@ -15435,7 +15614,7 @@ snapshots: webpack-sources@3.3.4: {} - webpack@5.105.4(esbuild@0.25.10): + webpack@5.105.2(esbuild@0.25.10): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -15447,7 +15626,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.1 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.20.1 + enhanced-resolve: 5.19.0 es-module-lexer: 2.0.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -15458,8 +15637,8 @@ snapshots: mime-types: 2.1.35 neo-async: 2.6.2 schema-utils: 4.3.3 - tapable: 2.3.2 - terser-webpack-plugin: 5.4.0(esbuild@0.25.10)(webpack@5.105.4(esbuild@0.27.4)) + tapable: 2.3.0 + terser-webpack-plugin: 5.3.16(esbuild@0.25.10)(webpack@5.105.2(esbuild@0.27.4)) watchpack: 2.5.1 webpack-sources: 3.3.4 transitivePeerDependencies: @@ -15545,6 +15724,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + wrappy@1.0.2: {} ws@8.18.3: {} @@ -15565,7 +15750,7 @@ snapshots: xml2js@0.6.2: dependencies: - sax: 1.6.0 + sax: 1.4.4 xmlbuilder: 11.0.1 xml@1.0.1: {} @@ -15578,15 +15763,13 @@ snapshots: xpath@0.0.33: {} - xpath@0.0.34: {} - xtend@4.0.2: {} y18n@5.0.8: {} yallist@3.1.1: {} - yaml@2.8.3: {} + yaml@2.8.2: {} yargs-parser@21.1.1: {} @@ -15609,7 +15792,7 @@ snapshots: zenstack@2.14.2(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3): dependencies: '@paralleldrive/cuid2': 2.3.1 - '@types/node': 20.19.37 + '@types/node': 20.19.33 '@zenstackhq/language': 2.14.2 '@zenstackhq/sdk': 2.14.2(@prisma/client@6.7.0(prisma@6.7.0(typescript@5.9.3))(typescript@5.9.3))(typescript@5.9.3) async-exit-hook: 2.0.1 diff --git a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/channel-form.tsx b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/channel-form.tsx index d6d78e73..06b4e1d0 100644 --- a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/channel-form.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/channel-form.tsx @@ -202,9 +202,9 @@ export const ChannelForm = ({onSuccessAction, organization, defaultValues, kind} name="name" render={({field}) => ( - Channel Name + Channel Name * - @@ -252,4 +252,3 @@ export const ChannelForm = ({onSuccessAction, organization, defaultValues, kind} ); }; - diff --git a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/discord.form.tsx b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/discord.form.tsx index 8281a4b9..fcad444e 100644 --- a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/discord.form.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/discord.form.tsx @@ -22,11 +22,11 @@ export const NotifierDiscordForm = ({ form }: NotifierDiscordFormProps) => { name="config.discordWebhook" render={({ field }) => ( - Discord Webhook URL + Discord Webhook URL * diff --git a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/gotify.form.tsx b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/gotify.form.tsx index 81108577..7061595a 100644 --- a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/gotify.form.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/gotify.form.tsx @@ -23,9 +23,9 @@ export const NotifierGotifyForm = ({ form }: NotifierGotifyFormProps) => { name="config.gotifyServerUrl" render={({ field }) => ( - Gotify Server URL + Gotify Server URL * - + @@ -36,9 +36,9 @@ export const NotifierGotifyForm = ({ form }: NotifierGotifyFormProps) => { name="config.gotifyAppToken" render={({ field }) => ( - Application Token + Application Token * - + diff --git a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/ntfy.form.tsx b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/ntfy.form.tsx index 3d588a7f..40f7f959 100644 --- a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/ntfy.form.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/ntfy.form.tsx @@ -18,9 +18,9 @@ export const NotifierNtfyForm = ({form}: NotifierNtfyFormProps) => { name="config.ntfyTopic" render={({field}) => ( - Topic Name + Topic Name * - + @@ -32,9 +32,9 @@ export const NotifierNtfyForm = ({form}: NotifierNtfyFormProps) => { name="config.ntfyServerUrl" render={({field}) => ( - Server URL (Optional) + Server URL - +

Leave empty to use the official ntfy.sh server.

@@ -47,9 +47,9 @@ export const NotifierNtfyForm = ({form}: NotifierNtfyFormProps) => { name="config.ntfyToken" render={({field}) => ( - Access Token (Optional) + Access Token - +

Only required for protected topics or self-hosted instances with auth.

@@ -64,9 +64,9 @@ export const NotifierNtfyForm = ({form}: NotifierNtfyFormProps) => { name="config.ntfyUsername" render={({field}) => ( - Basic Auth Username (Optional) + Basic Auth Username - + @@ -78,9 +78,9 @@ export const NotifierNtfyForm = ({form}: NotifierNtfyFormProps) => { name="config.ntfyPassword" render={({field}) => ( - Basic Auth Password (Optional) + Basic Auth Password - + diff --git a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/slack.form.tsx b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/slack.form.tsx index 5da65e9d..604b0179 100644 --- a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/slack.form.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/slack.form.tsx @@ -22,11 +22,11 @@ export const NotifierSlackForm = ({ form }: NotifierSmtpFormProps) => { name="config.slackWebhook" render={({ field }) => ( - Slack Webhook URL + Slack Webhook URL * diff --git a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/smtp.form.tsx b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/smtp.form.tsx index c1c3483b..4a0fb42e 100644 --- a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/smtp.form.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/smtp.form.tsx @@ -19,9 +19,9 @@ export const NotifierSmtpForm = ({form}: NotifierSmtpFormProps) => { name="config.host" render={({field}) => ( - SMTP Host + SMTP Host * - + @@ -32,9 +32,9 @@ export const NotifierSmtpForm = ({form}: NotifierSmtpFormProps) => { name="config.port" render={({field}) => ( - SMTP Port + SMTP Port * - + @@ -45,9 +45,9 @@ export const NotifierSmtpForm = ({form}: NotifierSmtpFormProps) => { name="config.user" render={({field}) => ( - Username + Username * - + @@ -58,7 +58,7 @@ export const NotifierSmtpForm = ({form}: NotifierSmtpFormProps) => { name="config.password" render={({field}) => ( - Password + Password * { name="config.from" render={({field}) => ( - From Email + From Email * - `} {...field} + `} {...field} value={field.value ?? ""}/> @@ -90,9 +90,9 @@ export const NotifierSmtpForm = ({form}: NotifierSmtpFormProps) => { name="config.to" render={({field}) => ( - To Email + To Email * - @@ -102,4 +102,4 @@ export const NotifierSmtpForm = ({form}: NotifierSmtpFormProps) => { ) -} \ No newline at end of file +} diff --git a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/telegram.form.tsx b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/telegram.form.tsx index 7e9e06f0..c5d42d3d 100644 --- a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/telegram.form.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/telegram.form.tsx @@ -23,11 +23,11 @@ export const NotifierTelegramForm = ({ form }: NotifierTelegramFormProps) => { name="config.telegramBotToken" render={({ field }) => ( - Telegram Bot Token + Telegram Bot Token * @@ -39,9 +39,9 @@ export const NotifierTelegramForm = ({ form }: NotifierTelegramFormProps) => { name="config.telegramChatId" render={({ field }) => ( - Telegram Chat ID + Telegram Chat ID * - +

You must start the conversation with the bot first ( @@ -69,7 +69,7 @@ export const NotifierTelegramForm = ({ form }: NotifierTelegramFormProps) => { Telegram Topic ID - +

Unique identifier for the target message thread (topic) of the diff --git a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/webhook.form.tsx b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/webhook.form.tsx index 5b1239b0..efd7af72 100644 --- a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/webhook.form.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/notifications/forms/webhook.form.tsx @@ -23,9 +23,9 @@ export const NotifierWebhookForm = ({ form }: NotifierWebhookFormProps) => { name="config.webhookUrl" render={({ field }) => ( - Webhook URL + Webhook URL * - + @@ -38,9 +38,9 @@ export const NotifierWebhookForm = ({ form }: NotifierWebhookFormProps) => { name="config.webhookSecretHeader" render={({ field }) => ( - Header Name (Optional) + Header Name - + @@ -53,9 +53,9 @@ export const NotifierWebhookForm = ({ form }: NotifierWebhookFormProps) => { name="config.webhookSecret" render={({ field }) => ( - Secret Value (Optional) + Secret Value - + diff --git a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/storages/forms/google-drive.form.tsx b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/storages/forms/google-drive.form.tsx index 6941cf65..7bd529ea 100644 --- a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/storages/forms/google-drive.form.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/storages/forms/google-drive.form.tsx @@ -96,9 +96,9 @@ export const StorageGoogleDriveForm = ({form}: StorageGoogleDriveFormProps) => { name="config.clientId" render={({field}) => ( - Client ID + Client ID * - + @@ -110,7 +110,7 @@ export const StorageGoogleDriveForm = ({form}: StorageGoogleDriveFormProps) => { name="config.clientSecret" render={({field}) => ( - Client Secret + Client Secret * @@ -124,9 +124,9 @@ export const StorageGoogleDriveForm = ({form}: StorageGoogleDriveFormProps) => { name="config.folderId" render={({field}) => ( - Folder ID + Folder ID * - + diff --git a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/storages/forms/s3.form.tsx b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/storages/forms/s3.form.tsx index b70fc86a..4dd5112a 100644 --- a/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/storages/forms/s3.form.tsx +++ b/src/components/wrappers/dashboard/admin/channels/channel/channel-form/providers/storages/forms/s3.form.tsx @@ -24,9 +24,9 @@ export const StorageS3Form = ({ form }: StorageS3FormProps) => { name="config.endPointUrl" render={({ field }) => ( - Endpoint URL + Endpoint URL * - + @@ -39,7 +39,7 @@ export const StorageS3Form = ({ form }: StorageS3FormProps) => { Region - + @@ -50,9 +50,9 @@ export const StorageS3Form = ({ form }: StorageS3FormProps) => { name="config.accessKey" render={({ field }) => ( - Access Key + Access Key * - + @@ -63,9 +63,9 @@ export const StorageS3Form = ({ form }: StorageS3FormProps) => { name="config.secretKey" render={({ field }) => ( - Secret Key + Secret Key * - + @@ -76,9 +76,9 @@ export const StorageS3Form = ({ form }: StorageS3FormProps) => { name="config.bucketName" render={({ field }) => ( - Bucket name + Bucket name * - + @@ -91,7 +91,7 @@ export const StorageS3Form = ({ form }: StorageS3FormProps) => { Port - + diff --git a/src/components/wrappers/dashboard/common/logged-in/logged-in-button.tsx b/src/components/wrappers/dashboard/common/logged-in/logged-in-button.tsx index a6a648af..836670be 100644 --- a/src/components/wrappers/dashboard/common/logged-in/logged-in-button.tsx +++ b/src/components/wrappers/dashboard/common/logged-in/logged-in-button.tsx @@ -28,7 +28,7 @@ export const LoggedInButtonClient = ({ user, sessions, currentSession, accounts, accounts={accounts} providers={providers} > - +

{user.name[0].toUpperCase()} diff --git a/src/components/wrappers/dashboard/common/sidebar/app-sidebar.tsx b/src/components/wrappers/dashboard/common/sidebar/app-sidebar.tsx index 6c3457b7..fb2d506f 100644 --- a/src/components/wrappers/dashboard/common/sidebar/app-sidebar.tsx +++ b/src/components/wrappers/dashboard/common/sidebar/app-sidebar.tsx @@ -16,7 +16,7 @@ import {UpdateNotification} from "@/features/updates/components/update-notificat export function AppSidebar() { const projectName = env.PROJECT_NAME; return ( - + @@ -32,8 +32,8 @@ export function AppSidebar() { - - + + diff --git a/src/components/wrappers/dashboard/organization/create-organisation-modal.tsx b/src/components/wrappers/dashboard/organization/create-organisation-modal.tsx index 5532a996..0d200a7e 100644 --- a/src/components/wrappers/dashboard/organization/create-organisation-modal.tsx +++ b/src/components/wrappers/dashboard/organization/create-organisation-modal.tsx @@ -45,7 +45,7 @@ export function CreateOrganizationModal({ onOpenChange(false); await authClient.organization.setActive({organizationSlug: result.data.value.slug}); onSuccess?.(); - toast.success(result.data.actionSuccess?.message || "Organization Created."); + toast.success(result.data.actionSuccess?.message); form.reset() router.replace(redirect); } else { diff --git a/src/components/wrappers/dashboard/organization/organization-combobox.tsx b/src/components/wrappers/dashboard/organization/organization-combobox.tsx index 7bd2be3a..28ef6efb 100644 --- a/src/components/wrappers/dashboard/organization/organization-combobox.tsx +++ b/src/components/wrappers/dashboard/organization/organization-combobox.tsx @@ -64,8 +64,8 @@ export function OrganizationCombobox() { onSuccess={handleReload} onOpenChange={setOpenModal} /> - - + +