From 852657c17edcd3e7478e8135c1ee8fa6a31806cb Mon Sep 17 00:00:00 2001 From: shortstacked Date: Tue, 1 Jul 2025 14:15:31 +0100 Subject: [PATCH] feat: Add testcontainers and Playwright (no-changelog) (#16662) Co-authored-by: Tomi Turtiainen <10324676+tomi@users.noreply.github.com> --- .gitignore | 4 + package.json | 5 +- .../cli/src/controllers/e2e.controller.ts | 16 +- packages/testing/containers/README.md | 170 + .../docker-image-not-found-error.ts | 22 + .../testing/containers/n8n-start-stack.ts | 202 ++ .../containers/n8n-test-container-creation.ts | 340 ++ .../n8n-test-container-dependencies.ts | 189 ++ .../containers/n8n-test-container-helpers.ts | 377 +++ packages/testing/containers/package.json | 23 + packages/testing/playwright/.eslintrc.js | 41 + packages/testing/playwright/README.md | 41 + packages/testing/playwright/Types.ts | 6 + .../playwright/composables/CanvasComposer.ts | 15 + .../playwright/composables/ProjectComposer.ts | 56 + .../composables/WorkflowComposer.ts | 25 + .../testing/playwright/config/constants.ts | 43 + .../testing/playwright/config/intercepts.ts | 105 + .../testing/playwright/config/test-users.ts | 77 + .../testing/playwright/currents.config.ts | 6 + packages/testing/playwright/fixtures/base.ts | 149 + packages/testing/playwright/global-setup.ts | 43 + packages/testing/playwright/package.json | 23 + packages/testing/playwright/pages/BasePage.ts | 21 + .../testing/playwright/pages/CanvasPage.ts | 117 + .../playwright/pages/CredentialsPage.ts | 65 + .../playwright/pages/ExecutionsPage.ts | 36 + .../playwright/pages/NodeDisplayViewPage.ts | 38 + .../playwright/pages/NotificationsPage.ts | 234 ++ .../playwright/pages/ProjectSettingsPage.ts | 11 + .../playwright/pages/ProjectWorkflowsPage.ts | 11 + .../testing/playwright/pages/SidebarPage.ts | 42 + .../testing/playwright/pages/WorkflowsPage.ts | 45 + packages/testing/playwright/pages/n8nPage.ts | 68 + .../testing/playwright/playwright.config.ts | 127 + .../testing/playwright/services/api-helper.ts | 238 ++ .../playwright/tests/1-workflows.spec.ts | 11 + .../testing/playwright/tests/28-debug.spec.ts | 113 + .../playwright/tests/39-projects.spec.ts | 107 + .../playwright/tests/authenticated.spec.ts | 26 + .../playwright/tests/multimain.spec.ts | 22 + packages/testing/playwright/tests/pdf.spec.ts | 15 + packages/testing/playwright/tsconfig.json | 12 + .../testing/playwright/utils/path-helper.ts | 32 + .../playwright/workflows/Test_workflow_1.json | 61 + .../workflows/test_pdf_workflow.json | 121 + pnpm-lock.yaml | 2990 +++++++++++------ pnpm-workspace.yaml | 1 + scripts/build-n8n.mjs | 16 +- scripts/dockerize-n8n.mjs | 218 +- scripts/scan-n8n-image.mjs | 12 +- turbo.json | 9 + 52 files changed, 5686 insertions(+), 1111 deletions(-) create mode 100644 packages/testing/containers/README.md create mode 100644 packages/testing/containers/docker-image-not-found-error.ts create mode 100755 packages/testing/containers/n8n-start-stack.ts create mode 100644 packages/testing/containers/n8n-test-container-creation.ts create mode 100644 packages/testing/containers/n8n-test-container-dependencies.ts create mode 100644 packages/testing/containers/n8n-test-container-helpers.ts create mode 100644 packages/testing/containers/package.json create mode 100644 packages/testing/playwright/.eslintrc.js create mode 100644 packages/testing/playwright/README.md create mode 100644 packages/testing/playwright/Types.ts create mode 100644 packages/testing/playwright/composables/CanvasComposer.ts create mode 100644 packages/testing/playwright/composables/ProjectComposer.ts create mode 100644 packages/testing/playwright/composables/WorkflowComposer.ts create mode 100644 packages/testing/playwright/config/constants.ts create mode 100644 packages/testing/playwright/config/intercepts.ts create mode 100644 packages/testing/playwright/config/test-users.ts create mode 100644 packages/testing/playwright/currents.config.ts create mode 100644 packages/testing/playwright/fixtures/base.ts create mode 100644 packages/testing/playwright/global-setup.ts create mode 100644 packages/testing/playwright/package.json create mode 100644 packages/testing/playwright/pages/BasePage.ts create mode 100644 packages/testing/playwright/pages/CanvasPage.ts create mode 100644 packages/testing/playwright/pages/CredentialsPage.ts create mode 100644 packages/testing/playwright/pages/ExecutionsPage.ts create mode 100644 packages/testing/playwright/pages/NodeDisplayViewPage.ts create mode 100644 packages/testing/playwright/pages/NotificationsPage.ts create mode 100644 packages/testing/playwright/pages/ProjectSettingsPage.ts create mode 100644 packages/testing/playwright/pages/ProjectWorkflowsPage.ts create mode 100644 packages/testing/playwright/pages/SidebarPage.ts create mode 100644 packages/testing/playwright/pages/WorkflowsPage.ts create mode 100644 packages/testing/playwright/pages/n8nPage.ts create mode 100644 packages/testing/playwright/playwright.config.ts create mode 100644 packages/testing/playwright/services/api-helper.ts create mode 100644 packages/testing/playwright/tests/1-workflows.spec.ts create mode 100644 packages/testing/playwright/tests/28-debug.spec.ts create mode 100644 packages/testing/playwright/tests/39-projects.spec.ts create mode 100644 packages/testing/playwright/tests/authenticated.spec.ts create mode 100644 packages/testing/playwright/tests/multimain.spec.ts create mode 100644 packages/testing/playwright/tests/pdf.spec.ts create mode 100644 packages/testing/playwright/tsconfig.json create mode 100644 packages/testing/playwright/utils/path-helper.ts create mode 100644 packages/testing/playwright/workflows/Test_workflow_1.json create mode 100644 packages/testing/playwright/workflows/test_pdf_workflow.json diff --git a/.gitignore b/.gitignore index 0359a9f213..4161487a74 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,10 @@ build-storybook.log junit.xml test-results.json *.0x +packages/testing/playwright/playwright-report +packages/testing/playwright/test-results +packages/testing/playwright/ms-playwright-cache +test-results/ compiled_app_output trivy_report* compiled diff --git a/package.json b/package.json index 566d739c24..c56d5e4a38 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "build:n8n": "node scripts/build-n8n.mjs", "build:docker": "node scripts/build-n8n.mjs && node scripts/dockerize-n8n.mjs", "build:docker:scan": "node scripts/build-n8n.mjs && node scripts/dockerize-n8n.mjs && node scripts/scan-n8n-image.mjs", + "build:docker:test": "node scripts/build-n8n.mjs && node scripts/dockerize-n8n.mjs && pnpm --filter=n8n-playwright run test:standard", "typecheck": "turbo typecheck", "dev": "turbo run dev --parallel --env-mode=loose --filter=!@n8n/design-system --filter=!@n8n/chat --filter=!@n8n/task-runner", "dev:be": "turbo run dev --parallel --env-mode=loose --filter=!@n8n/design-system --filter=!@n8n/chat --filter=!@n8n/task-runner --filter=!n8n-editor-ui", @@ -101,7 +102,9 @@ "ws": ">=8.17.1", "zod": "3.25.67", "brace-expansion@1": "1.1.12", - "brace-expansion@2": "2.0.2" + "brace-expansion@2": "2.0.2", + "date-fns": "2.30.0", + "date-fns-tz": "2.0.0" }, "patchedDependencies": { "bull@4.16.4": "patches/bull@4.16.4.patch", diff --git a/packages/cli/src/controllers/e2e.controller.ts b/packages/cli/src/controllers/e2e.controller.ts index 5cbf71a409..f86354138a 100644 --- a/packages/cli/src/controllers/e2e.controller.ts +++ b/packages/cli/src/controllers/e2e.controller.ts @@ -229,14 +229,20 @@ export class E2EController { } private async truncateAll() { + const { connection } = this.settingsRepo.manager; + const dbType = connection.options.type; for (const table of tablesToTruncate) { try { - const { connection } = this.settingsRepo.manager; - await connection.query( - `DELETE FROM ${table}; DELETE FROM sqlite_sequence WHERE name=${table};`, - ); + if (dbType === 'postgres') { + await connection.query(`TRUNCATE TABLE "${table}" RESTART IDENTITY CASCADE;`); + } else { + await connection.query(`DELETE FROM "${table}";`); + if (dbType === 'sqlite') { + await connection.query(`DELETE FROM sqlite_sequence WHERE name = '${table}';`); + } + } } catch (error) { - Container.get(Logger).warn('Dropping Table for E2E Reset error', { + Container.get(Logger).warn(`Dropping Table "${table}" for E2E Reset error`, { error: error as Error, }); } diff --git a/packages/testing/containers/README.md b/packages/testing/containers/README.md new file mode 100644 index 0000000000..f9b06476e7 --- /dev/null +++ b/packages/testing/containers/README.md @@ -0,0 +1,170 @@ +# n8n Test Containers - Usage Guide + +A simple way to spin up n8n container stacks for development and testing. + +## Quick Start + +```bash +# Start a basic n8n instance (SQLite database) +pnpm stack + +# Start with PostgreSQL database +pnpm stack --postgres + +# Start in queue mode (with Redis + PostgreSQL) +pnpm stack --queue +``` + +When started, you'll see: +- **URL**: http://localhost:[random-port] + + +## Common Usage Patterns + +### Development with Container Reuse +```bash +# Enable container reuse (faster restarts) +pnpm run dev # SQLite +pnpm run dev:postgres # PostgreSQL +pnpm run dev:queue # Queue mode +pnpm run dev:multi-main # Multiple main instances +``` + +### Queue Mode with Scaling +```bash +# Custom scaling: 3 main instances, 5 workers +pnpm stack --queue --mains 3 --workers 5 + +# Single main, 2 workers +pnpm stack --queue --workers 2 +``` + +### Environment Variables +```bash +# Set custom environment variables +pnpm run stack --postgres --env N8N_LOG_LEVEL=info --env N8N_ENABLED_MODULES=insights +``` + +### Parallel Testing +```bash +# Run multiple stacks in parallel with unique names +pnpm run stack --name test-1 --postgres +pnpm run stack --name test-2 --queue +``` + + +## Custom Container Config + +### Via Command Line +```bash +# Pass any n8n env vars to containers +N8N_TEST_ENV='{"N8N_METRICS":"true"}' npm run stack:standard +N8N_TEST_ENV='{"N8N_LOG_LEVEL":"debug","N8N_METRICS":"true","N8N_ENABLED_MODULES":"insights"}' npm run stack:postgres +``` + +## Programmatic Usage + +```typescript +import { createN8NStack } from './containers/n8n-test-containers'; + +// Simple SQLite instance +const stack = await createN8NStack(); + +// PostgreSQL with custom environment +const stack = await createN8NStack({ + postgres: true, + env: { N8N_LOG_LEVEL: 'debug' } +}); + +// Queue mode with scaling +const stack = await createN8NStack({ + queueMode: { mains: 2, workers: 3 } +}); + +// Use the stack +console.log(`n8n available at: ${stack.baseUrl}`); + +// Clean up when done +await stack.stop(); +``` + +## Configuration Options + +| Option | Description | Example | +|--------|-------------|---------| +| `--postgres` | Use PostgreSQL instead of SQLite | `npm run stack -- --postgres` | +| `--queue` | Enable queue mode with Redis | `npm run stack -- --queue` | +| `--mains ` | Number of main instances (requires queue mode) | `--mains 3` | +| `--workers ` | Number of worker instances (requires queue mode) | `--workers 5` | +| `--name ` | Custom project name for parallel runs | `--name my-test` | +| `--env KEY=VALUE` | Set environment variables | `--env N8N_LOG_LEVEL=debug` | + +## Container Architecture + +### Single Instance (Default) +``` +┌─────────────┐ +│ n8n │ ← SQLite database +│ (SQLite) │ +└─────────────┘ +``` + +### With PostgreSQL +``` +┌─────────────┐ ┌──────────────┐ +│ n8n │────│ PostgreSQL │ +│ │ │ │ +└─────────────┘ └──────────────┘ +``` + +### Queue Mode +``` +┌─────────────┐ ┌──────────────┐ ┌─────────────┐ +│ n8n-main │────│ PostgreSQL │ │ Redis │ +└─────────────┘ └──────────────┘ └─────────────┘ +┌─────────────┐ │ │ +│ n8n-worker │────────────────────────┘ │ +└─────────────┘ │ +┌─────────────┐ │ +│ n8n-worker │──────────────────────────────────────┘ +└─────────────┘ +``` + +### Multi-Main with Load Balancer +``` + ┌──────────────┐ + ────│ nginx │ ← Entry point + / │ Load Balancer│ +┌─────────────┐ └──────────────┘ +│ n8n-main-1 │────┐ +└─────────────┘ │ ┌──────────────┐ ┌─────────────┐ +┌─────────────┐ ├─│ PostgreSQL │ │ Redis │ +│ n8n-main-2 │────┤ └──────────────┘ └─────────────┘ +└─────────────┘ │ │ │ +┌─────────────┐ │ ┌─────────────────────────────────┤ +│ n8n-worker │────┘ │ │ +└─────────────┘ └─────────────────────────────────┘ +``` + +## Cleanup + +```bash +# Remove all n8n containers and networks +pnpm run stack:clean:all + + +## Tips + +- **Container Reuse**: Set `TESTCONTAINERS_REUSE_ENABLE=true` for faster development cycles +- **Parallel Testing**: Use `--name` parameter to run multiple stacks without conflicts +- **Queue Mode**: Automatically enables PostgreSQL (required for queue mode) +- **Multi-Main**: Requires queue mode and special licensing read from N8N_LICENSE_ACTIVATION_KEY environment variable +- **Log Monitoring**: Use the `ContainerTestHelpers` class for advanced log monitoring in tests + +## Docker Image + +By default, uses the `n8nio/n8n:local` image. Override with: +```bash +export N8N_DOCKER_IMAGE=n8nio/n8n:dev +pnpm run stack +``` diff --git a/packages/testing/containers/docker-image-not-found-error.ts b/packages/testing/containers/docker-image-not-found-error.ts new file mode 100644 index 0000000000..95a0ff0896 --- /dev/null +++ b/packages/testing/containers/docker-image-not-found-error.ts @@ -0,0 +1,22 @@ +// Custom error class for when the Docker image is not found locally/remotely +// This can happen when using the "n8nio/n8n:local" image, which is not available on Docker Hub +// This image is available after running `pnpm build:docker` at the root of the repository +export class DockerImageNotFoundError extends Error { + constructor(containerName: string, originalError?: Error) { + const dockerImage = process.env.N8N_DOCKER_IMAGE ?? 'n8nio/n8n:local'; + + const message = `Failed to start container ${containerName}: Docker image '${dockerImage}' not found locally! + +This is likely because the image is not available locally. +To fix this, you can either: + 1. Build the image by running: pnpm build:docker at the root + 2. Use a different image by setting: N8N_DOCKER_IMAGE= + +Example with different image: + N8N_DOCKER_IMAGE=n8nio/n8n:latest npm run stack`; + + super(message); + this.name = 'DockerImageNotFoundError'; + this.cause = originalError; + } +} diff --git a/packages/testing/containers/n8n-start-stack.ts b/packages/testing/containers/n8n-start-stack.ts new file mode 100755 index 0000000000..d8b4bbb4ee --- /dev/null +++ b/packages/testing/containers/n8n-start-stack.ts @@ -0,0 +1,202 @@ +#!/usr/bin/env tsx +import { parseArgs } from 'node:util'; + +import type { N8NConfig, N8NStack } from './n8n-test-container-creation'; +import { createN8NStack } from './n8n-test-container-creation'; +import { DockerImageNotFoundError } from './docker-image-not-found-error'; + +// ANSI colors for terminal output +const colors = { + reset: '\x1b[0m', + bright: '\x1b[1m', + green: '\x1b[32m', + yellow: '\x1b[33m', + blue: '\x1b[34m', + red: '\x1b[31m', + cyan: '\x1b[36m', +}; + +const log = { + info: (msg: string) => console.log(`${colors.blue}ℹ${colors.reset} ${msg}`), + success: (msg: string) => console.log(`${colors.green}✓${colors.reset} ${msg}`), + error: (msg: string) => console.error(`${colors.red}✗${colors.reset} ${msg}`), + warn: (msg: string) => console.warn(`${colors.yellow}⚠${colors.reset} ${msg}`), + header: (msg: string) => console.log(`\n${colors.bright}${colors.cyan}${msg}${colors.reset}\n`), +}; + +function showHelp() { + console.log(` +${colors.bright}n8n Stack Manager${colors.reset} + +Start n8n containers for development and testing. + +${colors.yellow}Usage:${colors.reset} + npm run stack [options] + +${colors.yellow}Options:${colors.reset} + --postgres Use PostgreSQL instead of SQLite + --queue Enable queue mode (requires PostgreSQL) + --mains Number of main instances (default: 1) + --workers Number of worker instances (default: 1) + --name Project name for parallel runs + --env KEY=VALUE Set environment variables + --help, -h Show this help + +${colors.yellow}Examples:${colors.reset} + ${colors.bright}# Simple SQLite instance${colors.reset} + npm run stack + + ${colors.bright}# PostgreSQL database${colors.reset} + npm run stack --postgres + + ${colors.bright}# Queue mode (automatically uses PostgreSQL)${colors.reset} + npm run stack --queue + + ${colors.bright}# Custom scaling${colors.reset} + npm run stack --queue --mains 3 --workers 5 + + ${colors.bright}# With environment variables${colors.reset} + npm run stack --postgres --env N8N_LOG_LEVEL=info --env N8N_ENABLED_MODULES=insights + + ${colors.bright}# Parallel instances${colors.reset} + npm run stack --name test-1 + npm run stack --name test-2 + +${colors.yellow}Notes:${colors.reset} + • SQLite is the default database (no external dependencies) + • Queue mode requires PostgreSQL and enables horizontal scaling + • Use --name for running multiple instances in parallel + • Press Ctrl+C to stop all containers +`); +} + +async function main() { + const { values } = parseArgs({ + args: process.argv.slice(2), + options: { + help: { type: 'boolean', short: 'h' }, + postgres: { type: 'boolean' }, + queue: { type: 'boolean' }, + mains: { type: 'string' }, + workers: { type: 'string' }, + name: { type: 'string' }, + env: { type: 'string', multiple: true }, + }, + allowPositionals: false, + }); + + // Show help if requested + if (values.help) { + showHelp(); + process.exit(0); + } + + // Build configuration + const config: N8NConfig = { + postgres: values.postgres ?? false, + projectName: values.name ?? `n8n-stack-${Math.random().toString(36).substring(7)}`, + }; + + // Handle queue mode + if (values.queue ?? values.mains ?? values.workers) { + const mains = parseInt(values.mains ?? '1', 10); + const workers = parseInt(values.workers ?? '1', 10); + + if (isNaN(mains) || isNaN(workers) || mains < 1 || workers < 0) { + log.error('Invalid mains or workers count'); + process.exit(1); + } + + config.queueMode = { mains, workers }; + + if (!values.queue && (values.mains ?? values.workers)) { + log.warn('--mains and --workers imply queue mode'); + } + } + + // Parse environment variables + if (values.env && values.env.length > 0) { + config.env = {}; + + for (const envStr of values.env) { + const [key, ...valueParts] = envStr.split('='); + const value = valueParts.join('='); // Handle values with = in them + + if (key && value) { + config.env[key] = value; + } else { + log.warn(`Invalid env format: ${envStr} (expected KEY=VALUE)`); + } + } + } + + log.header('Starting n8n Stack'); + log.info(`Project name: ${config.projectName}`); + displayConfig(config); + + let stack: N8NStack; + + try { + log.info('Starting containers...'); + try { + stack = await createN8NStack(config); + } catch (error) { + if (error instanceof DockerImageNotFoundError) { + log.error(error.message); + process.exit(1); + } + throw error; + } + + log.success('All containers started successfully!'); + console.log(''); + log.info(`n8n URL: ${colors.bright}${colors.green}${stack.baseUrl}${colors.reset}`); + } catch (error) { + log.error(`Failed to start: ${error as string}`); + process.exit(1); + } +} + +function displayConfig(config: N8NConfig) { + const dockerImage = process.env.N8N_DOCKER_IMAGE ?? 'n8nio/n8n:local'; + log.info(`Docker image: ${dockerImage}`); + + // Determine actual database + const usePostgres = config.postgres || config.queueMode; + log.info(`Database: ${usePostgres ? 'PostgreSQL' : 'SQLite'}`); + + if (config.queueMode) { + const qm = typeof config.queueMode === 'boolean' ? { mains: 1, workers: 1 } : config.queueMode; + log.info(`Queue mode: ${qm.mains} main(s), ${qm.workers} worker(s)`); + if (!config.postgres) { + log.info('(PostgreSQL automatically enabled for queue mode)'); + } + if (qm.mains && qm.mains > 1) { + log.info('(nginx load balancer will be configured)'); + } + } else { + log.info('Queue mode: disabled'); + } + + if (config.env) { + const envCount = Object.keys(config.env).length; + if (envCount > 0) { + log.info(`Environment variables: ${envCount} custom variable(s)`); + Object.entries(config.env).forEach(([key, value]) => { + console.log(` ${key}=${value as string}`); + }); + } + } + + if (process.env.TESTCONTAINERS_REUSE_ENABLE === 'true') { + log.info('Container reuse: enabled (containers will persist)'); + } +} + +// Run if executed directly +if (require.main === module) { + main().catch((error) => { + log.error(`Unexpected error: ${error}`); + process.exit(1); + }); +} diff --git a/packages/testing/containers/n8n-test-container-creation.ts b/packages/testing/containers/n8n-test-container-creation.ts new file mode 100644 index 0000000000..4c4e7977ab --- /dev/null +++ b/packages/testing/containers/n8n-test-container-creation.ts @@ -0,0 +1,340 @@ +/** + * n8n Test Containers Setup + * This file provides a complete n8n container stack for testing with support for: + * - Single instances (SQLite or PostgreSQL) + * - Queue mode with Redis + * - Multi-main instances with nginx load balancing + * - Parallel execution (multiple stacks running simultaneously) + * + * Key features for parallel execution: + * - Dynamic port allocation to avoid conflicts (handled by testcontainers) + * - WebSocket support through nginx load balancer + */ + +import type { StartedNetwork, StartedTestContainer } from 'testcontainers'; +import { GenericContainer, Network, Wait } from 'testcontainers'; + +import { + setupNginxLoadBalancer, + setupPostgres, + setupRedis, +} from './n8n-test-container-dependencies'; +import { DockerImageNotFoundError } from './docker-image-not-found-error'; + +// --- Constants --- + +const POSTGRES_IMAGE = 'postgres:16-alpine'; +const REDIS_IMAGE = 'redis:7-alpine'; +const NGINX_IMAGE = 'nginx:stable'; +const N8N_E2E_IMAGE = 'n8nio/n8n:local'; + +// Default n8n image (can be overridden via N8N_DOCKER_IMAGE env var) +const N8N_IMAGE = process.env.N8N_DOCKER_IMAGE || N8N_E2E_IMAGE; + +// Base environment for all n8n instances +const BASE_ENV: Record = { + N8N_LOG_LEVEL: 'debug', + N8N_ENCRYPTION_KEY: 'test-encryption-key', + E2E_TESTS: 'true', + QUEUE_HEALTH_CHECK_ACTIVE: 'true', + N8N_DIAGNOSTICS_ENABLED: 'false', + NODE_ENV: 'development', // If this is set to test, the n8n container will not start, insights module is not found?? +}; + +const MULTI_MAIN_LICENSE = { + N8N_LICENSE_TENANT_ID: '1001', + N8N_LICENSE_ACTIVATION_KEY: process.env.N8N_LICENSE_ACTIVATION_KEY ?? '', +}; + +// Wait strategy for n8n containers +const N8N_WAIT_STRATEGY = Wait.forAll([ + Wait.forListeningPorts(), + Wait.forHttp('/healthz/readiness', 5678).forStatusCode(200).withStartupTimeout(90000), +]); + +// --- Interfaces --- + +export interface N8NConfig { + postgres?: boolean; + queueMode?: + | boolean + | { + mains?: number; + workers?: number; + }; + env?: Record; + projectName?: string; +} + +export interface N8NStack { + baseUrl: string; + stop: () => Promise; + containers: StartedTestContainer[]; +} + +/** + * Create an n8n container stack + * + * @example + * // Simple SQLite instance + * const stack = await createN8NStack(); + * + * @example + * // PostgreSQL without queue mode + * const stack = await createN8NStack({ postgres: true }); + * + * @example + * // Queue mode (automatically uses PostgreSQL) + * const stack = await createN8NStack({ queueMode: true }); + * + * @example + * // Custom scaling + * const stack = await createN8NStack({ + * queueMode: { mains: 3, workers: 5 }, + * env: { N8N_ENABLED_MODULES: 'insights' } + * }); + */ +export async function createN8NStack(config: N8NConfig = {}): Promise { + const { postgres = false, queueMode = false, env = {}, projectName } = config; + const queueConfig = normalizeQueueConfig(queueMode); + const usePostgres = postgres || !!queueConfig; + const uniqueProjectName = projectName ?? `n8n-${Math.random().toString(36).substring(7)}`; + const containers: StartedTestContainer[] = []; + let network: StartedNetwork | undefined; + let nginxContainer: StartedTestContainer | undefined; + + let environment: Record = { ...BASE_ENV, ...env }; + + if (usePostgres || queueConfig) { + network = await new Network().start(); + } + + if (usePostgres) { + const postgresContainer = await setupPostgres({ + postgresImage: POSTGRES_IMAGE, + projectName: uniqueProjectName, + network: network!, + }); + containers.push(postgresContainer.container); + environment = { + ...environment, + DB_TYPE: 'postgresdb', + DB_POSTGRESDB_HOST: 'postgres', + DB_POSTGRESDB_PORT: '5432', + DB_POSTGRESDB_DATABASE: postgresContainer.database, + DB_POSTGRESDB_USER: postgresContainer.username, + DB_POSTGRESDB_PASSWORD: postgresContainer.password, + }; + } else { + environment.DB_TYPE = 'sqlite'; + } + + if (queueConfig) { + const redis = await setupRedis({ + redisImage: REDIS_IMAGE, + projectName: uniqueProjectName, + network: network!, + }); + containers.push(redis); + environment = { + ...environment, + EXECUTIONS_MODE: 'queue', + QUEUE_BULL_REDIS_HOST: 'redis', + QUEUE_BULL_REDIS_PORT: '6379', + }; + + if (queueConfig.mains > 1) { + if (!process.env.N8N_LICENSE_ACTIVATION_KEY) { + throw new Error('N8N_LICENSE_ACTIVATION_KEY is required for multi-main instances'); + } + environment = { + ...environment, + N8N_PROXY_HOPS: '1', + N8N_MULTI_MAIN_SETUP_ENABLED: 'true', + ...MULTI_MAIN_LICENSE, + }; + } + } + + let baseUrl: string; + + const instances = await createN8NInstances({ + mainCount: queueConfig?.mains ?? 1, + workerCount: queueConfig?.workers ?? 0, + uniqueProjectName: uniqueProjectName, + environment, + network, + }); + containers.push(...instances); + + if (queueConfig && queueConfig.mains > 1) { + nginxContainer = await setupNginxLoadBalancer({ + nginxImage: NGINX_IMAGE, + projectName: uniqueProjectName, + mainInstances: instances.slice(0, queueConfig.mains), + network: network!, + }); + containers.push(nginxContainer); + baseUrl = `http://localhost:${nginxContainer.getMappedPort(80)}`; + } else { + baseUrl = `http://localhost:${instances[0].getMappedPort(5678)}`; + } + + return { + baseUrl, + stop: async () => { + await stopN8NStack(containers, network, uniqueProjectName); + }, + containers, + }; +} + +async function stopN8NStack( + containers: StartedTestContainer[], + network: StartedNetwork | undefined, + uniqueProjectName: string, +): Promise { + const errors: Error[] = []; + try { + const stopPromises = containers.reverse().map(async (container) => { + try { + await container.stop(); + } catch (error) { + errors.push(new Error(`Failed to stop container ${container.getId()}: ${error as string}`)); + } + }); + await Promise.allSettled(stopPromises); + + if (network) { + try { + await network.stop(); + } catch (error) { + errors.push(new Error(`Failed to stop network ${network.getName()}: ${error as string}`)); + } + } + + if (errors.length > 0) { + console.warn( + `Some cleanup operations failed for stack ${uniqueProjectName}:`, + errors.map((e) => e.message).join(', '), + ); + } + } catch (error) { + console.error(`Critical error during cleanup for stack ${uniqueProjectName}:`, error); + throw error; + } +} + +function normalizeQueueConfig( + queueMode: boolean | { mains?: number; workers?: number }, +): { mains: number; workers: number } | null { + if (!queueMode) return null; + if (typeof queueMode === 'boolean') { + return { mains: 1, workers: 1 }; + } + return { + mains: queueMode.mains ?? 1, + workers: queueMode.workers ?? 1, + }; +} + +interface CreateInstancesOptions { + mainCount: number; + workerCount: number; + uniqueProjectName: string; + environment: Record; + network?: StartedNetwork; +} + +async function createN8NInstances({ + mainCount, + workerCount, + uniqueProjectName, + environment, + network, +}: CreateInstancesOptions): Promise { + const instances: StartedTestContainer[] = []; + + for (let i = 1; i <= mainCount; i++) { + const name = mainCount > 1 ? `${uniqueProjectName}-n8n-main-${i}` : `${uniqueProjectName}-n8n`; + const container = await createN8NContainer({ + name, + uniqueProjectName, + environment, + network, + isWorker: false, + instanceNumber: i, + networkAlias: mainCount > 1 ? name : undefined, + }); + instances.push(container); + } + + for (let i = 1; i <= workerCount; i++) { + const name = `${uniqueProjectName}-n8n-worker-${i}`; + const container = await createN8NContainer({ + name, + uniqueProjectName, + environment, + network: network!, + isWorker: true, + instanceNumber: i, + }); + instances.push(container); + } + + return instances; +} + +interface CreateContainerOptions { + name: string; + uniqueProjectName: string; + environment: Record; + network?: StartedNetwork; + isWorker: boolean; + instanceNumber: number; + networkAlias?: string; +} + +async function createN8NContainer({ + name, + uniqueProjectName, + environment, + network, + isWorker, + instanceNumber, + networkAlias, +}: CreateContainerOptions): Promise { + let container = new GenericContainer(N8N_IMAGE); + + container = container + .withEnvironment(environment) + .withLabels({ + 'com.docker.compose.project': uniqueProjectName, + 'com.docker.compose.service': isWorker ? 'n8n-worker' : 'n8n-main', + instance: instanceNumber.toString(), + }) + .withName(name) + .withReuse(); + + if (isWorker) { + container = container.withCommand(['worker']); + } else { + container = container.withExposedPorts(5678).withWaitStrategy(N8N_WAIT_STRATEGY); + } + + if (network) { + container = container.withNetwork(network); + if (networkAlias) { + container = container.withNetworkAliases(networkAlias); + } + } + + try { + return await container.start(); + } catch (error) { + if (error instanceof Error && 'statusCode' in error && error.statusCode === 404) { + throw new DockerImageNotFoundError(name, error); + } + throw error; + } +} diff --git a/packages/testing/containers/n8n-test-container-dependencies.ts b/packages/testing/containers/n8n-test-container-dependencies.ts new file mode 100644 index 0000000000..ee9a678377 --- /dev/null +++ b/packages/testing/containers/n8n-test-container-dependencies.ts @@ -0,0 +1,189 @@ +import { PostgreSqlContainer } from '@testcontainers/postgresql'; +import { RedisContainer } from '@testcontainers/redis'; +import type { StartedNetwork, StartedTestContainer } from 'testcontainers'; +import { GenericContainer, Wait } from 'testcontainers'; + +export async function setupRedis({ + redisImage, + projectName, + network, +}: { + redisImage: string; + projectName: string; + network: StartedNetwork; +}): Promise { + return await new RedisContainer(redisImage) + .withNetwork(network) + .withNetworkAliases('redis') + .withLabels({ + 'com.docker.compose.project': projectName, + 'com.docker.compose.service': 'redis', + }) + .withName(`${projectName}-redis`) + .withReuse() + .start(); +} + +export async function setupPostgres({ + postgresImage, + projectName, + network, +}: { + postgresImage: string; + projectName: string; + network: StartedNetwork; +}): Promise<{ + container: StartedTestContainer; + database: string; + username: string; + password: string; +}> { + const postgres = await new PostgreSqlContainer(postgresImage) + .withNetwork(network) + .withNetworkAliases('postgres') + .withDatabase('n8n_db') + .withUsername('n8n_user') + .withPassword('test_password') + .withStartupTimeout(30000) + .withLabels({ + 'com.docker.compose.project': projectName, + 'com.docker.compose.service': 'postgres', + }) + .withName(`${projectName}-postgres`) + .withReuse() + .start(); + + return { + container: postgres, + database: postgres.getDatabase(), + username: postgres.getUsername(), + password: postgres.getPassword(), + }; +} + +/** + * Setup NGINX for multi-main instances + * @param nginxImage The Docker image for NGINX. + * @param uniqueSuffix A unique suffix for naming and labeling. + * @param mainInstances An array of running backend container instances. + * @param network The shared Docker network. + * @param nginxPort The host port to expose for NGINX. + * @returns A promise that resolves to the started NGINX container. + */ +export async function setupNginxLoadBalancer({ + nginxImage, + projectName, + mainInstances, + network, +}: { + nginxImage: string; + projectName: string; + mainInstances: StartedTestContainer[]; + network: StartedNetwork; +}): Promise { + // Generate upstream server entries from the list of main instances. + const upstreamServers = mainInstances + .map((_, index) => ` server ${projectName}-n8n-main-${index + 1}:5678;`) + .join('\n'); + + // Build the NGINX configuration with dynamic upstream servers. + // This allows us to have the port allocation be dynamic. + const nginxConfig = buildNginxConfig(upstreamServers); + + return await new GenericContainer(nginxImage) + .withNetwork(network) + .withExposedPorts(80) + .withCopyContentToContainer([{ content: nginxConfig, target: '/etc/nginx/nginx.conf' }]) + .withWaitStrategy(Wait.forListeningPorts()) + .withLabels({ + 'com.docker.compose.project': projectName, + 'com.docker.compose.service': 'nginx-lb', + }) + .withName(`${projectName}-nginx-lb`) + .withReuse() + .start(); +} + +/** + * Builds NGINX configuration for load balancing n8n instances + * @param upstreamServers The upstream server entries to include in the configuration + * @returns The complete NGINX configuration as a string + */ +function buildNginxConfig(upstreamServers: string): string { + return ` + events { + worker_connections 1024; + } + + http { + client_max_body_size 50M; + access_log off; + error_log /dev/stderr warn; + + # Map for WebSocket upgrades + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + upstream backend { + # Use ip_hash for sticky sessions + ip_hash; + ${upstreamServers} + keepalive 32; + } + + server { + listen 80; + + # Set longer timeouts for slow operations + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + + location / { + proxy_pass http://backend; + + # Forward standard proxy headers + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Forward WebSocket headers + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_http_version 1.1; + proxy_buffering off; + } + + # Specific location for real-time push/websockets + location /rest/push { + proxy_pass http://backend; + + # Forward standard proxy headers + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Configure WebSocket proxying + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + + # Disable buffering for real-time data + proxy_buffering off; + + # Set very long timeouts for persistent connections + proxy_read_timeout 3600s; + proxy_send_timeout 3600s; + } + } + }`; +} + +// TODO: Look at Ollama container? +// TODO: Look at MariaDB container? +// TODO: Look at MockServer container, could we use this for mocking out external services? diff --git a/packages/testing/containers/n8n-test-container-helpers.ts b/packages/testing/containers/n8n-test-container-helpers.ts new file mode 100644 index 0000000000..3bf9030fdc --- /dev/null +++ b/packages/testing/containers/n8n-test-container-helpers.ts @@ -0,0 +1,377 @@ +import type { StartedTestContainer, StoppedTestContainer } from 'testcontainers'; + +export interface LogMatch { + container: StartedTestContainer; + containerName: string; + message: string; + timestamp: Date; +} + +interface WaitForLogOptions { + namePattern?: string | RegExp; + timeoutMs?: number; + caseSensitive?: boolean; +} + +interface StreamLogMatch { + line: string; + date: Date | null; +} + +/** + * Container helpers bound to a specific set of containers + */ +export class ContainerTestHelpers { + private static readonly DEFAULT_TIMEOUT_MS = 30000; + + private static readonly POLL_INTERVAL_MS = 1000; + + // Containers + private containers: StartedTestContainer[]; + + constructor(containers: StartedTestContainer[]) { + this.containers = containers; + } + + /** + * Read logs from a container + */ + async readLogs(containerNamePattern: string | RegExp, since?: number): Promise { + const container = this.findContainers(containerNamePattern)[0]; + if (!container) { + console.warn(`No container found matching pattern: ${containerNamePattern}`); + return ''; + } + + return await this.readLogsFromContainer(container, since); + } + + /** + * Wait for a log message matching pattern (case-insensitive by default) + * Uses streaming approach for immediate detection + */ + async waitForLog( + messagePattern: string | RegExp, + options: WaitForLogOptions = {}, + ): Promise { + const { + namePattern, + timeoutMs = ContainerTestHelpers.DEFAULT_TIMEOUT_MS, + caseSensitive = false, + } = options; + + const messageRegex = this.createRegex(messagePattern, caseSensitive); + const targetContainers = namePattern ? this.findContainers(namePattern) : this.containers; + const startTime = Date.now(); + + console.log( + `🔍 Waiting for log pattern: ${messageRegex} in ${targetContainers.length} containers (timeout: ${timeoutMs}ms)`, + ); + + // First check: scan existing logs quickly + const existingMatch = await this.findFirstMatchingLog(targetContainers, messageRegex); + if (existingMatch) { + console.log(`✅ Found existing log in ${existingMatch.containerName}`); + return existingMatch; + } + + // Monitor new logs with streaming approach + return await this.pollForNewLogs(targetContainers, messageRegex, startTime, timeoutMs); + } + + /** + * Find the first matching log across multiple containers + */ + private async findFirstMatchingLog( + containers: StartedTestContainer[], + messageRegex: RegExp, + sinceTimestamp?: number, + ): Promise { + const matchPromises = containers.map(async (container) => { + const match = await this.findLogInContainer(container, messageRegex, sinceTimestamp); + if (match) { + return { + container, + containerName: container.getName(), + message: match.line, + timestamp: match.date ?? new Date(), + }; + } + return null; + }); + + const results = await Promise.all(matchPromises); + return results.find((result) => result !== null) ?? null; + } + + /** + * Poll containers for new logs matching the pattern + */ + private async pollForNewLogs( + targetContainers: StartedTestContainer[], + messageRegex: RegExp, + startTime: number, + timeoutMs: number, + ): Promise { + let currentCheckTime = Math.floor(Date.now() / 1000); + let iteration = 0; + + while (Date.now() - startTime < timeoutMs) { + iteration++; + await this.sleep(ContainerTestHelpers.POLL_INTERVAL_MS); + + // Capture the timestamp for this iteration to avoid race conditions + const checkTimestamp = currentCheckTime; + + // Check all containers concurrently + const matchPromises = targetContainers.map((container) => + this.checkContainerForMatch(container, messageRegex, checkTimestamp), + ); + + const results = await Promise.all(matchPromises); + const found = results.find((result) => result !== null); + + if (found) { + console.log(`✅ Found new log in ${found.containerName} (iteration ${iteration})`); + return found; + } + + // Update timestamp for next iteration + currentCheckTime = Math.floor(Date.now() / 1000); + + // Progress indicator + if (iteration % 10 === 0) { + const elapsedSeconds = Math.floor((Date.now() - startTime) / 1000); + console.log(`⏱️ Still waiting... (${elapsedSeconds}s elapsed)`); + } + } + + console.log(`❌ Timeout reached after ${timeoutMs}ms`); + throw new Error(`Timeout reached after ${timeoutMs}ms`); + } + + /** + * Check a single container for matching logs + */ + private async checkContainerForMatch( + container: StartedTestContainer, + messageRegex: RegExp, + sinceTimestamp: number, + ): Promise { + const match = await this.findLogInContainer(container, messageRegex, sinceTimestamp); + + if (!match) { + return null; + } + + return { + container, + containerName: container.getName(), + message: match.line, + timestamp: match.date ?? new Date(), + }; + } + + /** + * Get all log messages matching pattern (case-insensitive by default) + */ + async getLogs( + messagePattern: string | RegExp, + namePattern?: string | RegExp, + caseSensitive = false, + ): Promise { + const messageRegex = this.createRegex(messagePattern, caseSensitive); + const targetContainers = namePattern ? this.findContainers(namePattern) : this.containers; + + console.log( + `🔍 Getting all logs matching: ${messageRegex} from ${targetContainers.length} containers`, + ); + + const logPromises = targetContainers.map(async (container) => { + const logs = await this.readLogsFromContainer(container); + return this.findAllLogMatches(logs, messageRegex, container); + }); + + const results = await Promise.all(logPromises); + const matches = results.flat(); + + console.log(`📈 Total matches found: ${matches.length}`); + return matches; + } + + /** + * Find containers by name pattern + */ + findContainers(namePattern: string | RegExp): StartedTestContainer[] { + const regex = typeof namePattern === 'string' ? new RegExp(namePattern) : namePattern; + const foundContainers = this.containers.filter((container) => regex.test(container.getName())); + + console.log(`🔎 Found ${foundContainers.length} containers matching pattern`); + return foundContainers; + } + + /** + * Stop container by name pattern + */ + async stopContainer(namePattern: string | RegExp): Promise { + const container = this.findContainers(namePattern)[0]; + return container ? await container.stop() : null; + } + + // Private helper methods + + private createRegex(pattern: string | RegExp, caseSensitive: boolean): RegExp { + return typeof pattern === 'string' ? new RegExp(pattern, caseSensitive ? 'g' : 'gi') : pattern; + } + + /** + * Strip ANSI escape codes from log text + */ + private stripAnsiCodes(text: string): string { + return text.replace(/\x1B\[[0-9;]*[mGKH]/g, ''); + } + + /** + * Extract timestamp from log line + */ + private extractTimestamp(line: string): Date | null { + const timestampMatch = line.match(/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z)/); + return timestampMatch ? new Date(timestampMatch[1]) : null; + } + + /** + * Find log line in container using streaming approach with early exit + */ + private async findLogInContainer( + container: StartedTestContainer, + messageRegex: RegExp, + since?: number, + ): Promise { + try { + const logOptions: any = {}; + if (since !== undefined) { + logOptions.since = since; + } + + const stream = await container.logs(logOptions); + + return await new Promise((resolve, reject) => { + let buffer = ''; + + const timeout = setTimeout(() => { + stream.destroy(); + resolve(null); // Timeout means no match found + }, 5000); // Shorter timeout for individual container checks + + const onData = (chunk: Buffer | string) => { + buffer += chunk.toString(); + const lines = buffer.split('\n'); + + // Keep the last incomplete line in buffer + buffer = lines.pop() ?? ''; + + // Check complete lines + for (const line of lines) { + const cleanLine = this.stripAnsiCodes(line.trim()); + if (cleanLine && messageRegex.test(cleanLine)) { + clearTimeout(timeout); + stream.destroy(); + resolve({ + line: cleanLine, + date: this.extractTimestamp(cleanLine), + }); + return; + } + } + }; + + stream.on('data', onData); + + stream.on('end', () => { + clearTimeout(timeout); + stream.destroy(); + resolve(null); // No match found + }); + + stream.on('error', (error) => { + clearTimeout(timeout); + stream.destroy(); + console.error(`❌ Stream error from ${container.getName()}:`, error); + reject(error); + }); + }); + } catch (error) { + console.warn(`❌ Failed to search logs from ${container.getName()}: ${error as string}`); + return null; + } + } + + private async readLogsFromContainer( + container: StartedTestContainer, + since?: number, + ): Promise { + try { + const logOptions: any = {}; + if (since !== undefined) { + logOptions.since = since; + } + + const stream = await container.logs(logOptions); + let allData = ''; + + return await new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + stream.destroy(); + reject(new Error('Log read timeout')); + }, 10000); + + stream.on('data', (chunk: Buffer | string) => { + allData += chunk.toString(); + }); + + stream.on('end', () => { + clearTimeout(timeout); + stream.destroy(); + resolve(this.stripAnsiCodes(allData)); + }); + + stream.on('error', (error) => { + clearTimeout(timeout); + stream.destroy(); + console.error(`❌ Stream error from ${container.getName()}:`, error); + reject(error); + }); + }); + } catch (error) { + console.warn(`❌ Failed to read logs from ${container.getName()}: ${error as string}`); + return ''; + } + } + + private findAllLogMatches( + logs: string, + messageRegex: RegExp, + container: StartedTestContainer, + ): LogMatch[] { + const lines = logs.split('\n').filter((line) => line.trim()); + const matches: LogMatch[] = []; + + for (const line of lines) { + const cleanLine = line.trim(); + if (messageRegex.test(cleanLine)) { + matches.push({ + container, + containerName: container.getName(), + message: cleanLine, + timestamp: this.extractTimestamp(cleanLine) ?? new Date(), + }); + } + } + + return matches; + } + + private sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); + } +} diff --git a/packages/testing/containers/package.json b/packages/testing/containers/package.json new file mode 100644 index 0000000000..518bc94278 --- /dev/null +++ b/packages/testing/containers/package.json @@ -0,0 +1,23 @@ +{ + "name": "n8n-containers", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "stack": "tsx ./n8n-start-stack.ts", + "stack:help": "tsx ./n8n-start-stack.ts --help", + "dev": "TESTCONTAINERS_REUSE_ENABLE=true npm run stack", + "dev:postgres": "TESTCONTAINERS_REUSE_ENABLE=true npm run stack -- --postgres", + "dev:queue": "TESTCONTAINERS_REUSE_ENABLE=true npm run stack -- --queue", + "dev:multi-main": "TESTCONTAINERS_REUSE_ENABLE=true npm run stack -- --mains 2 --workers 1", + "stack:clean:all": "docker rm -f $(docker ps -aq --filter 'name=n8n-*') 2>/dev/null || true && docker network prune -f" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@testcontainers/postgresql": "^11.0.3", + "@testcontainers/redis": "^11.0.3", + "testcontainers": "^11.0.3" + } +} diff --git a/packages/testing/playwright/.eslintrc.js b/packages/testing/playwright/.eslintrc.js new file mode 100644 index 0000000000..0576337e09 --- /dev/null +++ b/packages/testing/playwright/.eslintrc.js @@ -0,0 +1,41 @@ +const sharedOptions = require('@n8n/eslint-config/shared'); + +/** + * @type {import('@types/eslint').ESLint.ConfigData} + */ +module.exports = { + extends: ['@n8n/eslint-config/base', 'plugin:playwright/recommended'], + + ...sharedOptions(__dirname), + + plugins: ['playwright'], + + env: { + node: true, + }, + + rules: { + // TODO: remove these rules + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/no-unused-expressions': 'off', + '@typescript-eslint/no-use-before-define': 'off', + '@typescript-eslint/promise-function-async': 'off', + 'n8n-local-rules/no-uncaught-json-parse': 'off', + 'playwright/expect-expect': 'warn', + 'playwright/max-nested-describe': 'warn', + 'playwright/no-conditional-in-test': 'warn', + 'playwright/no-skipped-test': 'warn', + 'import/no-extraneous-dependencies': [ + 'error', + { + devDependencies: ['**/tests/**', '**/e2e/**', '**/playwright/**'], + optionalDependencies: false, + }, + ], + }, +}; diff --git a/packages/testing/playwright/README.md b/packages/testing/playwright/README.md new file mode 100644 index 0000000000..1206e2cc8e --- /dev/null +++ b/packages/testing/playwright/README.md @@ -0,0 +1,41 @@ +# Playwright E2E Test Guide + +## Quick Start +```bash +pnpm test # Run all tests (fresh containers) +pnpm run test:local # Run against http://localhost:5678 +``` + +## Test Commands +```bash +# By Mode +pnpm run test:standard # Basic n8n +pnpm run test:postgres # PostgreSQL +pnpm run test:queue # Queue mode +pnpm run test:multi-main # HA setup + +# Development +pnpm test --grep "workflow" # Pattern match +``` + +## Test Tags +```typescript +test('basic test', ...) // All modes, fully parallel +test('postgres only @mode:postgres', ...) // Mode-specific +test('needs clean db @db:reset', ...) // Sequential per worker +test('chaos test @mode:multi-main @chaostest', ...) // Isolated per worker +``` + +## Tips +- `test:*` commands use fresh containers (for testing) +- VS Code: Set `N8N_BASE_URL` in Playwright settings to run tests directly from VS Code +- Pass custom env vars via `N8N_TEST_ENV='{"KEY":"value"}'` + +## Project Layout +- **composables**: Multi-page interactions (e.g., `WorkflowComposer.executeWorkflowAndWaitForNotification()`) +- **config**: Test setup and configuration (constants, test users, etc.) +- **fixtures**: Custom test fixtures extending Playwright's base test +- **pages**: Page Object Models for UI interactions +- **services**: API helpers for E2E controller, REST calls, etc. +- **utils**: Utility functions (string manipulation, helpers, etc.) +- **workflows**: Test workflow JSON files for import/reuse \ No newline at end of file diff --git a/packages/testing/playwright/Types.ts b/packages/testing/playwright/Types.ts new file mode 100644 index 0000000000..0648aa22eb --- /dev/null +++ b/packages/testing/playwright/Types.ts @@ -0,0 +1,6 @@ +export class TestError extends Error { + constructor(message: string) { + super(message); + this.name = 'TestError'; + } +} diff --git a/packages/testing/playwright/composables/CanvasComposer.ts b/packages/testing/playwright/composables/CanvasComposer.ts new file mode 100644 index 0000000000..75b2d020b3 --- /dev/null +++ b/packages/testing/playwright/composables/CanvasComposer.ts @@ -0,0 +1,15 @@ +import type { n8nPage } from '../pages/n8nPage'; + +export class CanvasComposer { + constructor(private readonly n8n: n8nPage) {} + + /** + * Pin the data on a node. Then close the node. + * @param nodeName - The name of the node to pin the data on. + */ + async pinNodeData(nodeName: string) { + await this.n8n.canvas.openNode(nodeName); + await this.n8n.ndv.togglePinData(); + await this.n8n.ndv.close(); + } +} diff --git a/packages/testing/playwright/composables/ProjectComposer.ts b/packages/testing/playwright/composables/ProjectComposer.ts new file mode 100644 index 0000000000..2c31aba464 --- /dev/null +++ b/packages/testing/playwright/composables/ProjectComposer.ts @@ -0,0 +1,56 @@ +import type { n8nPage } from '../pages/n8nPage'; + +export class ProjectComposer { + constructor(private readonly n8n: n8nPage) {} + + /** + * Create a project and return the project name and ID. If no project name is provided, a unique name will be generated. + * @param projectName - The name of the project to create. + * @returns The project name and ID. + */ + async createProject(projectName?: string) { + await this.n8n.page.getByTestId('universal-add').click(); + await Promise.all([ + this.n8n.page.waitForResponse('**/rest/projects/*'), + this.n8n.page.getByTestId('navigation-menu-item').filter({ hasText: 'Project' }).click(), + ]); + await this.n8n.notifications.waitForNotificationAndClose('saved successfully'); + await this.n8n.page.waitForLoadState(); + const projectNameUnique = projectName ?? `Project ${Date.now()}`; + await this.n8n.projectSettings.fillProjectName(projectNameUnique); + await this.n8n.projectSettings.clickSaveButton(); + const projectId = await this.extractProjectIdFromPage('projects', 'settings'); + return { projectName: projectNameUnique, projectId }; + } + + /** + * Add a new credential to a project. + * @param projectName - The name of the project to add the credential to. + * @param credentialType - The type of credential to add by visible name e.g 'Notion API' + * @param credentialFieldName - The name of the field to add the credential to. e.g. 'apiKey' which would be data-test-id='parameter-input-apiKey' + * @param credentialValue - The value of the credential to add. + */ + async addCredentialToProject( + projectName: string, + credentialType: string, + credentialFieldName: string, + credentialValue: string, + ) { + await this.n8n.sideBar.openNewCredentialDialogForProject(projectName); + await this.n8n.credentials.openNewCredentialDialogFromCredentialList(credentialType); + await this.n8n.credentials.fillCredentialField(credentialFieldName, credentialValue); + await this.n8n.credentials.saveCredential(); + await this.n8n.notifications.waitForNotificationAndClose('Credential successfully created'); + await this.n8n.credentials.closeCredentialDialog(); + } + + extractIdFromUrl(url: string, beforeWord: string, afterWord: string): string { + const path = url.includes('://') ? new URL(url).pathname : url; + const match = path.match(new RegExp(`/${beforeWord}/([^/]+)/${afterWord}`)); + return match?.[1] ?? ''; + } + + async extractProjectIdFromPage(beforeWord: string, afterWord: string): Promise { + return this.extractIdFromUrl(this.n8n.page.url(), beforeWord, afterWord); + } +} diff --git a/packages/testing/playwright/composables/WorkflowComposer.ts b/packages/testing/playwright/composables/WorkflowComposer.ts new file mode 100644 index 0000000000..7014ac3bfa --- /dev/null +++ b/packages/testing/playwright/composables/WorkflowComposer.ts @@ -0,0 +1,25 @@ +import type { n8nPage } from '../pages/n8nPage'; + +/** + * A class for user interactions with workflows that go across multiple pages. + */ +export class WorkflowComposer { + constructor(private readonly n8n: n8nPage) {} + + /** + * Executes a successful workflow and waits for the notification to be closed. + * This waits for http calls and also closes the notification. + */ + async executeWorkflowAndWaitForNotification(notificationMessage: string) { + const responsePromise = this.n8n.page.waitForResponse( + (response) => + response.url().includes('/rest/workflows/') && + response.url().includes('/run') && + response.request().method() === 'POST', + ); + + await this.n8n.canvas.clickExecuteWorkflowButton(); + await responsePromise; + await this.n8n.notifications.waitForNotificationAndClose(notificationMessage); + } +} diff --git a/packages/testing/playwright/config/constants.ts b/packages/testing/playwright/config/constants.ts new file mode 100644 index 0000000000..d9d715479c --- /dev/null +++ b/packages/testing/playwright/config/constants.ts @@ -0,0 +1,43 @@ +export const BACKEND_BASE_URL = 'http://localhost:5678'; +export const N8N_AUTH_COOKIE = 'n8n-auth'; + +export const DEFAULT_USER_PASSWORD = 'PlaywrightTest123'; + +export const MANUAL_TRIGGER_NODE_NAME = 'Manual Trigger'; +export const MANUAL_TRIGGER_NODE_DISPLAY_NAME = 'When clicking ‘Execute workflow’'; +export const MANUAL_CHAT_TRIGGER_NODE_NAME = 'Chat Trigger'; +export const CHAT_TRIGGER_NODE_DISPLAY_NAME = 'When chat message received'; +export const SCHEDULE_TRIGGER_NODE_NAME = 'Schedule Trigger'; +export const CODE_NODE_NAME = 'Code'; +export const SET_NODE_NAME = 'Set'; +export const EDIT_FIELDS_SET_NODE_NAME = 'Edit Fields'; +export const LOOP_OVER_ITEMS_NODE_NAME = 'Loop Over Items'; +export const IF_NODE_NAME = 'If'; +export const MERGE_NODE_NAME = 'Merge'; +export const SWITCH_NODE_NAME = 'Switch'; +export const GMAIL_NODE_NAME = 'Gmail'; +export const TRELLO_NODE_NAME = 'Trello'; +export const NOTION_NODE_NAME = 'Notion'; +export const PIPEDRIVE_NODE_NAME = 'Pipedrive'; +export const HTTP_REQUEST_NODE_NAME = 'HTTP Request'; +export const AGENT_NODE_NAME = 'AI Agent'; +export const BASIC_LLM_CHAIN_NODE_NAME = 'Basic LLM Chain'; +export const AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME = 'Simple Memory'; +export const AI_TOOL_CALCULATOR_NODE_NAME = 'Calculator'; +export const AI_TOOL_CODE_NODE_NAME = 'Code Tool'; +export const AI_TOOL_WIKIPEDIA_NODE_NAME = 'Wikipedia'; +export const AI_TOOL_HTTP_NODE_NAME = 'HTTP Request Tool'; +export const AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME = 'OpenAI Chat Model'; +export const AI_MEMORY_POSTGRES_NODE_NAME = 'Postgres Chat Memory'; +export const AI_OUTPUT_PARSER_AUTO_FIXING_NODE_NAME = 'Auto-fixing Output Parser'; +export const WEBHOOK_NODE_NAME = 'Webhook'; +export const EXECUTE_WORKFLOW_NODE_NAME = 'Execute Workflow'; + +export const NEW_GOOGLE_ACCOUNT_NAME = 'Gmail account'; +export const NEW_TRELLO_ACCOUNT_NAME = 'Trello account'; +export const NEW_NOTION_ACCOUNT_NAME = 'Notion account'; +export const NEW_QUERY_AUTH_ACCOUNT_NAME = 'Query Auth account'; + +export const ROUTES = { + NEW_WORKFLOW_PAGE: '/workflow/new', +}; diff --git a/packages/testing/playwright/config/intercepts.ts b/packages/testing/playwright/config/intercepts.ts new file mode 100644 index 0000000000..2ef1edbe6c --- /dev/null +++ b/packages/testing/playwright/config/intercepts.ts @@ -0,0 +1,105 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import type { FrontendSettings } from '@n8n/api-types'; +import type { BrowserContext, Route } from '@playwright/test'; +import cloneDeep from 'lodash/cloneDeep'; +import merge from 'lodash/merge'; + +export let settings: Partial; + +export async function setupDefaultInterceptors(target: BrowserContext) { + await target.route('**/rest/settings', async (route: Route) => { + try { + const originalResponse = await route.fetch(); + const originalJson = await originalResponse.json(); + + const modifiedData = { + data: merge(cloneDeep(originalJson.data), settings), + }; + + await route.fulfill({ + status: originalResponse.status(), + headers: originalResponse.headers(), + contentType: 'application/json', + body: JSON.stringify(modifiedData), + }); + } catch (error) { + console.error('Error in /rest/settings intercept:', error); + await route.continue(); + } + }); + + // POST /rest/credentials/test + await target.route('**/rest/credentials/test', async (route: Route) => { + if (route.request().method() === 'POST') { + await route.fulfill({ + contentType: 'application/json', + body: JSON.stringify({ data: { status: 'success', message: 'Tested successfully' } }), + }); + } else { + await route.continue(); + } + }); + + // POST /rest/license/renew + await target.route('**/rest/license/renew', async (route: Route) => { + if (route.request().method() === 'POST') { + await route.fulfill({ + contentType: 'application/json', + body: JSON.stringify({ + data: { + usage: { activeWorkflowTriggers: { limit: -1, value: 0, warningThreshold: 0.8 } }, + license: { planId: '', planName: 'Community' }, + }, + }), + }); + } else { + await route.continue(); + } + }); + + // Pathname /api/health + await target.route( + (url) => url.pathname.endsWith('/api/health'), + async (route: Route) => { + await route.fulfill({ + contentType: 'application/json', + body: JSON.stringify({ status: 'OK' }), + }); + }, + ); + + // Pathname /api/versions/* + await target.route( + (url) => url.pathname.startsWith('/api/versions/'), + async (route: Route) => { + await route.fulfill({ + contentType: 'application/json', + body: JSON.stringify([ + { + name: '1.45.1', + createdAt: '2023-08-18T11:53:12.857Z', + hasSecurityIssue: null, + hasSecurityFix: null, + securityIssueFixVersion: null, + hasBreakingChange: null, + documentationUrl: 'https://docs.n8n.io/release-notes/#n8n131', + nodes: [], + description: 'Includes bug fixes', + }, + { + name: '1.0.5', + createdAt: '2023-07-24T10:54:56.097Z', + hasSecurityIssue: false, + hasSecurityFix: null, + securityIssueFixVersion: null, + hasBreakingChange: true, + documentationUrl: 'https://docs.n8n.io/release-notes/#n8n104', + nodes: [], + description: + 'Includes core functionality and bug fixes', + }, + ]), + }); + }, + ); +} diff --git a/packages/testing/playwright/config/test-users.ts b/packages/testing/playwright/config/test-users.ts new file mode 100644 index 0000000000..97c79b923b --- /dev/null +++ b/packages/testing/playwright/config/test-users.ts @@ -0,0 +1,77 @@ +import { DEFAULT_USER_PASSWORD } from './constants'; + +export interface UserCredentials { + email: string; + password: string; + firstName: string; + lastName: string; +} + +// Simple name generators +const FIRST_NAMES = [ + 'Alex', + 'Jordan', + 'Taylor', + 'Morgan', + 'Casey', + 'Riley', + 'Avery', + 'Quinn', + 'Sam', + 'Drew', + 'Blake', + 'Sage', + 'River', + 'Rowan', + 'Skylar', + 'Emery', +]; + +const LAST_NAMES = [ + 'Smith', + 'Johnson', + 'Williams', + 'Brown', + 'Jones', + 'Garcia', + 'Miller', + 'Davis', + 'Rodriguez', + 'Martinez', + 'Hernandez', + 'Lopez', + 'Gonzalez', + 'Wilson', + 'Anderson', + 'Thomas', +]; + +const getRandomName = (names: string[]): string => { + return names[Math.floor(Math.random() * names.length)]; +}; + +const randFirstName = (): string => getRandomName(FIRST_NAMES); +const randLastName = (): string => getRandomName(LAST_NAMES); + +export const INSTANCE_OWNER_CREDENTIALS: UserCredentials = { + email: 'nathan@n8n.io', + password: DEFAULT_USER_PASSWORD, + firstName: randFirstName(), + lastName: randLastName(), +}; + +export const INSTANCE_ADMIN_CREDENTIALS: UserCredentials = { + email: 'admin@n8n.io', + password: DEFAULT_USER_PASSWORD, + firstName: randFirstName(), + lastName: randLastName(), +}; + +export const INSTANCE_MEMBER_CREDENTIALS: UserCredentials[] = [ + { + email: 'member@n8n.io', + password: DEFAULT_USER_PASSWORD, + firstName: randFirstName(), + lastName: randLastName(), + }, +]; diff --git a/packages/testing/playwright/currents.config.ts b/packages/testing/playwright/currents.config.ts new file mode 100644 index 0000000000..503b494364 --- /dev/null +++ b/packages/testing/playwright/currents.config.ts @@ -0,0 +1,6 @@ +import type { CurrentsConfig } from '@currents/playwright'; + +export const config: CurrentsConfig = { + recordKey: process.env.CURRENTS_RECORD_KEY ?? '', + projectId: process.env.CURRENTS_PROJECT_ID ?? 'I0yzoc', +}; diff --git a/packages/testing/playwright/fixtures/base.ts b/packages/testing/playwright/fixtures/base.ts new file mode 100644 index 0000000000..deb2a6e20b --- /dev/null +++ b/packages/testing/playwright/fixtures/base.ts @@ -0,0 +1,149 @@ +import { test as base, expect, type TestInfo } from '@playwright/test'; +import type { N8NStack } from 'n8n-containers/n8n-test-container-creation'; +import { createN8NStack } from 'n8n-containers/n8n-test-container-creation'; +import { ContainerTestHelpers } from 'n8n-containers/n8n-test-container-helpers'; + +import { setupDefaultInterceptors } from '../config/intercepts'; +import { n8nPage } from '../pages/n8nPage'; +import { ApiHelpers } from '../services/api-helper'; +import { TestError } from '../Types'; + +type TestFixtures = { + n8n: n8nPage; + api: ApiHelpers; + baseURL: string; +}; + +type WorkerFixtures = { + n8nUrl: string; + dbSetup: undefined; + chaos: ContainerTestHelpers; + n8nContainer: N8NStack; + containerConfig: ContainerConfig; // Configuration for container creation +}; + +interface ContainerConfig { + postgres?: boolean; + queueMode?: { + mains: number; + workers: number; + }; +} + +/** + * Extended Playwright test with n8n-specific fixtures. + * Supports both external n8n instances (via N8N_BASE_URL) and containerized testing. + * Provides tag-driven authentication and database management. + */ +export const test = base.extend({ + // Container configuration from the project use options + containerConfig: [ + async ({}, use, testInfo: TestInfo) => { + const config = (testInfo.project.use?.containerConfig as ContainerConfig) || {}; + await use(config); + }, + { scope: 'worker' }, + ], + + // Create a new n8n container if N8N_BASE_URL is not set, otherwise use the existing n8n instance + n8nContainer: [ + async ({ containerConfig }, use) => { + const envBaseURL = process.env.N8N_BASE_URL; + + if (envBaseURL) { + console.log(`Using external N8N_BASE_URL: ${envBaseURL}`); + await use(null as unknown as N8NStack); + return; + } + + console.log('Creating container with config:', containerConfig); + const container = await createN8NStack(containerConfig); + + // TODO: Remove this once we have a better way to wait for the container to be ready (e.g. healthcheck) + await new Promise((resolve) => setTimeout(resolve, 5000)); + + console.log(`Container URL: ${container.baseUrl}`); + + await use(container); + await container.stop(); + }, + { scope: 'worker' }, + ], + + // Set the n8n URL for based on the N8N_BASE_URL environment variable or the n8n container + n8nUrl: [ + async ({ n8nContainer }, use) => { + const envBaseURL = process.env.N8N_BASE_URL ?? n8nContainer?.baseUrl; + await use(envBaseURL); + }, + { scope: 'worker' }, + ], + + // Reset the database for the new container + dbSetup: [ + async ({ n8nUrl, n8nContainer, browser }, use) => { + if (n8nContainer) { + console.log('Resetting database for new container'); + const context = await browser.newContext({ baseURL: n8nUrl }); + const api = new ApiHelpers(context.request); + await api.resetDatabase(); + await context.close(); + } + await use(undefined); + }, + { scope: 'worker' }, + ], + + // Create container test helpers for the n8n container. + chaos: [ + async ({ n8nContainer }, use) => { + if (process.env.N8N_BASE_URL) { + throw new TestError( + 'Chaos testing is not supported when using N8N_BASE_URL environment variable. Remove N8N_BASE_URL to use containerized testing.', + ); + } + const helpers = new ContainerTestHelpers(n8nContainer.containers); + await use(helpers); + }, + { scope: 'worker' }, + ], + + baseURL: async ({ n8nUrl }, use) => { + await use(n8nUrl); + }, + + // Browser, baseURL, and dbSetup are required here to ensure they run first. + // This is how Playwright does dependency graphs + context: async ({ context, browser, baseURL, dbSetup }, use) => { + await setupDefaultInterceptors(context); + await use(context); + }, + + page: async ({ context }, use, testInfo) => { + const page = await context.newPage(); + const api = new ApiHelpers(context.request); + + await api.setupFromTags(testInfo.tags); + + await use(page); + await page.close(); + }, + + n8n: async ({ page }, use) => { + const n8nInstance = new n8nPage(page); + await use(n8nInstance); + }, + + api: async ({ context }, use) => { + const api = new ApiHelpers(context.request); + await use(api); + }, +}); + +export { expect }; + +/* +Dependency Graph: +Worker Scope: containerConfig → n8nContainer → [n8nUrl, chaos] → dbSetup +Test Scope: n8nUrl → baseURL → context → page → [n8n, api] +*/ diff --git a/packages/testing/playwright/global-setup.ts b/packages/testing/playwright/global-setup.ts new file mode 100644 index 0000000000..fb0f7dae69 --- /dev/null +++ b/packages/testing/playwright/global-setup.ts @@ -0,0 +1,43 @@ +import { request } from '@playwright/test'; + +import { ApiHelpers } from './services/api-helper'; + +async function globalSetup() { + console.log('🚀 Starting global setup...'); + + // Check if N8N_BASE_URL is set + const n8nBaseUrl = process.env.N8N_BASE_URL; + if (!n8nBaseUrl) { + console.log('⚠️ N8N_BASE_URL environment variable is not set, skipping database reset'); + return; + } + + const resetE2eDb = process.env.RESET_E2E_DB; + if (resetE2eDb !== 'true') { + console.log('⚠️ RESET_E2E_DB is not set to "true", skipping database reset'); + return; + } + + console.log(`🔄 Resetting database for ${n8nBaseUrl}...`); + + // Create standalone API request context + const requestContext = await request.newContext({ + baseURL: n8nBaseUrl, + }); + + try { + const api = new ApiHelpers(requestContext); + await api.resetDatabase(); + console.log('✅ Database reset completed successfully'); + } catch (error) { + console.error('❌ Failed to reset database:', error); + throw error; // This will fail the entire test suite if database reset fails + } finally { + await requestContext.dispose(); + } + + console.log('🏁 Global setup completed'); +} + +// eslint-disable-next-line import/no-default-export +export default globalSetup; diff --git a/packages/testing/playwright/package.json b/packages/testing/playwright/package.json new file mode 100644 index 0000000000..6decb508b5 --- /dev/null +++ b/packages/testing/playwright/package.json @@ -0,0 +1,23 @@ +{ + "name": "n8n-playwright", + "private": true, + "scripts": { + "test": "playwright test", + "test:local:reset": "N8N_BASE_URL=http://localhost:5678 RESET_E2E_DB=true playwright test --workers=4", + "test:local": "N8N_BASE_URL=http://localhost:5678 playwright test", + "test:standard": "playwright test --project=mode:standard*", + "test:postgres": "playwright test --project=mode:postgres*", + "test:queue": "playwright test --project=mode:queue*", + "test:multi-main": "playwright test --project=mode:multi-main*", + "test:clean": "docker rm -f $(docker ps -aq --filter 'name=n8n-*') 2>/dev/null || true && docker network prune -f", + "lint": "eslint . --quiet", + "lintfix": "eslint . --fix", + "install-browsers": "PLAYWRIGHT_BROWSERS_PATH=./ms-playwright-cache playwright install chromium --with-deps" + }, + "devDependencies": { + "@currents/playwright": "1.14.1", + "@playwright/test": "1.53.0", + "eslint-plugin-playwright": "2.2.0", + "n8n-containers": "workspace:*" + } +} diff --git a/packages/testing/playwright/pages/BasePage.ts b/packages/testing/playwright/pages/BasePage.ts new file mode 100644 index 0000000000..f81720c5f1 --- /dev/null +++ b/packages/testing/playwright/pages/BasePage.ts @@ -0,0 +1,21 @@ +import type { Page } from '@playwright/test'; + +export abstract class BasePage { + constructor(protected readonly page: Page) {} + + protected async clickByTestId(testId: string) { + await this.page.getByTestId(testId).click(); + } + + protected async fillByTestId(testId: string, value: string) { + await this.page.getByTestId(testId).fill(value); + } + + protected async clickByText(text: string) { + await this.page.getByText(text).click(); + } + + protected async clickButtonByName(name: string) { + await this.page.getByRole('button', { name }).click(); + } +} diff --git a/packages/testing/playwright/pages/CanvasPage.ts b/packages/testing/playwright/pages/CanvasPage.ts new file mode 100644 index 0000000000..500eb42c21 --- /dev/null +++ b/packages/testing/playwright/pages/CanvasPage.ts @@ -0,0 +1,117 @@ +import type { Locator } from '@playwright/test'; + +import { BasePage } from './BasePage'; + +export class CanvasPage extends BasePage { + saveWorkflowButton(): Locator { + return this.page.getByRole('button', { name: 'Save' }); + } + + nodeCreatorItemByName(text: string): Locator { + return this.page.getByTestId('node-creator-item-name').getByText(text, { exact: true }); + } + + nodeCreatorSubItem(subItemText: string): Locator { + return this.page.getByTestId('node-creator-item-name').getByText(subItemText, { exact: true }); + } + + nodeByName(nodeName: string): Locator { + return this.page.locator(`[data-test-id="canvas-node"][data-node-name="${nodeName}"]`); + } + + nodeToolbar(nodeName: string): Locator { + return this.nodeByName(nodeName).getByTestId('canvas-node-toolbar'); + } + + nodeDeleteButton(nodeName: string): Locator { + return this.nodeToolbar(nodeName).getByTestId('delete-node-button'); + } + + async clickCanvasPlusButton(): Promise { + await this.clickByTestId('canvas-plus-button'); + } + + async clickNodeCreatorPlusButton(): Promise { + await this.clickByTestId('node-creator-plus-button'); + } + + async clickSaveWorkflowButton(): Promise { + await this.clickButtonByName('Save'); + } + + async fillNodeCreatorSearchBar(text: string): Promise { + await this.fillByTestId('node-creator-search-bar', text); + } + + async clickNodeCreatorItemName(text: string): Promise { + await this.nodeCreatorItemByName(text).click(); + } + + async addNode(text: string): Promise { + await this.clickNodeCreatorPlusButton(); + await this.fillNodeCreatorSearchBar(text); + await this.clickNodeCreatorItemName(text); + } + + async addNodeToCanvasWithSubItem(searchText: string, subItemText: string): Promise { + await this.addNode(searchText); + await this.nodeCreatorSubItem(subItemText).click(); + } + + async deleteNodeByName(nodeName: string): Promise { + await this.nodeDeleteButton(nodeName).click(); + } + + async saveWorkflow(): Promise { + await this.clickSaveWorkflowButton(); + } + + async clickExecuteWorkflowButton(): Promise { + await this.page.getByTestId('execute-workflow-button').click(); + } + + async clickDebugInEditorButton(): Promise { + await this.page.getByRole('button', { name: 'Debug in editor' }).click(); + } + + async pinNodeByNameUsingContextMenu(nodeName: string): Promise { + await this.nodeByName(nodeName).click({ button: 'right' }); + await this.page.getByTestId('context-menu').getByText('Pin').click(); + } + + async unpinNodeByNameUsingContextMenu(nodeName: string): Promise { + await this.nodeByName(nodeName).click({ button: 'right' }); + await this.page.getByText('Unpin').click(); + } + + async openNode(nodeName: string): Promise { + await this.nodeByName(nodeName).dblclick(); + } + + /** + * Get the names of all pinned nodes on the canvas. + * @returns An array of node names. + */ + async getPinnedNodeNames(): Promise { + const pinnedNodesLocator = this.page + .getByTestId('canvas-node') + .filter({ has: this.page.getByTestId('canvas-node-status-pinned') }); + + const names: string[] = []; + const count = await pinnedNodesLocator.count(); + + for (let i = 0; i < count; i++) { + const node = pinnedNodesLocator.nth(i); + const name = await node.getAttribute('data-node-name'); + if (name) { + names.push(name); + } + } + + return names; + } + + async clickExecutionsTab(): Promise { + await this.page.getByRole('radio', { name: 'Executions' }).click(); + } +} diff --git a/packages/testing/playwright/pages/CredentialsPage.ts b/packages/testing/playwright/pages/CredentialsPage.ts new file mode 100644 index 0000000000..045bb9e900 --- /dev/null +++ b/packages/testing/playwright/pages/CredentialsPage.ts @@ -0,0 +1,65 @@ +import { BasePage } from './BasePage'; + +export class CredentialsPage extends BasePage { + get emptyListCreateCredentialButton() { + return this.page.getByRole('button', { name: 'Add first credential' }); + } + + get createCredentialButton() { + return this.page.getByTestId('create-credential-button'); + } + + get credentialCards() { + return this.page.getByTestId('credential-cards'); + } + + /** + * Create a new credential of the specified type + * @param credentialType - The type of credential to create (e.g. 'Notion API') + */ + async openNewCredentialDialogFromCredentialList(credentialType: string): Promise { + await this.page.getByRole('combobox', { name: 'Search for app...' }).fill(credentialType); + await this.page + .getByTestId('new-credential-type-select-option') + .filter({ hasText: credentialType }) + .click(); + await this.page.getByTestId('new-credential-type-button').click(); + } + + async openCredentialSelector() { + await this.page.getByRole('combobox', { name: 'Select Credential' }).click(); + } + + async createNewCredential() { + await this.clickByText('Create new credential'); + } + + async fillCredentialField(fieldName: string, value: string) { + const field = this.page + .getByTestId(`parameter-input-${fieldName}`) + .getByTestId('parameter-input-field'); + await field.click(); + await field.fill(value); + } + + async saveCredential() { + await this.clickButtonByName('Save'); + } + + async closeCredentialDialog() { + await this.clickButtonByName('Close this dialog'); + } + + async createAndSaveNewCredential(fieldName: string, value: string) { + await this.openCredentialSelector(); + await this.createNewCredential(); + await this.filLCredentialSaveClose(fieldName, value); + } + + async filLCredentialSaveClose(fieldName: string, value: string) { + await this.fillCredentialField(fieldName, value); + await this.saveCredential(); + await this.page.getByText('Connection tested successfully').waitFor({ state: 'visible' }); + await this.closeCredentialDialog(); + } +} diff --git a/packages/testing/playwright/pages/ExecutionsPage.ts b/packages/testing/playwright/pages/ExecutionsPage.ts new file mode 100644 index 0000000000..4ece9676ad --- /dev/null +++ b/packages/testing/playwright/pages/ExecutionsPage.ts @@ -0,0 +1,36 @@ +import type { Locator } from '@playwright/test'; + +import { BasePage } from './BasePage'; + +export class ExecutionsPage extends BasePage { + async clickDebugInEditorButton(): Promise { + await this.clickButtonByName('Debug in editor'); + } + + async clickCopyToEditorButton(): Promise { + await this.clickButtonByName('Copy to editor'); + } + + async getExecutionItems(): Promise { + return this.page.locator('div.execution-card'); + } + + async getLastExecutionItem(): Promise { + const executionItems = await this.getExecutionItems(); + return executionItems.nth(0); + } + + async clickLastExecutionItem(): Promise { + const executionItem = await this.getLastExecutionItem(); + await executionItem.click(); + } + + /** + * Handle the pinned nodes confirmation dialog. + * @param action - The action to take. + */ + async handlePinnedNodesConfirmation(action: 'Unpin' | 'Cancel'): Promise { + const confirmDialog = this.page.locator('.matching-pinned-nodes-confirmation'); + await this.page.getByRole('button', { name: action }).click(); + } +} diff --git a/packages/testing/playwright/pages/NodeDisplayViewPage.ts b/packages/testing/playwright/pages/NodeDisplayViewPage.ts new file mode 100644 index 0000000000..efe02c4a15 --- /dev/null +++ b/packages/testing/playwright/pages/NodeDisplayViewPage.ts @@ -0,0 +1,38 @@ +import { BasePage } from './BasePage'; + +export class NodeDisplayViewPage extends BasePage { + async clickBackToCanvasButton() { + await this.clickByTestId('back-to-canvas'); + } + + getParameterByLabel(labelName: string) { + return this.page.locator('.parameter-item').filter({ hasText: labelName }); + } + + /** + * Fill a parameter input field + * @param labelName - The label of the parameter e.g URL + * @param value - The value to fill in the input field e.g https://foo.bar + */ + async fillParameterInput(labelName: string, value: string) { + await this.getParameterByLabel(labelName).getByTestId('parameter-input-field').fill(value); + } + + async selectWorkflowResource(createItemText: string, searchText: string = '') { + await this.clickByTestId('rlc-input'); + + if (searchText) { + await this.fillByTestId('rlc-search', searchText); + } + + await this.clickByText(createItemText); + } + + async togglePinData() { + await this.clickByTestId('ndv-pin-data'); + } + + async close() { + await this.clickBackToCanvasButton(); + } +} diff --git a/packages/testing/playwright/pages/NotificationsPage.ts b/packages/testing/playwright/pages/NotificationsPage.ts new file mode 100644 index 0000000000..ecac374778 --- /dev/null +++ b/packages/testing/playwright/pages/NotificationsPage.ts @@ -0,0 +1,234 @@ +import type { Locator, Page } from '@playwright/test'; + +export class NotificationsPage { + readonly page: Page; + + constructor(page: Page) { + this.page = page; + } + + /** + * Gets the main container locator for a notification by its visible text. + * @param text The text or a regular expression to find within the notification's title. + * @returns A Locator for the notification container element. + */ + notificationContainerByText(text: string | RegExp): Locator { + return this.page.getByRole('alert').filter({ + has: this.page.locator('.el-notification__title').filter({ hasText: text }), + }); + } + + /** + * Clicks the close button on the FIRST notification matching the text. + * Fast execution with short timeouts for snappy notifications. + * @param text The text of the notification to close. + * @param options Optional configuration + */ + async closeNotificationByText( + text: string | RegExp, + options: { timeout?: number } = {}, + ): Promise { + const { timeout = 2000 } = options; + + try { + const notification = this.notificationContainerByText(text).first(); + await notification.waitFor({ state: 'visible', timeout }); + + const closeBtn = notification.locator('.el-notification__closeBtn'); + await closeBtn.click({ timeout: 500 }); + + // Quick check that it's gone - don't wait long + await notification.waitFor({ state: 'hidden', timeout: 1000 }); + return true; + } catch (error) { + return false; + } + } + + /** + * Closes ALL currently visible notifications that match the given text. + * Uses aggressive polling for fast cleanup. + * @param text The text of the notifications to close. + * @param options Optional configuration + */ + async closeAllNotificationsWithText( + text: string | RegExp, + options: { timeout?: number; maxRetries?: number } = {}, + ): Promise { + const { timeout = 1500, maxRetries = 15 } = options; + let closedCount = 0; + let retries = 0; + + while (retries < maxRetries) { + try { + const notifications = this.notificationContainerByText(text); + const count = await notifications.count(); + + if (count === 0) { + break; + } + + // Close the first visible notification quickly + const firstNotification = notifications.first(); + if (await firstNotification.isVisible({ timeout: 200 })) { + const closeBtn = firstNotification.locator('.el-notification__closeBtn'); + await closeBtn.click({ timeout: 300 }); + + // Brief wait for disappearance, then continue + await firstNotification.waitFor({ state: 'hidden', timeout: 500 }).catch(() => {}); + closedCount++; + } else { + // If not visible, likely already gone + break; + } + } catch (error) { + // Continue quickly on any error + break; + } + + retries++; + } + + return closedCount; + } + + /** + * Check if a notification is visible based on text. + * Fast check with short timeout. + * @param text The text to search for in notification title. + * @param options Optional configuration + */ + async isNotificationVisible( + text: string | RegExp, + options: { timeout?: number } = {}, + ): Promise { + const { timeout = 500 } = options; + + try { + const notification = this.notificationContainerByText(text).first(); + await notification.waitFor({ state: 'visible', timeout }); + return true; + } catch { + return false; + } + } + + /** + * Wait for a notification to appear with specific text. + * Reasonable timeout for waiting, but still faster than before. + * @param text The text to search for in notification title. + * @param options Optional configuration + */ + async waitForNotification( + text: string | RegExp, + options: { timeout?: number } = {}, + ): Promise { + const { timeout = 5000 } = options; + + try { + const notification = this.notificationContainerByText(text).first(); + await notification.waitFor({ state: 'visible', timeout }); + return true; + } catch { + return false; + } + } + + // Wait for notification and then close it + async waitForNotificationAndClose( + text: string | RegExp, + options: { timeout?: number } = {}, + ): Promise { + const { timeout = 3000 } = options; + await this.waitForNotification(text, { timeout }); + await this.closeNotificationByText(text, { timeout }); + return true; + } + + /** + * Get all visible notification texts. + * @returns Array of notification title texts + */ + async getAllNotificationTexts(): Promise { + try { + const titles = this.page.getByRole('alert').locator('.el-notification__title'); + return await titles.allTextContents(); + } catch { + return []; + } + } + + /** + * Wait for all notifications to disappear. + * Fast check with short timeout. + * @param options Optional configuration + */ + async waitForAllNotificationsToDisappear(options: { timeout?: number } = {}): Promise { + const { timeout = 2000 } = options; + + try { + // Wait for no alerts to be visible + await this.page.getByRole('alert').first().waitFor({ + state: 'detached', + timeout, + }); + return true; + } catch { + // Check if any are still visible + const count = await this.getNotificationCount(); + return count === 0; + } + } + + /** + * Get the count of visible notifications. + * @param text Optional text to filter notifications + */ + async getNotificationCount(text?: string | RegExp): Promise { + try { + const notifications = text + ? this.notificationContainerByText(text) + : this.page.getByRole('alert'); + return await notifications.count(); + } catch { + return 0; + } + } + + /** + * Quick utility to close any notification and continue. + * Uses the most aggressive timeouts for maximum speed. + * @param text The text of the notification to close. + */ + async quickClose(text: string | RegExp): Promise { + try { + const notification = this.notificationContainerByText(text).first(); + if (await notification.isVisible({ timeout: 100 })) { + await notification.locator('.el-notification__closeBtn').click({ timeout: 200 }); + } + } catch { + // Silent fail for speed + } + } + + /** + * Nuclear option: Close everything as fast as possible. + * No waiting, no error handling, just close and move on. + */ + async quickCloseAll(): Promise { + try { + const closeButtons = this.page.locator('.el-notification__closeBtn'); + const count = await closeButtons.count(); + + for (let i = 0; i < count; i++) { + try { + await closeButtons.nth(i).click({ timeout: 100 }); + } catch { + // Continue silently + } + } + } catch { + // Silent fail + } + } +} diff --git a/packages/testing/playwright/pages/ProjectSettingsPage.ts b/packages/testing/playwright/pages/ProjectSettingsPage.ts new file mode 100644 index 0000000000..81885b5382 --- /dev/null +++ b/packages/testing/playwright/pages/ProjectSettingsPage.ts @@ -0,0 +1,11 @@ +import { BasePage } from './BasePage'; + +export class ProjectSettingsPage extends BasePage { + async fillProjectName(name: string) { + await this.page.getByTestId('project-settings-name-input').locator('input').fill(name); + } + + async clickSaveButton() { + await this.clickButtonByName('Save'); + } +} diff --git a/packages/testing/playwright/pages/ProjectWorkflowsPage.ts b/packages/testing/playwright/pages/ProjectWorkflowsPage.ts new file mode 100644 index 0000000000..ba08dc021a --- /dev/null +++ b/packages/testing/playwright/pages/ProjectWorkflowsPage.ts @@ -0,0 +1,11 @@ +import { BasePage } from './BasePage'; + +export class ProjectWorkflowsPage extends BasePage { + async clickCreateWorkflowButton() { + await this.clickByTestId('add-resource-workflow'); + } + + async clickProjectMenuItem(projectName: string) { + await this.page.getByTestId('project-menu-item').filter({ hasText: projectName }).click(); + } +} diff --git a/packages/testing/playwright/pages/SidebarPage.ts b/packages/testing/playwright/pages/SidebarPage.ts new file mode 100644 index 0000000000..d466e75487 --- /dev/null +++ b/packages/testing/playwright/pages/SidebarPage.ts @@ -0,0 +1,42 @@ +import type { Locator, Page } from '@playwright/test'; + +export class SidebarPage { + readonly page: Page; + + constructor(page: Page) { + this.page = page; + } + + async clickAddProjectButton() { + await this.page.getByTestId('project-plus-button').click(); + } + + async universalAdd() { + await this.page.getByTestId('universal-add').click(); + } + + async addProjectFromUniversalAdd() { + await this.universalAdd(); + await this.page.getByTestId('navigation-menu-item').filter({ hasText: 'Project' }).click(); + } + + async addWorkflowFromUniversalAdd(projectName: string) { + await this.universalAdd(); + await this.page.getByTestId('universal-add').getByText('Workflow').click(); + await this.page.getByTestId('universal-add').getByRole('link', { name: projectName }).click(); + } + + async openNewCredentialDialogForProject(projectName: string) { + await this.universalAdd(); + await this.page.getByTestId('universal-add').getByText('Credential').click(); + await this.page.getByTestId('universal-add').getByRole('link', { name: projectName }).click(); + } + + getProjectMenuItems(): Locator { + return this.page.getByTestId('project-menu-item'); + } + + getAddFirstProjectButton(): Locator { + return this.page.getByTestId('add-first-project-button'); + } +} diff --git a/packages/testing/playwright/pages/WorkflowsPage.ts b/packages/testing/playwright/pages/WorkflowsPage.ts new file mode 100644 index 0000000000..95de8b18f9 --- /dev/null +++ b/packages/testing/playwright/pages/WorkflowsPage.ts @@ -0,0 +1,45 @@ +import { BasePage } from './BasePage'; +import { resolveFromRoot } from '../utils/path-helper'; + +export class WorkflowsPage extends BasePage { + async clickNewWorkflowCard() { + await this.clickByTestId('new-workflow-card'); + } + + async clickAddFirstProjectButton() { + await this.clickByTestId('add-first-project-button'); + } + + async clickAddProjectButton() { + await this.clickByTestId('project-plus-button'); + } + + async clickAddWorklowButton() { + await this.clickByTestId('add-resource-workflow'); + } + + /** + * Import a workflow from a fixture file + * @param fixtureKey - The key of the fixture file to import + * @param workflowName - The name of the workflow to import + * Naming the file causes the workflow to save so we don't need to click save + */ + async importWorkflow(fixtureKey: string, workflowName: string) { + await this.clickByTestId('workflow-menu'); + + const [fileChooser] = await Promise.all([ + this.page.waitForEvent('filechooser'), + this.clickByText('Import from File...'), + ]); + await fileChooser.setFiles(resolveFromRoot('workflows', fixtureKey)); + await this.page.waitForTimeout(250); + + await this.clickByTestId('inline-edit-preview'); + await this.fillByTestId('inline-edit-input', workflowName); + await this.page.getByTestId('inline-edit-input').press('Enter'); + } + + workflowTags() { + return this.page.getByTestId('workflow-tags').locator('.el-tag'); + } +} diff --git a/packages/testing/playwright/pages/n8nPage.ts b/packages/testing/playwright/pages/n8nPage.ts new file mode 100644 index 0000000000..c758cf6aa8 --- /dev/null +++ b/packages/testing/playwright/pages/n8nPage.ts @@ -0,0 +1,68 @@ +import type { Page } from '@playwright/test'; + +import { CanvasPage } from './CanvasPage'; +import { CredentialsPage } from './CredentialsPage'; +import { ExecutionsPage } from './ExecutionsPage'; +import { NodeDisplayViewPage } from './NodeDisplayViewPage'; +import { NotificationsPage } from './NotificationsPage'; +import { ProjectSettingsPage } from './ProjectSettingsPage'; +import { ProjectWorkflowsPage } from './ProjectWorkflowsPage'; +import { SidebarPage } from './SidebarPage'; +import { WorkflowsPage } from './WorkflowsPage'; +import { CanvasComposer } from '../composables/CanvasComposer'; +import { ProjectComposer } from '../composables/ProjectComposer'; +import { WorkflowComposer } from '../composables/WorkflowComposer'; + +export class n8nPage { + readonly page: Page; + + // Pages + readonly canvas: CanvasPage; + + readonly ndv: NodeDisplayViewPage; + + readonly projectWorkflows: ProjectWorkflowsPage; + + readonly projectSettings: ProjectSettingsPage; + + readonly workflows: WorkflowsPage; + + readonly notifications: NotificationsPage; + + readonly credentials: CredentialsPage; + + readonly executions: ExecutionsPage; + + readonly sideBar: SidebarPage; + + // Composables + readonly workflowComposer: WorkflowComposer; + + readonly projectComposer: ProjectComposer; + + readonly canvasComposer: CanvasComposer; + + constructor(page: Page) { + this.page = page; + + // Pages + this.canvas = new CanvasPage(page); + this.ndv = new NodeDisplayViewPage(page); + this.projectWorkflows = new ProjectWorkflowsPage(page); + this.projectSettings = new ProjectSettingsPage(page); + this.workflows = new WorkflowsPage(page); + this.notifications = new NotificationsPage(page); + this.credentials = new CredentialsPage(page); + this.executions = new ExecutionsPage(page); + this.sideBar = new SidebarPage(page); + + // Composables + this.workflowComposer = new WorkflowComposer(this); + this.projectComposer = new ProjectComposer(this); + this.canvasComposer = new CanvasComposer(this); + } + + async goHome() { + await this.page.goto('/'); + } +} diff --git a/packages/testing/playwright/playwright.config.ts b/packages/testing/playwright/playwright.config.ts new file mode 100644 index 0000000000..6ea07f2b4a --- /dev/null +++ b/packages/testing/playwright/playwright.config.ts @@ -0,0 +1,127 @@ +/* eslint-disable import/no-default-export */ +import type { Project } from '@playwright/test'; +import { defineConfig } from '@playwright/test'; + +/* + * Mode-based Test Configuration + * + * Usage examples: + * + * 1. Run only mode:standard tests: + * npx playwright test --project="mode:standard*" + * + * 2. Run only parallel tests for all modes: + * npx playwright test --project="*Parallel" + * + * 3. Run a specific mode's sequential tests: + * npx playwright test --project="mode:multi-main - Sequential" + * + * Test tagging examples: + * + * // Runs on all modes + * test('basic functionality', async ({ page }) => { ... }); + * + * // Only runs on multi-main mode + * test('multi-main specific @mode:multi-main', async ({ page }) => { ... }); + * + * // Only runs on postgres mode, and in sequential execution + * test('database reset test @mode:postgres @db:reset', async ({ page }) => { ... }); + * + * // Runs on all modes, but in sequential execution + * test('another reset test @db:reset', async ({ page }) => { ... }); + */ + +// Container configurations +const containerConfigs = [ + { name: 'mode:standard', config: {} }, + { name: 'mode:postgres', config: { postgres: true } }, + { name: 'mode:queue', config: { queueMode: { mains: 1, workers: 1 } } }, + { name: 'mode:multi-main', config: { queueMode: { mains: 2, workers: 1 } } }, +]; + +// Parallel tests can run fully parallel on a worker +// Sequential tests can run on a single worker, since the need a DB reset +// Chaos tests can run on a single worker, since they can destroy containers etc, these need to be isolate from DB tests since they are destructive +function createProjectTrio(name: string, containerConfig: any): Project[] { + const modeTag = `@${name}`; + + // Parse custom env vars from command line + const customEnv = process.env.N8N_TEST_ENV ? JSON.parse(process.env.N8N_TEST_ENV) : {}; + + // Merge custom env vars into container config + const mergedConfig = { + ...containerConfig, + env: { + ...containerConfig.env, + ...customEnv, + }, + }; + + // Only add dependencies when using external URL (i.e., using containers) + // This is to stop DB reset tests from running in parallel with other tests when more than 1 worker is used + const shouldAddDependencies = process.env.N8N_BASE_URL; + + return [ + { + name: `${name} - Parallel`, + grep: new RegExp( + `${modeTag}(?!.*(@db:reset|@chaostest))|^(?!.*(@mode:|@db:reset|@chaostest))`, + ), + fullyParallel: true, + use: { containerConfig: mergedConfig } as any, + }, + { + name: `${name} - Sequential`, + grep: new RegExp(`${modeTag}.*@db:reset|@db:reset(?!.*@mode:)`), + fullyParallel: false, + workers: 1, + ...(shouldAddDependencies && { dependencies: [`${name} - Parallel`] }), + use: { containerConfig: mergedConfig } as any, + }, + { + name: `${name} - Chaos`, + grep: new RegExp(`${modeTag}.*@chaostest`), + fullyParallel: false, + workers: 1, + use: { containerConfig: mergedConfig } as any, + timeout: 120000, + }, + ]; +} + +export default defineConfig({ + globalSetup: './global-setup.ts', + testDir: './tests', + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 2 : 8, + timeout: 60000, + + reporter: process.env.CI + ? [ + ['list'], + ['github'], + ['junit', { outputFile: process.env.PLAYWRIGHT_JUNIT_OUTPUT_NAME ?? 'results.xml' }], + ['html', { open: 'never' }], + ['json', { outputFile: 'test-results.json' }], + ['blob'], + ] + : [['html']], + + use: { + trace: 'on', + video: 'on', + screenshot: 'on', + testIdAttribute: 'data-test-id', + headless: true, + viewport: { width: 1536, height: 960 }, + actionTimeout: 10000, + navigationTimeout: 10000, + }, + + projects: process.env.N8N_BASE_URL + ? containerConfigs + .filter(({ name }) => name === 'mode:standard') + .flatMap(({ name, config }) => createProjectTrio(name, config)) + : containerConfigs.flatMap(({ name, config }) => createProjectTrio(name, config)), +}); diff --git a/packages/testing/playwright/services/api-helper.ts b/packages/testing/playwright/services/api-helper.ts new file mode 100644 index 0000000000..50fd6530aa --- /dev/null +++ b/packages/testing/playwright/services/api-helper.ts @@ -0,0 +1,238 @@ +// services/api-helper.ts +import type { APIRequestContext } from '@playwright/test'; + +import type { UserCredentials } from '../config/test-users'; +import { + INSTANCE_OWNER_CREDENTIALS, + INSTANCE_MEMBER_CREDENTIALS, + INSTANCE_ADMIN_CREDENTIALS, +} from '../config/test-users'; +import { TestError } from '../Types'; + +export interface LoginResponseData { + id: string; + [key: string]: any; +} + +export type UserRole = 'owner' | 'admin' | 'member'; +export type TestState = 'fresh' | 'reset' | 'signin-only'; + +const AUTH_TAGS = { + ADMIN: '@auth:admin', + OWNER: '@auth:owner', + MEMBER: '@auth:member', + NONE: '@auth:none', +} as const; + +const DB_TAGS = { + RESET: '@db:reset', +} as const; + +export class ApiHelpers { + private request: APIRequestContext; + + constructor(requestContext: APIRequestContext) { + this.request = requestContext; + } + + // ===== MAIN SETUP METHODS ===== + + /** + * Setup test environment based on test tags (recommended approach) + * @param tags - Array of test tags (e.g., ['@db:reset', '@auth:owner']) + * @param memberIndex - Which member to use (if auth role is 'member') + * + * Examples: + * - ['@db:reset'] = reset DB, manual signin required + * - ['@db:reset', '@auth:owner'] = reset DB + signin as owner + * - ['@auth:admin'] = signin as admin (no reset) + */ + async setupFromTags(tags: string[], memberIndex: number = 0): Promise { + const shouldReset = this.shouldResetDatabase(tags); + const role = this.getRoleFromTags(tags); + + if (shouldReset && role) { + // Reset + signin + await this.resetDatabase(); + return await this.signin(role, memberIndex); + } else if (shouldReset) { + // Reset only, manual signin required + await this.resetDatabase(); + return null; + } else if (role) { + // Signin only + return await this.signin(role, memberIndex); + } + + // No setup required + return null; + } + + /** + * Setup test environment based on desired state (programmatic approach) + * @param state - 'fresh': new container, 'reset': reset DB + signin, 'signin-only': just signin + * @param role - User role to sign in as + * @param memberIndex - Which member to use (if role is 'member') + */ + async setupTest( + state: TestState, + role: UserRole = 'owner', + memberIndex: number = 0, + ): Promise { + switch (state) { + case 'fresh': + // For fresh docker container - just reset, no signin needed yet + await this.resetDatabase(); + return null; + + case 'reset': + // Reset database then sign in + await this.resetDatabase(); + return await this.signin(role, memberIndex); + + case 'signin-only': + // Just sign in without reset + return await this.signin(role, memberIndex); + + default: + throw new TestError('Unknown test state'); + } + } + + // ===== CORE METHODS ===== + + async resetDatabase(): Promise { + const response = await this.request.post('/rest/e2e/reset', { + data: { + owner: INSTANCE_OWNER_CREDENTIALS, + members: INSTANCE_MEMBER_CREDENTIALS, + admin: INSTANCE_ADMIN_CREDENTIALS, + }, + }); + + if (!response.ok()) { + const errorText = await response.text(); + throw new TestError(errorText); + } + // Adding small delay to ensure database is reset + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + + async signin(role: UserRole, memberIndex: number = 0): Promise { + const credentials = this.getCredentials(role, memberIndex); + return await this.loginAndSetCookies(credentials); + } + + // ===== CONFIGURATION METHODS ===== + + async setFeature(feature: string, enabled: boolean): Promise { + await this.request.patch('/rest/e2e/feature', { + data: { feature: `feat:${feature}`, enabled }, + }); + } + + async setQuota(quotaName: string, value: number | string): Promise { + await this.request.patch('/rest/e2e/quota', { + data: { feature: `quota:${quotaName}`, value }, + }); + } + + async setQueueMode(enabled: boolean): Promise { + await this.request.patch('/rest/e2e/queue-mode', { + data: { enabled }, + }); + } + + // ===== CONVENIENCE METHODS ===== + + async enableFeature(feature: string): Promise { + await this.setFeature(feature, true); + } + + async disableFeature(feature: string): Promise { + await this.setFeature(feature, false); + } + + async setMaxTeamProjectsQuota(value: number | string): Promise { + await this.setQuota('maxTeamProjects', value); + } + + async get(path: string, params?: URLSearchParams) { + const response = await this.request.get(path, { params }); + + const { data } = await response.json(); + return data; + } + + // ===== PRIVATE METHODS ===== + + private async loginAndSetCookies( + credentials: Pick, + ): Promise { + const response = await this.request.post('/rest/login', { + data: { + emailOrLdapLoginId: credentials.email, + password: credentials.password, + }, + }); + + if (!response.ok()) { + const errorText = await response.text(); + throw new TestError(errorText); + } + + let responseData: any; + try { + responseData = await response.json(); + } catch (error) { + const errorText = await response.text(); + throw new TestError(errorText); + } + + const loginData: LoginResponseData = responseData.data; + + if (!loginData?.id) { + throw new TestError('Login did not return expected user data (missing user ID)'); + } + + return loginData; + } + + private getCredentials(role: UserRole, memberIndex: number = 0): UserCredentials { + switch (role) { + case 'owner': + return INSTANCE_OWNER_CREDENTIALS; + case 'admin': + return INSTANCE_ADMIN_CREDENTIALS; + case 'member': + if (!INSTANCE_MEMBER_CREDENTIALS || memberIndex >= INSTANCE_MEMBER_CREDENTIALS.length) { + throw new TestError(`No member credentials found for index ${memberIndex}`); + } + return INSTANCE_MEMBER_CREDENTIALS[memberIndex]; + default: + throw new TestError(`Unknown role: ${role as string}`); + } + } + + // ===== TAG PARSING METHODS ===== + + private shouldResetDatabase(tags: string[]): boolean { + const lowerTags = tags.map((tag) => tag.toLowerCase()); + return lowerTags.includes(DB_TAGS.RESET.toLowerCase()); + } + + /** + * Get the role from the tags + * @param tags - Array of test tags (e.g., ['@db:reset', '@auth:owner']) + * @returns The role from the tags, or 'owner' if no role is found + */ + getRoleFromTags(tags: string[]): UserRole | null { + const lowerTags = tags.map((tag) => tag.toLowerCase()); + + if (lowerTags.includes(AUTH_TAGS.ADMIN.toLowerCase())) return 'admin'; + if (lowerTags.includes(AUTH_TAGS.OWNER.toLowerCase())) return 'owner'; + if (lowerTags.includes(AUTH_TAGS.MEMBER.toLowerCase())) return 'member'; + if (lowerTags.includes(AUTH_TAGS.NONE.toLowerCase())) return null; + return 'owner'; + } +} diff --git a/packages/testing/playwright/tests/1-workflows.spec.ts b/packages/testing/playwright/tests/1-workflows.spec.ts new file mode 100644 index 0000000000..a544f1ae2e --- /dev/null +++ b/packages/testing/playwright/tests/1-workflows.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '../fixtures/base'; + +// Example of importing a workflow from a file +test.describe('Workflows', () => { + test('should create a new workflow using empty state card @db:reset', async ({ n8n }) => { + await n8n.goHome(); + await n8n.workflows.clickNewWorkflowCard(); + await n8n.workflows.importWorkflow('Test_workflow_1.json', 'Empty State Card Workflow'); + await expect(n8n.workflows.workflowTags()).toHaveText(['some-tag-1', 'some-tag-2']); + }); +}); diff --git a/packages/testing/playwright/tests/28-debug.spec.ts b/packages/testing/playwright/tests/28-debug.spec.ts new file mode 100644 index 0000000000..2cd5cd8fd5 --- /dev/null +++ b/packages/testing/playwright/tests/28-debug.spec.ts @@ -0,0 +1,113 @@ +import { test, expect } from '../fixtures/base'; + +// Example of using helper functions inside a test +test.describe('Debug mode', () => { + // Constants to avoid magic strings + const URLS = { + FAILING: 'https://foo.bar', + SUCCESS: 'https://postman-echo.com/get?foo1=bar1&foo2=bar2', + }; + + const NOTIFICATIONS = { + WORKFLOW_CREATED: 'Workflow successfully created', + EXECUTION_IMPORTED: 'Execution data imported', + PROBLEM_IN_NODE: 'Problem in node', + SUCCESSFUL: 'Successful', + DATA_NOT_IMPORTED: "Some execution data wasn't imported", + }; + + test.beforeEach(async ({ api, n8n }) => { + await api.enableFeature('debugInEditor'); + await n8n.goHome(); + }); + + // Helper function to create basic workflow + async function createBasicWorkflow(n8n, url = URLS.FAILING) { + await n8n.workflows.clickAddWorklowButton(); + await n8n.canvas.addNode('Manual Trigger'); + await n8n.canvas.addNode('HTTP Request'); + await n8n.ndv.fillParameterInput('URL', url); + await n8n.ndv.close(); + await n8n.canvas.clickSaveWorkflowButton(); + await n8n.notifications.waitForNotificationAndClose(NOTIFICATIONS.WORKFLOW_CREATED); + } + + // Helper function to import execution for debugging + async function importExecutionForDebugging(n8n) { + await n8n.canvas.clickExecutionsTab(); + await n8n.executions.clickDebugInEditorButton(); + await n8n.notifications.waitForNotificationAndClose(NOTIFICATIONS.EXECUTION_IMPORTED); + } + + test('should enter debug mode for failed executions', async ({ n8n }) => { + await createBasicWorkflow(n8n, URLS.FAILING); + await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.PROBLEM_IN_NODE); + await importExecutionForDebugging(n8n); + expect(n8n.page.url()).toContain('/debug'); + }); + + test('should exit debug mode after successful execution', async ({ n8n }) => { + await createBasicWorkflow(n8n, URLS.FAILING); + await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.PROBLEM_IN_NODE); + await importExecutionForDebugging(n8n); + + await n8n.canvas.openNode('HTTP Request'); + await n8n.ndv.fillParameterInput('URL', URLS.SUCCESS); + await n8n.ndv.close(); + await n8n.canvas.clickSaveWorkflowButton(); + + await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.SUCCESSFUL); + expect(n8n.page.url()).not.toContain('/debug'); + }); + + test('should handle pinned data conflicts during execution import', async ({ n8n }) => { + await createBasicWorkflow(n8n, URLS.SUCCESS); + await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.SUCCESSFUL); + await n8n.canvasComposer.pinNodeData('HTTP Request'); + + await n8n.workflowComposer.executeWorkflowAndWaitForNotification('Successful'); + + // Go to executions and try to copy execution to editor + await n8n.canvas.clickExecutionsTab(); + await n8n.executions.clickLastExecutionItem(); + await n8n.executions.clickCopyToEditorButton(); + + // Test CANCEL dialog + await n8n.executions.handlePinnedNodesConfirmation('Cancel'); + + // Try again and CONFIRM + await n8n.executions.clickLastExecutionItem(); + await n8n.executions.clickCopyToEditorButton(); + await n8n.executions.handlePinnedNodesConfirmation('Unpin'); + + expect(n8n.page.url()).toContain('/debug'); + + // Verify pinned status + const pinnedNodeNames = await n8n.canvas.getPinnedNodeNames(); + expect(pinnedNodeNames).not.toContain('HTTP Request'); + expect(pinnedNodeNames).toContain('When clicking ‘Execute workflow’'); + }); + + test('should show error for pinned data mismatch', async ({ n8n }) => { + // Create workflow, execute, and pin data + await createBasicWorkflow(n8n, URLS.SUCCESS); + await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.SUCCESSFUL); + + await n8n.canvasComposer.pinNodeData('HTTP Request'); + await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.SUCCESSFUL); + + // Delete node to create mismatch + await n8n.canvas.deleteNodeByName('HTTP Request'); + + // Try to copy execution and verify error + await attemptCopyToEditor(n8n); + await n8n.notifications.waitForNotificationAndClose(NOTIFICATIONS.DATA_NOT_IMPORTED); + expect(n8n.page.url()).toContain('/debug'); + }); + + async function attemptCopyToEditor(n8n) { + await n8n.canvas.clickExecutionsTab(); + await n8n.executions.clickLastExecutionItem(); + await n8n.executions.clickCopyToEditorButton(); + } +}); diff --git a/packages/testing/playwright/tests/39-projects.spec.ts b/packages/testing/playwright/tests/39-projects.spec.ts new file mode 100644 index 0000000000..d382b98cc0 --- /dev/null +++ b/packages/testing/playwright/tests/39-projects.spec.ts @@ -0,0 +1,107 @@ +import { test, expect } from '../fixtures/base'; +import { n8nPage } from '../pages/n8nPage'; +import type { ApiHelpers } from '../services/api-helper'; + +const MANUAL_TRIGGER_NODE_NAME = 'Manual Trigger'; +const EXECUTE_WORKFLOW_NODE_NAME = 'Execute Sub-workflow'; +const NOTION_NODE_NAME = 'Notion'; +const NOTION_API_KEY = 'abc123Playwright'; + +// Example of using API calls in a test +async function getCredentialsForProject(api: ApiHelpers, projectId?: string) { + const params = new URLSearchParams({ + includeScopes: 'true', + includeData: 'true', + ...(projectId && { filter: JSON.stringify({ projectId }) }), + }); + return await api.get('/rest/credentials', params); +} + +test.describe('Projects @db:reset', () => { + test.beforeEach(async ({ api, n8n }) => { + await api.enableFeature('sharing'); + await api.enableFeature('folders'); + await api.enableFeature('advancedPermissions'); + await api.enableFeature('projectRole:admin'); + await api.enableFeature('projectRole:editor'); + await api.setMaxTeamProjectsQuota(-1); + await n8n.goHome(); + }); + + test('should not show project add button and projects to a member if not invited to any project @auth:member', async ({ + n8n, + }) => { + await expect(n8n.sideBar.getAddFirstProjectButton()).toBeDisabled(); + await expect(n8n.sideBar.getProjectMenuItems()).toHaveCount(0); + }); + + test('should filter credentials by project ID', async ({ n8n, api }) => { + const { projectName, projectId } = await n8n.projectComposer.createProject(); + await n8n.projectComposer.addCredentialToProject( + projectName, + 'Notion API', + 'apiKey', + NOTION_API_KEY, + ); + + const credentials = await getCredentialsForProject(api, projectId); + expect(credentials).toHaveLength(1); + + const { projectId: project2Id } = await n8n.projectComposer.createProject(); + const credentials2 = await getCredentialsForProject(api, project2Id); + expect(credentials2).toHaveLength(0); + }); + + test('should create sub-workflow and credential in the sub-workflow in the same project @auth:owner', async ({ + n8n, + }) => { + const { projectName } = await n8n.projectComposer.createProject(); + await n8n.sideBar.addWorkflowFromUniversalAdd(projectName); + await n8n.canvas.addNode(MANUAL_TRIGGER_NODE_NAME); + await n8n.canvas.saveWorkflow(); + await expect( + n8n.page.getByText('Workflow successfully created', { exact: false }), + ).toBeVisible(); + + await n8n.canvas.addNodeToCanvasWithSubItem( + EXECUTE_WORKFLOW_NODE_NAME, + 'Execute A Sub Workflow', + ); + + const subWorkflowPagePromise = n8n.page.waitForEvent('popup'); + + await n8n.ndv.selectWorkflowResource(`Create a Sub-Workflow in '${projectName}'`); + + const subn8n = new n8nPage(await subWorkflowPagePromise); + + await subn8n.ndv.clickBackToCanvasButton(); + + await subn8n.canvas.deleteNodeByName('Replace me with your logic'); + await subn8n.canvas.addNodeToCanvasWithSubItem(NOTION_NODE_NAME, 'Append a block'); + + await subn8n.credentials.createAndSaveNewCredential('apiKey', NOTION_API_KEY); + + await subn8n.ndv.clickBackToCanvasButton(); + await subn8n.canvas.saveWorkflow(); + + await subn8n.page.goto('/home/workflows'); + await subn8n.projectWorkflows.clickProjectMenuItem(projectName); + await subn8n.page.getByRole('link', { name: 'Workflows' }).click(); + + // Get Workflow Count + + await expect(subn8n.page.locator('[data-test-id="resources-list-item-workflow"]')).toHaveCount( + 2, + ); + + // Assert that the sub-workflow is in the list + await expect(subn8n.page.getByRole('heading', { name: 'My Sub-Workflow' })).toBeVisible(); + + // Navigate to Credentials + await subn8n.page.getByRole('link', { name: 'Credentials' }).click(); + + // Assert that the credential is in the list + await expect(subn8n.page.locator('[data-test-id="resources-list-item"]')).toHaveCount(1); + await expect(subn8n.page.getByRole('heading', { name: 'Notion account' })).toBeVisible(); + }); +}); diff --git a/packages/testing/playwright/tests/authenticated.spec.ts b/packages/testing/playwright/tests/authenticated.spec.ts new file mode 100644 index 0000000000..a16b1f2cac --- /dev/null +++ b/packages/testing/playwright/tests/authenticated.spec.ts @@ -0,0 +1,26 @@ +import { test, expect } from '../fixtures/base'; + +test('default signin is as owner', async ({ n8n }) => { + await n8n.goHome(); + await expect(n8n.page).toHaveURL(/\/workflow/); +}); + +test('owner can access dashboard @auth:owner', async ({ n8n }) => { + await n8n.goHome(); + await expect(n8n.page).toHaveURL(/\/workflow/); +}); + +test('admin can access dashboard @auth:admin', async ({ n8n }) => { + await n8n.goHome(); + await expect(n8n.page).toHaveURL(/\/workflow/); +}); + +test('member can access dashboard @auth:member', async ({ n8n }) => { + await n8n.goHome(); + await expect(n8n.page).toHaveURL(/\/workflow/); +}); + +test('no auth can not access dashboard @auth:none', async ({ n8n }) => { + await n8n.goHome(); + await expect(n8n.page).toHaveURL(/\/signin/); +}); diff --git a/packages/testing/playwright/tests/multimain.spec.ts b/packages/testing/playwright/tests/multimain.spec.ts new file mode 100644 index 0000000000..a890285809 --- /dev/null +++ b/packages/testing/playwright/tests/multimain.spec.ts @@ -0,0 +1,22 @@ +import { test, expect } from '../fixtures/base'; + +test('Leader election @mode:multi-main @chaostest', async ({ chaos }) => { + // First get the container (try main 1 first) + const namePattern = 'n8n-main-*'; + + const findContainerByLog = await chaos.waitForLog('Leader is now this', { + namePattern, + }); + + expect(findContainerByLog).toBeDefined(); + const currentLeader = findContainerByLog.containerName; + // Stop leader + await chaos.stopContainer(currentLeader); + + // Find new leader + const newLeader = await chaos.waitForLog('Leader is now this', { + namePattern, + }); + + expect(newLeader).toBeDefined(); +}); diff --git a/packages/testing/playwright/tests/pdf.spec.ts b/packages/testing/playwright/tests/pdf.spec.ts new file mode 100644 index 0000000000..74cd0ac730 --- /dev/null +++ b/packages/testing/playwright/tests/pdf.spec.ts @@ -0,0 +1,15 @@ +import { expect, test } from '../fixtures/base'; + +// Example of importing a workflow from a file +test.describe('PDF Test', () => { + // eslint-disable-next-line playwright/no-skipped-test + test.skip('Can read and write PDF files and extract text', async ({ n8n }) => { + await n8n.goHome(); + await n8n.workflows.clickAddWorklowButton(); + await n8n.workflows.importWorkflow('test_pdf_workflow.json', 'PDF Workflow'); + await n8n.canvas.clickExecuteWorkflowButton(); + await expect( + n8n.notifications.notificationContainerByText('Workflow executed successfully'), + ).toBeVisible(); + }); +}); diff --git a/packages/testing/playwright/tsconfig.json b/packages/testing/playwright/tsconfig.json new file mode 100644 index 0000000000..74c428b679 --- /dev/null +++ b/packages/testing/playwright/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "sourceMap": false, + "declaration": false, + "lib": ["esnext", "dom"], + "types": ["@playwright/test", "node"] + }, + "include": ["**/*.ts"], + "exclude": ["**/dist/**/*", "**/node_modules/**/*"], + "references": [{ "path": "../../workflow/tsconfig.build.esm.json" }] +} diff --git a/packages/testing/playwright/utils/path-helper.ts b/packages/testing/playwright/utils/path-helper.ts new file mode 100644 index 0000000000..0edae95ce2 --- /dev/null +++ b/packages/testing/playwright/utils/path-helper.ts @@ -0,0 +1,32 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +import { TestError } from '../Types'; + +/** + * Finds the project root by searching upwards for a marker file. + * @param marker The file that identifies the project root (e.g., 'playwright.config.ts' or 'package.json'). + * @returns The absolute path to the project root. + */ +function findProjectRoot(marker: string): string { + let dir = __dirname; + while (!fs.existsSync(path.join(dir, marker))) { + const parentDir = path.dirname(dir); + if (parentDir === dir) { + throw new TestError('Could not find project root'); + } + dir = parentDir; + } + return dir; +} + +const playwrightRoot = findProjectRoot('playwright.config.ts'); + +/** + * Resolves a path relative to the Playwright project root. + * @param pathSegments Segments of the path starting from the project root. + * @returns An absolute path to the file or directory. + */ +export function resolveFromRoot(...pathSegments: string[]): string { + return path.join(playwrightRoot, ...pathSegments); +} diff --git a/packages/testing/playwright/workflows/Test_workflow_1.json b/packages/testing/playwright/workflows/Test_workflow_1.json new file mode 100644 index 0000000000..d10c44beca --- /dev/null +++ b/packages/testing/playwright/workflows/Test_workflow_1.json @@ -0,0 +1,61 @@ +{ + "name": "Test workflow 1", + "nodes": [ + { + "parameters": {}, + "id": "a2f85497-260d-4489-a957-2b7d88e2f33d", + "name": "On clicking 'execute'", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [220, 260] + }, + { + "parameters": { + "jsCode": "// Loop over input items and add a new field\n// called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n item.json.myNewField = 1;\n}\n\nreturn $input.all();" + }, + "id": "9493d278-1ede-47c9-bedf-92ac3a737c65", + "name": "Code", + "type": "n8n-nodes-base.code", + "typeVersion": 1, + "position": [400, 260] + } + ], + "pinData": {}, + "connections": { + "On clicking 'execute'": { + "main": [ + [ + { + "node": "Code", + "type": "main", + "index": 0 + } + ] + ] + }, + "Code": { + "main": [[]] + } + }, + "active": false, + "settings": {}, + "hash": "a59c7b1c97b1741597afae0fcd43ebef", + "id": 3, + "meta": { + "instanceId": "a5280676597d00ecd0ea712da7f9cf2ce90174a791a309112731f6e44d162f35" + }, + "tags": [ + { + "name": "some-tag-1", + "createdAt": "2022-11-10T13:43:34.001Z", + "updatedAt": "2022-11-10T13:43:34.001Z", + "id": "6" + }, + { + "name": "some-tag-2", + "createdAt": "2022-11-10T13:43:39.778Z", + "updatedAt": "2022-11-10T13:43:39.778Z", + "id": "7" + } + ] +} diff --git a/packages/testing/playwright/workflows/test_pdf_workflow.json b/packages/testing/playwright/workflows/test_pdf_workflow.json new file mode 100644 index 0000000000..3beb66b9a9 --- /dev/null +++ b/packages/testing/playwright/workflows/test_pdf_workflow.json @@ -0,0 +1,121 @@ +{ + "name": "My workflow", + "nodes": [ + { + "parameters": {}, + "id": "1285fa02-e091-4bd3-89cf-c7e6c174ff49", + "name": "Manual Trigger", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [460, -120] + }, + { + "parameters": { + "url": "https://ontheline.trincoll.edu/images/bookdown/sample-local-pdf.pdf", + "options": { + "response": { + "response": { + "responseFormat": "file" + } + } + } + }, + "id": "9c8b960d-e7c8-4116-97d4-4f5ca9872898", + "name": "Download PDF", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [680, -120] + }, + { + "parameters": { + "operation": "pdf", + "options": {} + }, + "type": "n8n-nodes-base.extractFromFile", + "typeVersion": 1, + "position": [1340, -120], + "id": "5757782b-7029-44d6-b87e-5f9b5910f1b7", + "name": "Extract from File" + }, + { + "parameters": { + "operation": "write", + "fileName": "/tmp/downloaded-sample.pdf", + "options": {} + }, + "type": "n8n-nodes-base.readWriteFile", + "typeVersion": 1, + "position": [900, -120], + "id": "2bc250b7-6f9f-4888-a229-beced5821b1b", + "name": "Write PDF" + }, + { + "parameters": { + "fileSelector": "/tmp/downloaded-sample.pdf", + "options": {} + }, + "type": "n8n-nodes-base.readWriteFile", + "typeVersion": 1, + "position": [1120, -120], + "id": "e3402ffd-b322-4442-b0d1-18bb19a9a319", + "name": "Read PDF" + } + ], + "pinData": {}, + "connections": { + "Manual Trigger": { + "main": [ + [ + { + "node": "Download PDF", + "type": "main", + "index": 0 + } + ] + ] + }, + "Download PDF": { + "main": [ + [ + { + "node": "Write PDF", + "type": "main", + "index": 0 + } + ] + ] + }, + "Write PDF": { + "main": [ + [ + { + "node": "Read PDF", + "type": "main", + "index": 0 + } + ] + ] + }, + "Read PDF": { + "main": [ + [ + { + "node": "Extract from File", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "active": false, + "settings": { + "executionOrder": "v1" + }, + "versionId": "8a74a3e5-c170-4d21-9821-90a47f3b7987", + "meta": { + "instanceId": "1b71763328f359150fb2679ac09d77f666c592638a32a2dd7f058138ceaf177d" + }, + "id": "1sTDcSTRKmMsFNn6", + "tags": [] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 53dfa91859..7bb40483c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -198,6 +198,8 @@ overrides: zod: 3.25.67 brace-expansion@1: 1.1.12 brace-expansion@2: 2.0.2 + date-fns: 2.30.0 + date-fns-tz: 2.0.0 patchedDependencies: '@types/express-serve-static-core@5.0.6': @@ -258,7 +260,7 @@ importers: version: 7.0.3 eslint: specifier: 'catalog:' - version: 9.29.0(jiti@1.21.0) + version: 9.29.0(jiti@1.21.7) jest: specifier: ^29.6.2 version: 29.6.2(@types/node@20.17.57)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)) @@ -361,7 +363,7 @@ importers: version: 4.17.17 eslint-plugin-cypress: specifier: ^4.3.0 - version: 4.3.0(eslint@9.29.0(jiti@1.21.0)) + version: 4.3.0(eslint@9.29.0(jiti@1.21.7)) n8n-workflow: specifier: workspace:* version: link:../packages/workflow @@ -481,10 +483,10 @@ importers: version: link:../permissions '@n8n/typeorm': specifier: 'catalog:' - version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mongodb@5.9.2(@aws-sdk/credential-providers@3.808.0))(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.14)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)) + version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.14)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) jest-mock-extended: specifier: ^3.0.4 - version: 3.0.4(jest@29.6.2(@types/node@20.17.57)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)))(typescript@5.8.3) + version: 3.0.4(jest@29.6.2(@types/node@20.19.1)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)))(typescript@5.8.3) n8n-workflow: specifier: workspace:^ version: link:../../workflow @@ -603,7 +605,7 @@ importers: version: link:../permissions '@n8n/typeorm': specifier: 'catalog:' - version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mongodb@5.9.2(@aws-sdk/credential-providers@3.808.0))(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.14)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)) + version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.14)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) class-validator: specifier: 0.14.0 version: 0.14.0 @@ -687,7 +689,7 @@ importers: dependencies: eslint: specifier: '>= 9' - version: 9.29.0(jiti@1.21.0) + version: 9.29.0(jiti@1.21.7) devDependencies: '@eslint/js': specifier: ^9.29.0 @@ -700,58 +702,58 @@ importers: version: link:../vitest-config '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.0.0(eslint@9.29.0(jiti@1.21.0)) + version: 5.0.0(eslint@9.29.0(jiti@1.21.7)) '@types/eslint': specifier: ^9.6.1 version: 9.6.1 '@typescript-eslint/eslint-plugin': specifier: ^8.35.0 - version: 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + version: 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/rule-tester': specifier: ^8.35.0 - version: 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/utils': specifier: ^8.35.0 - version: 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) eslint-config-prettier: specifier: ^10.1.5 - version: 10.1.5(eslint@9.29.0(jiti@1.21.0)) + version: 10.1.5(eslint@9.29.0(jiti@1.21.7)) eslint-import-resolver-typescript: specifier: ^4.4.3 - version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.0)))(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@1.21.0)) + version: 4.4.3(eslint-plugin-import-x@4.15.2(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.7)))(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.29.0(jiti@1.21.0)) + version: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.3)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-import-x: specifier: ^4.15.2 - version: 4.16.1(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.0)) + version: 4.15.2(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-lodash: specifier: ^8.0.0 - version: 8.0.0(eslint@9.29.0(jiti@1.21.0)) + version: 8.0.0(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-unicorn: specifier: ^59.0.1 - version: 59.0.1(eslint@9.29.0(jiti@1.21.0)) + version: 59.0.1(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-unused-imports: specifier: ^4.1.4 - version: 4.1.4(@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.0)) + version: 4.1.4(@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7)) eslint-plugin-vue: specifier: ^10.2.0 - version: 10.2.0(eslint@9.29.0(jiti@1.21.0))(vue-eslint-parser@9.4.2(eslint@9.29.0(jiti@1.21.0))) + version: 10.2.0(eslint@9.29.0(jiti@1.21.7))(vue-eslint-parser@10.1.3(eslint@9.29.0(jiti@1.21.7))) globals: specifier: ^16.2.0 version: 16.2.0 tsup: specifier: 'catalog:' - version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.17.57))(jiti@1.21.0)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) + version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.1))(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) typescript: specifier: 5.8.3 version: 5.8.3 typescript-eslint: specifier: ^8.35.0 - version: 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + version: 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) packages/@n8n/extension-sdk: dependencies: @@ -764,7 +766,7 @@ importers: version: link:../typescript-config '@vitejs/plugin-vue': specifier: catalog:frontend - version: 5.2.4(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.4(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) '@vue/tsconfig': specifier: catalog:frontend version: 0.7.0(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) @@ -776,7 +778,7 @@ importers: version: 4.19.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vue: specifier: catalog:frontend version: 3.5.13(typescript@5.8.3) @@ -846,7 +848,7 @@ importers: version: 4.3.0 '@getzep/zep-cloud': specifier: 1.0.12 - version: 1.0.12(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.28(d0079d2993dfd2a4e9e2c2f03851bb21)) + version: 1.0.12(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.28(f9561c3b67724aa0f177a38a80041072)) '@getzep/zep-js': specifier: 0.9.0 version: 0.9.0 @@ -873,7 +875,7 @@ importers: version: 0.3.4(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(encoding@0.1.13) '@langchain/community': specifier: 'catalog:' - version: 0.3.46(10ae15256126511fe3944d0a838f3cc8) + version: 0.3.46(6de8a673a24e563cf8f4ca63f57e8b8d) '@langchain/core': specifier: 'catalog:' version: 0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)) @@ -924,7 +926,7 @@ importers: version: link:../json-schema-to-zod '@n8n/typeorm': specifier: 0.3.20-12 - version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mongodb@6.11.0(@aws-sdk/credential-providers@3.808.0)(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.8.3))(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.12)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)) + version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mongodb@6.11.0(@aws-sdk/credential-providers@3.808.0)(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.8.3))(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.12)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) '@n8n/typescript-config': specifier: workspace:* version: link:../typescript-config @@ -981,7 +983,7 @@ importers: version: 23.0.1 langchain: specifier: 0.3.28 - version: 0.3.28(d0079d2993dfd2a4e9e2c2f03851bb21) + version: 0.3.28(f9561c3b67724aa0f177a38a80041072) lodash: specifier: 'catalog:' version: 4.17.21 @@ -1063,7 +1065,7 @@ importers: version: link:../../core tsup: specifier: 'catalog:' - version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.17.57))(jiti@1.21.0)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) + version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.1))(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) packages/@n8n/permissions: dependencies: @@ -1112,7 +1114,7 @@ importers: version: 8.6.4(storybook@8.6.4(prettier@3.3.3))(vue@3.5.13(typescript@5.8.3)) '@storybook/vue3-vite': specifier: ^8.6.4 - version: 8.6.4(storybook@8.6.4(prettier@3.3.3))(vite@7.0.0(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + version: 8.6.4(storybook@8.6.4(prettier@3.3.3))(vite@7.0.0(@types/node@20.19.1)(jiti@1.21.7)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) chromatic: specifier: ^11.27.0 version: 11.27.0 @@ -1184,16 +1186,16 @@ importers: version: 14.6.1(@testing-library/dom@10.4.0) tsup: specifier: 'catalog:' - version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.17.57))(jiti@1.21.0)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) + version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.1))(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) typescript: specifier: 5.8.3 version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) packages/@n8n/vitest-config: devDependencies: @@ -1202,10 +1204,10 @@ importers: version: link:../typescript-config vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) packages/cli: dependencies: @@ -1265,7 +1267,7 @@ importers: version: link:../@n8n/task-runner '@n8n/typeorm': specifier: 'catalog:' - version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mongodb@5.9.2(@aws-sdk/credential-providers@3.808.0))(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.14)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)) + version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.14)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) '@n8n_io/ai-assistant-sdk': specifier: 'catalog:' version: 1.14.0 @@ -1739,7 +1741,7 @@ importers: version: link:../../@n8n/typescript-config '@vitejs/plugin-vue': specifier: catalog:frontend - version: 5.2.4(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.4(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) '@vue/tsconfig': specifier: catalog:frontend version: 0.7.0(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) @@ -1748,7 +1750,7 @@ importers: version: 6.0.1 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vue: specifier: catalog:frontend version: 3.5.13(typescript@5.8.3) @@ -1800,22 +1802,22 @@ importers: version: link:../../../@n8n/vitest-config '@vitejs/plugin-vue': specifier: catalog:frontend - version: 5.2.4(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.4(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) '@vitest/coverage-v8': specifier: 'catalog:' - version: 3.2.4(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) + version: 3.2.4(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) unplugin-icons: specifier: ^0.19.0 version: 0.19.0(@vue/compiler-sfc@3.5.13) vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vite-plugin-dts: specifier: ^4.5.3 - version: 4.5.3(@types/node@20.17.57)(rollup@4.44.1)(typescript@5.8.3)(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) + version: 4.5.3(@types/node@20.19.1)(rollup@4.44.0)(typescript@5.8.3)(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vue-tsc: specifier: ^2.2.8 version: 2.2.8(patch_hash=e2aee939ccac8a57fe449bfd92bedd8117841579526217bc39aca26c6b8c317f)(typescript@5.8.3) @@ -1842,7 +1844,7 @@ importers: version: 8.1.0(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.8.3)) '@vitejs/plugin-vue': specifier: catalog:frontend - version: 5.2.4(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.4(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) '@vue/tsconfig': specifier: catalog:frontend version: 0.7.0(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) @@ -1851,16 +1853,16 @@ importers: version: 10.11.0(vue@3.5.13(typescript@5.8.3)) tsup: specifier: 'catalog:' - version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.17.57))(jiti@1.21.0)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) + version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.1))(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) typescript: specifier: 5.8.3 version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vue: specifier: catalog:frontend version: 3.5.13(typescript@5.8.3) @@ -1972,10 +1974,10 @@ importers: version: 2.11.0 '@vitejs/plugin-vue': specifier: catalog:frontend - version: 5.2.4(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.4(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) '@vitest/coverage-v8': specifier: 'catalog:' - version: 3.2.4(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) + version: 3.2.4(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) autoprefixer: specifier: ^10.4.19 version: 10.4.19(postcss@8.4.49) @@ -1987,22 +1989,22 @@ importers: version: 1.64.1 tailwindcss: specifier: ^3.4.3 - version: 3.4.3(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)) + version: 3.4.3(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) unplugin-icons: specifier: catalog:frontend version: 0.19.0(@vue/compiler-sfc@3.5.13) unplugin-vue-components: specifier: catalog:frontend - version: 0.27.3(@babel/parser@7.27.5)(rollup@4.44.1)(vue@3.5.13(typescript@5.8.3)) + version: 0.27.3(@babel/parser@7.27.5)(rollup@4.44.0)(vue@3.5.13(typescript@5.8.3)) vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vitest-mock-extended: specifier: 'catalog:' - version: 3.1.0(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) + version: 3.1.0(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) vue-tsc: specifier: ^2.2.8 version: 2.2.8(patch_hash=e2aee939ccac8a57fe449bfd92bedd8117841579526217bc39aca26c6b8c317f)(typescript@5.8.3) @@ -2036,7 +2038,7 @@ importers: version: 8.1.0(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.8.3)) '@vitejs/plugin-vue': specifier: catalog:frontend - version: 5.2.4(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.4(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) '@vue/tsconfig': specifier: catalog:frontend version: 0.7.0(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) @@ -2045,16 +2047,16 @@ importers: version: 10.11.0(vue@3.5.13(typescript@5.8.3)) tsup: specifier: 'catalog:' - version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.17.57))(jiti@1.21.0)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) + version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.1))(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) typescript: specifier: 5.8.3 version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vue: specifier: catalog:frontend version: 3.5.13(typescript@5.8.3) @@ -2109,16 +2111,16 @@ importers: version: 14.6.1(@testing-library/dom@10.4.0) tsup: specifier: 'catalog:' - version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.17.57))(jiti@1.21.0)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) + version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.1))(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) typescript: specifier: 5.8.3 version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) packages/frontend/@n8n/stores: dependencies: @@ -2146,7 +2148,7 @@ importers: version: 8.1.0(@vue/compiler-sfc@3.5.13)(vue@3.5.13(typescript@5.8.3)) '@vitejs/plugin-vue': specifier: catalog:frontend - version: 5.2.4(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.4(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) '@vue/tsconfig': specifier: catalog:frontend version: 0.7.0(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) @@ -2158,16 +2160,16 @@ importers: version: 2.2.4(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) tsup: specifier: 'catalog:' - version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.17.57))(jiti@1.21.0)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) + version: 8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.1))(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3) typescript: specifier: 5.8.3 version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vue: specifier: catalog:frontend version: 3.5.13(typescript@5.8.3) @@ -2474,13 +2476,13 @@ importers: version: 10.0.0 '@vitejs/plugin-legacy': specifier: ^6.0.2 - version: 6.0.2(terser@5.16.1)(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) + version: 6.0.2(terser@5.16.1)(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) '@vitejs/plugin-vue': specifier: catalog:frontend - version: 5.2.4(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) + version: 5.2.4(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3)) '@vitest/coverage-v8': specifier: 'catalog:' - version: 3.2.4(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) + version: 3.2.4(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) browserslist-to-esbuild: specifier: ^2.1.1 version: 2.1.1(browserslist@4.24.4) @@ -2495,22 +2497,22 @@ importers: version: 0.19.0(@vue/compiler-sfc@3.5.13) unplugin-vue-components: specifier: catalog:frontend - version: 0.27.3(@babel/parser@7.27.5)(rollup@4.44.1)(vue@3.5.13(typescript@5.8.3)) + version: 0.27.3(@babel/parser@7.27.5)(rollup@4.44.0)(vue@3.5.13(typescript@5.8.3)) vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vite-plugin-static-copy: specifier: 2.2.0 - version: 2.2.0(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) + version: 2.2.0(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) vite-svg-loader: specifier: 5.1.0 version: 5.1.0(vue@3.5.13(typescript@5.8.3)) vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vitest-mock-extended: specifier: 'catalog:' - version: 3.1.0(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) + version: 3.1.0(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) vue-tsc: specifier: ^2.2.8 version: 2.2.8(patch_hash=e2aee939ccac8a57fe449bfd92bedd8117841579526217bc39aca26c6b8c317f)(typescript@5.8.3) @@ -2839,11 +2841,38 @@ importers: version: 0.4.14 eslint-plugin-n8n-nodes-base: specifier: ^1.16.3 - version: 1.16.3(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + version: 1.16.3(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) n8n-core: specifier: workspace:* version: link:../core + packages/testing/containers: + devDependencies: + '@testcontainers/postgresql': + specifier: ^11.0.3 + version: 11.0.3 + '@testcontainers/redis': + specifier: ^11.0.3 + version: 11.0.3 + testcontainers: + specifier: ^11.0.3 + version: 11.0.3 + + packages/testing/playwright: + devDependencies: + '@currents/playwright': + specifier: 1.14.1 + version: 1.14.1(magicast@0.3.5) + '@playwright/test': + specifier: 1.53.0 + version: 1.53.0 + eslint-plugin-playwright: + specifier: 2.2.0 + version: 2.2.0(eslint@9.29.0(jiti@1.21.7)) + n8n-containers: + specifier: workspace:* + version: link:../containers + packages/workflow: dependencies: '@n8n/tournament': @@ -2927,10 +2956,10 @@ importers: version: 0.4.14 vitest: specifier: 'catalog:' - version: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + version: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vitest-mock-extended: specifier: 'catalog:' - version: 3.1.0(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) + version: 3.1.0(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) packages: @@ -3294,6 +3323,10 @@ packages: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.26.8': resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} engines: {node: '>=6.9.0'} @@ -3883,6 +3916,9 @@ packages: resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} engines: {node: '>=6.9.0'} + '@balena/dockerignore@1.0.2': + resolution: {integrity: sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -4015,6 +4051,11 @@ packages: resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} engines: {node: '>=0.1.90'} + '@commander-js/extra-typings@12.1.0': + resolution: {integrity: sha512-wf/lwQvWAA0goIghcb91dQYpkLBcyhOhQNqG/VgWhnKzgt+UOMvra7EX/2fv70arm5RW+PUHoQHHDa6/p77Eqg==} + peerDependencies: + commander: ~12.1.0 + '@common.js/is-network-error@1.0.1': resolution: {integrity: sha512-dkk7FX8L/JLia5pi+IQ11lCw2D6FTmbWL2iWTHgCbP40/deeXgknlkEQcQ/rOkjwQbqp8RZ4ey/anR17K66sqw==} engines: {node: '>=16'} @@ -4027,6 +4068,14 @@ packages: resolution: {integrity: sha512-/Z3l6pXthq0JvMYdUFyX9j0MaCltlIn6mfh9jLyQwg5aPKxkyNa0PTHtU1AlFXLNk55ZuAeJRcpvq+tmLfKmaQ==} engines: {node: '>=10'} + '@currents/commit-info@1.0.1-beta.0': + resolution: {integrity: sha512-gkn8E3UC+F4/fCla7QAGMGgGPzxZUL9bU9+4I+KZf9PtCU3DdQCdy7a+er2eg4ewfUzZ2Ic1HcfnHuPkuLPKIw==} + engines: {node: '>=6'} + + '@currents/playwright@1.14.1': + resolution: {integrity: sha512-ScnvvJ/Juku8j4QTvwzflaPTXxooYHI+hDIVvySUxjQJMLv/Y2ZUXJoQEoWpDWYuRXXVf58TADI1W3etNkux+A==} + hasBin: true + '@cypress/grep@4.1.0': resolution: {integrity: sha512-yUscMiUgM28VDPrNxL19/BhgHZOVrAPrzVsuEcy6mqPqDYt8H8fIaHeeGQPW4CbMu/ry9sehjH561WDDBIXOIg==} peerDependencies: @@ -4072,146 +4121,152 @@ packages: '@emotion/unitless@0.8.0': resolution: {integrity: sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==} - '@esbuild/aix-ppc64@0.24.0': - resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + '@esbuild/aix-ppc64@0.24.2': + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.24.0': - resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + '@esbuild/android-arm64@0.24.2': + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.24.0': - resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + '@esbuild/android-arm@0.24.2': + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.24.0': - resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + '@esbuild/android-x64@0.24.2': + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.24.0': - resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + '@esbuild/darwin-arm64@0.24.2': + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.24.0': - resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + '@esbuild/darwin-x64@0.24.2': + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.24.0': - resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + '@esbuild/freebsd-arm64@0.24.2': + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.24.0': - resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + '@esbuild/freebsd-x64@0.24.2': + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.24.0': - resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + '@esbuild/linux-arm64@0.24.2': + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.24.0': - resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + '@esbuild/linux-arm@0.24.2': + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.24.0': - resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + '@esbuild/linux-ia32@0.24.2': + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.24.0': - resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + '@esbuild/linux-loong64@0.24.2': + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.24.0': - resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + '@esbuild/linux-mips64el@0.24.2': + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.24.0': - resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + '@esbuild/linux-ppc64@0.24.2': + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.24.0': - resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + '@esbuild/linux-riscv64@0.24.2': + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.24.0': - resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + '@esbuild/linux-s390x@0.24.2': + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.24.0': - resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + '@esbuild/linux-x64@0.24.2': + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.24.0': - resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + '@esbuild/netbsd-arm64@0.24.2': + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.24.2': + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.24.0': - resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + '@esbuild/openbsd-arm64@0.24.2': + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.24.0': - resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + '@esbuild/openbsd-x64@0.24.2': + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.24.0': - resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + '@esbuild/sunos-x64@0.24.2': + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.24.0': - resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + '@esbuild/win32-arm64@0.24.2': + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.24.0': - resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + '@esbuild/win32-ia32@0.24.2': + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.24.0': - resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + '@esbuild/win32-x64@0.24.2': + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -4248,8 +4303,8 @@ packages: resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.1': - resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} + '@eslint/core@0.15.0': + resolution: {integrity: sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': @@ -4268,8 +4323,8 @@ packages: resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.3': - resolution: {integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==} + '@eslint/plugin-kit@0.3.2': + resolution: {integrity: sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ewoudenberg/difflib@0.1.0': @@ -4571,6 +4626,14 @@ packages: '@ioredis/commands@1.2.0': resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -5417,68 +5480,68 @@ packages: '@n8n_io/riot-tmpl@4.0.1': resolution: {integrity: sha512-/zdRbEfTFjsm1NqnpPQHgZTkTdbp5v3VUxGeMA9098sps8jRCTraQkc3AQstJgHUm7ylBXJcIVhnVeLUMWAfwQ==} - '@napi-rs/canvas-android-arm64@0.1.71': - resolution: {integrity: sha512-cxi3VCotIOS9kNFQI7dcysbVJi106pxryVY1Hi85pX+ZeqahRyeqc/NsLaZ998Ae99+F3HI5X/39G1Y/Byrf0A==} + '@napi-rs/canvas-android-arm64@0.1.70': + resolution: {integrity: sha512-I/YOuQ0wbkVYxVaYtCgN42WKTYxNqFA0gTcTrHIGG1jfpDSyZWII/uHcjOo4nzd19io6Y4+/BqP8E5hJgf9OmQ==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@napi-rs/canvas-darwin-arm64@0.1.71': - resolution: {integrity: sha512-7Y4D/6vIuMLYsVNtRM/w2j0+fB1GyqeOxc7I0BTx8eLP1S6BZE2Rj6zJfdG+zmLEOW0IlHa+VQq1q2MUAjW84w==} + '@napi-rs/canvas-darwin-arm64@0.1.70': + resolution: {integrity: sha512-4pPGyXetHIHkw2TOJHujt3mkCP8LdDu8+CT15ld9Id39c752RcI0amDHSuMLMQfAjvusA9B5kKxazwjMGjEJpQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@napi-rs/canvas-darwin-x64@0.1.71': - resolution: {integrity: sha512-Z0IUqxclrYdfVt/SK9nKCzUHTOXKTWiygtO71YCzs0OtxKdNI7GJRJdYG48wXZEDQ/pqTF4F7Ifgtidfc2tYpg==} + '@napi-rs/canvas-darwin-x64@0.1.70': + resolution: {integrity: sha512-+2N6Os9LbkmDMHL+raknrUcLQhsXzc5CSXRbXws9C3pv/mjHRVszQ9dhFUUe9FjfPhCJznO6USVdwOtu7pOrzQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.71': - resolution: {integrity: sha512-KlpqqCASak5ruY+UIolJgmhMZ9Pa2o1QyaNu648L8sz4WNBbNa+aOT60XCLCL1VIKLv11B3MlNgiOHoYNmDhXQ==} + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.70': + resolution: {integrity: sha512-QjscX9OaKq/990sVhSMj581xuqLgiaPVMjjYvWaCmAJRkNQ004QfoSMEm3FoTqM4DRoquP8jvuEXScVJsc1rqQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@napi-rs/canvas-linux-arm64-gnu@0.1.71': - resolution: {integrity: sha512-bdGZCGu8YQNAiu3nkIVVUp6nIn6fPd36IuZsLXTG027E52KyIuZ3obCxehSwjDIUNkFWvmff5D6JYfWwAoioEw==} + '@napi-rs/canvas-linux-arm64-gnu@0.1.70': + resolution: {integrity: sha512-LNakMOwwqwiHIwMpnMAbFRczQMQ7TkkMyATqFCOtUJNlE6LPP/QiUj/mlFrNbUn/hctqShJ60gWEb52ZTALbVw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@napi-rs/canvas-linux-arm64-musl@0.1.71': - resolution: {integrity: sha512-1R5sMWe9ur8uM+hAeylBwG0b6UHDR+iWQNgzXmF9vbBYRooQvmDWqpcgytKLJAC0vnWhIkKwqd7yExn7cwczmg==} + '@napi-rs/canvas-linux-arm64-musl@0.1.70': + resolution: {integrity: sha512-wBTOllEYNfJCHOdZj9v8gLzZ4oY3oyPX8MSRvaxPm/s7RfEXxCyZ8OhJ5xAyicsDdbE5YBZqdmaaeP5+xKxvtg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@napi-rs/canvas-linux-riscv64-gnu@0.1.71': - resolution: {integrity: sha512-xjjKsipueuG+LdKIk6/uAlqdo+rzGcmNpTZPXdakIT1sHX4NNSnQTzjRaj9Gh96Czjd9G89UWR0KIlE7fwOgFA==} + '@napi-rs/canvas-linux-riscv64-gnu@0.1.70': + resolution: {integrity: sha512-GVUUPC8TuuFqHip0rxHkUqArQnlzmlXmTEBuXAWdgCv85zTCFH8nOHk/YCF5yo0Z2eOm8nOi90aWs0leJ4OE5Q==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] - '@napi-rs/canvas-linux-x64-gnu@0.1.71': - resolution: {integrity: sha512-3s6YpklXDB4OeeULG1XTRyKrKAOo7c3HHEqM9A6N4STSjMaJtzmpp7tB/JTvAFeOeFte6gWN8IwC+7AjGJ6MpQ==} + '@napi-rs/canvas-linux-x64-gnu@0.1.70': + resolution: {integrity: sha512-/kvUa2lZRwGNyfznSn5t1ShWJnr/m5acSlhTV3eXECafObjl0VBuA1HJw0QrilLpb4Fe0VLywkpD1NsMoVDROQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@napi-rs/canvas-linux-x64-musl@0.1.71': - resolution: {integrity: sha512-5v9aCLzCXw7u10ray5juQMdl7TykZSn1X5AIGYwBvTAcKSgrqaR9QkRxp1Lqk3njQmFekOW1SFN9bZ/i/6y6kA==} + '@napi-rs/canvas-linux-x64-musl@0.1.70': + resolution: {integrity: sha512-aqlv8MLpycoMKRmds7JWCfVwNf1fiZxaU7JwJs9/ExjTD8lX2KjsO7CTeAj5Cl4aEuzxUWbJPUUE2Qu9cZ1vfg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@napi-rs/canvas-win32-x64-msvc@0.1.71': - resolution: {integrity: sha512-oJughk6xjsRIr0Rd9EqjmZmhIMkvcPuXgr3MNn2QexTqn+YFOizrwHS5ha0BDfFl7TEGRvwaDUXBQtu8JKXb8A==} + '@napi-rs/canvas-win32-x64-msvc@0.1.70': + resolution: {integrity: sha512-Q9QU3WIpwBTVHk4cPfBjGHGU4U0llQYRXgJtFtYqqGNEOKVN4OT6PQ+ve63xwIPODMpZ0HHyj/KLGc9CWc3EtQ==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@napi-rs/canvas@0.1.71': - resolution: {integrity: sha512-92ybDocKl6JM48ZpYbj+A7Qt45IaTABDk0y3sDecEQfgdhfNzJtEityqNHoCZ4Vty2dldPkJhxgvOnbrQMXTTA==} + '@napi-rs/canvas@0.1.70': + resolution: {integrity: sha512-nD6NGa4JbNYSZYsTnLGrqe9Kn/lCkA4ybXt8sx5ojDqZjr2i0TWAHxx/vhgfjX+i3hCdKWufxYwi7CfXqtITSA==} engines: {node: '>= 10'} '@napi-rs/wasm-runtime@0.2.11': @@ -5771,8 +5834,8 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@playwright/test@1.49.1': - resolution: {integrity: sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==} + '@playwright/test@1.53.0': + resolution: {integrity: sha512-15hjKreZDcp7t6TL/7jkAo6Df5STZN09jGiv5dbP9A6vMVncXRqE7/B2SncsyOwrkZRBH2i6/TPOL8BVmm3c7w==} engines: {node: '>=18'} hasBin: true @@ -5883,103 +5946,103 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.44.1': - resolution: {integrity: sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==} + '@rollup/rollup-android-arm-eabi@4.44.0': + resolution: {integrity: sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.44.1': - resolution: {integrity: sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==} + '@rollup/rollup-android-arm64@4.44.0': + resolution: {integrity: sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.44.1': - resolution: {integrity: sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==} + '@rollup/rollup-darwin-arm64@4.44.0': + resolution: {integrity: sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.44.1': - resolution: {integrity: sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==} + '@rollup/rollup-darwin-x64@4.44.0': + resolution: {integrity: sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.44.1': - resolution: {integrity: sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==} + '@rollup/rollup-freebsd-arm64@4.44.0': + resolution: {integrity: sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.44.1': - resolution: {integrity: sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==} + '@rollup/rollup-freebsd-x64@4.44.0': + resolution: {integrity: sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.44.1': - resolution: {integrity: sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.44.0': + resolution: {integrity: sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.44.1': - resolution: {integrity: sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==} + '@rollup/rollup-linux-arm-musleabihf@4.44.0': + resolution: {integrity: sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.44.1': - resolution: {integrity: sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==} + '@rollup/rollup-linux-arm64-gnu@4.44.0': + resolution: {integrity: sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.44.1': - resolution: {integrity: sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==} + '@rollup/rollup-linux-arm64-musl@4.44.0': + resolution: {integrity: sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.44.1': - resolution: {integrity: sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==} + '@rollup/rollup-linux-loongarch64-gnu@4.44.0': + resolution: {integrity: sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.44.1': - resolution: {integrity: sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==} + '@rollup/rollup-linux-powerpc64le-gnu@4.44.0': + resolution: {integrity: sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.44.1': - resolution: {integrity: sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==} + '@rollup/rollup-linux-riscv64-gnu@4.44.0': + resolution: {integrity: sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.44.1': - resolution: {integrity: sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==} + '@rollup/rollup-linux-riscv64-musl@4.44.0': + resolution: {integrity: sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.44.1': - resolution: {integrity: sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==} + '@rollup/rollup-linux-s390x-gnu@4.44.0': + resolution: {integrity: sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.44.1': - resolution: {integrity: sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==} + '@rollup/rollup-linux-x64-gnu@4.44.0': + resolution: {integrity: sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.44.1': - resolution: {integrity: sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==} + '@rollup/rollup-linux-x64-musl@4.44.0': + resolution: {integrity: sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.44.1': - resolution: {integrity: sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==} + '@rollup/rollup-win32-arm64-msvc@4.44.0': + resolution: {integrity: sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.44.1': - resolution: {integrity: sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==} + '@rollup/rollup-win32-ia32-msvc@4.44.0': + resolution: {integrity: sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.44.1': - resolution: {integrity: sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==} + '@rollup/rollup-win32-x64-msvc@4.44.0': + resolution: {integrity: sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ==} cpu: [x64] os: [win32] @@ -6013,6 +6076,9 @@ packages: '@rushstack/ts-command-line@4.23.6': resolution: {integrity: sha512-7WepygaF3YPEoToh4MAL/mmHkiIImQq3/uAkQX46kVoKTNOOlCtFGyNnze6OYuWw2o9rxsyrHVfIBKxq/am2RA==} + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@selderee/plugin-htmlparser2@0.11.0': resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==} @@ -6090,6 +6156,10 @@ packages: '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + '@sinonjs/commons@2.0.0': resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} @@ -6611,6 +6681,12 @@ packages: '@tediousjs/connection-string@0.5.0': resolution: {integrity: sha512-7qSgZbincDDDFyRweCIEvZULFAw5iz/DeunhvuxpL31nfntX3P4Yd4HkHBRg9H8CdqY1e5WFN1PZIz/REL9MVQ==} + '@testcontainers/postgresql@11.0.3': + resolution: {integrity: sha512-nMq0lBLguZecp9JDV4J8nlPWwxOQ4XiXUIGkV5Lvj1CMdVqbqQJe4eVrNHVC3rIM/w8nadNp5ecEoxnwkhG33w==} + + '@testcontainers/redis@11.0.3': + resolution: {integrity: sha512-0TTXdnzvH55nMc7wj5s+3e/h29M5EEZ7cQAoCR16ZzQgzcLlXFTCIzSi02EkSZYrxayaToXrBdWCc6skisFzZw==} + '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} @@ -6747,9 +6823,18 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/docker-modem@3.0.6': + resolution: {integrity: sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==} + + '@types/dockerode@3.3.41': + resolution: {integrity: sha512-5kOi6bcnEjqfJ68ZNV/bBvSMLNIucc0XbRmBO4hg5OoFCoP99eSRcbMysjkzV7ZxQEmmc/zMnv4A7odwuKFzDA==} + '@types/eslint@9.6.1': resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -6915,6 +7000,9 @@ packages: '@types/node@20.17.57': resolution: {integrity: sha512-f3T4y6VU4fVQDKVqJV4Uppy8c1p/sVvS3peyqxyWnzkqXFJLRU7Y1Bl7rMS1Qe9z0v4M6McY0Fp9yBsgHJUsWQ==} + '@types/node@20.19.1': + resolution: {integrity: sha512-jJD50LtlD2dodAEO653i3YF04NWak6jN3ky+Ri3Em3mGR39/glWiboM/IePaRbgwSfqM1TpGXfAg8ohn/4dTgA==} + '@types/nodemailer@6.4.14': resolution: {integrity: sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==} @@ -6936,8 +7024,8 @@ packages: '@types/promise-ftp@1.3.4': resolution: {integrity: sha512-fCIX7I84e25RX6bZ+qiIv0Puu5axWhCj9+El+4Kz1gZZyO/NvwdGTNQ33y6jdrPuTn3Df3kg7nMi1HohjNQLog==} - '@types/prop-types@15.7.14': - resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} '@types/proxy-from-env@1.0.4': resolution: {integrity: sha512-TPR9/bCZAr3V1eHN4G3LD3OLicdJjqX1QRXWuNcCYgE66f/K8jO2ZRtHxI2D9MbnuUP6+qiKSS8eUHp6TFHGCw==} @@ -7008,6 +7096,12 @@ packages: '@types/ssh2-sftp-client@5.3.2': resolution: {integrity: sha512-s5R3hsnI3/7Ar57LG++gm2kxgONHtOZY2A3AgGzEwiJlHR8j7MRPDw1n/hG6oMnOUJ4zuoLNtDXgDfmmxV4lDA==} + '@types/ssh2-streams@0.1.12': + resolution: {integrity: sha512-Sy8tpEmCce4Tq0oSOYdfqaBpA3hDM8SoxoFh5vzFsu2oL+znzGz8oVWW7xb4K920yYMUY+PIG31qZnFMfPWNCg==} + + '@types/ssh2@0.5.52': + resolution: {integrity: sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg==} + '@types/ssh2@1.11.6': resolution: {integrity: sha512-8Mf6bhzYYBLEB/G6COux7DS/F5bCWwojv/qFo2yH/e4cLzAavJnxvFXrYW59iKfXdhG6OmzJcXDasgOb/s0rxw==} @@ -7089,9 +7183,6 @@ packages: '@types/whatwg-url@11.0.4': resolution: {integrity: sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==} - '@types/whatwg-url@8.2.2': - resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==} - '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} @@ -7355,6 +7446,9 @@ packages: '@vitest/pretty-format@3.1.3': resolution: {integrity: sha512-i6FDiBeJUGLDKADw2Gb01UtUNb12yyXAqC/mmRWuYl+m/U9GS7s8us5ONmGkGpUUo7/iAYzI2ePVfOZTYvUifA==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/runner@3.1.3': resolution: {integrity: sha512-Tae+ogtlNfFei5DggOsSUvkIaSuVywujMj6HzR97AHK6XK8i3BuVyIifWAm/sE3a15lF5RH9yQIrbXYuo0IFyA==} @@ -7716,6 +7810,14 @@ packages: arch@2.2.0: resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} + + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} + are-we-there-yet@3.0.1: resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -7850,6 +7952,9 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} + async-lock@1.4.1: + resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} + async-mutex@0.5.0: resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} @@ -7869,6 +7974,10 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + autoprefixer@10.4.19: resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==} engines: {node: ^10 || ^12 || >=14} @@ -7903,11 +8012,14 @@ packages: peerDependencies: axios: 0.x || 1.x + axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + axios@1.8.3: resolution: {integrity: sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==} - axios@1.9.0: - resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==} + b4a@1.6.7: + resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} babel-jest@29.6.2: resolution: {integrity: sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A==} @@ -7961,6 +8073,9 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bare-events@2.5.4: + resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -8013,6 +8128,9 @@ packages: bluebird@3.4.7: resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} + bluebird@3.5.5: + resolution: {integrity: sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==} + bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} @@ -8065,6 +8183,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.25.0: + resolution: {integrity: sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + bs-logger@0.2.6: resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} engines: {node: '>= 6'} @@ -8072,10 +8195,6 @@ packages: bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - bson@5.5.1: - resolution: {integrity: sha512-ix0EwukN2EpC0SRWIj/7B5+A6uQMQy6KMREI9qQqvgpkV2frH63T0UDVd1SYedL6dNCmDBYB3QtXi4ISk9YT+g==} - engines: {node: '>=14.20.1'} - bson@6.10.0: resolution: {integrity: sha512-ROchNosXMJD2cbQGm84KoP7vOGPO6/bOAW0veMMbzhXLqoZptcaYRVLitwvuhwhjjpU1qP4YZRWLhgETdgqUQw==} engines: {node: '>=16.20.1'} @@ -8084,6 +8203,10 @@ packages: buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} @@ -8130,10 +8253,22 @@ packages: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} + byline@5.0.0: + resolution: {integrity: sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==} + engines: {node: '>=0.10.0'} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + c12@1.11.2: + resolution: {integrity: sha512-oBs8a4uvSDO9dm8b7OCFW7+dgtVrwmwnrVXYzLm43ta7ep2jCn/0MhoUFygIWtxhyy6+/MG7/agvpY0U1Iemew==} + peerDependencies: + magicast: ^0.3.4 + peerDependenciesMeta: + magicast: + optional: true + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -8199,6 +8334,9 @@ packages: caniuse-lite@1.0.30001703: resolution: {integrity: sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==} + caniuse-lite@1.0.30001724: + resolution: {integrity: sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA==} + capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} @@ -8277,6 +8415,10 @@ packages: resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} engines: {node: '>= 14.16.0'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -8304,6 +8446,9 @@ packages: resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==} engines: {node: '>=8'} + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + cjs-module-lexer@1.2.2: resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} @@ -8435,6 +8580,10 @@ packages: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -8475,6 +8624,10 @@ packages: resolution: {integrity: sha512-/1+d/k0Al0uzg4rFAz9fbYOTnT20JYgN7SoaRr5x2cz7kH4Mtj+GQPh7W9UocpzFtxSL8flv6qAOOfJvQGqUjg==} engines: {node: '>=18'} + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} @@ -8504,8 +8657,8 @@ packages: config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} - consola@3.4.0: - resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} console-control-strings@1.1.0: @@ -8556,8 +8709,8 @@ packages: cookiejar@2.1.4: resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} - core-js-compat@3.41.0: - resolution: {integrity: sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==} + core-js-compat@3.43.0: + resolution: {integrity: sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==} core-js@3.40.0: resolution: {integrity: sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==} @@ -8585,6 +8738,15 @@ packages: resolution: {integrity: sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==} engines: {node: '>=10.0.0'} + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -8612,6 +8774,10 @@ packages: cross-fetch@4.0.0: resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + cross-spawn@6.0.6: + resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} + engines: {node: '>=4.8'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -8794,7 +8960,7 @@ packages: date-fns-tz@2.0.0: resolution: {integrity: sha512-OAtcLdB9vxSXTWHdT8b398ARImVwQMyjfYGkKD2zaGpHseG2UPHbHjXELReErZFxWdSLph3c2zOaaTyHfOhERQ==} peerDependencies: - date-fns: '>=2.0.0' + date-fns: 2.30.0 date-fns@2.30.0: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} @@ -8948,6 +9114,9 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + detect-libc@2.0.4: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} @@ -8983,6 +9152,18 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + docker-compose@1.2.0: + resolution: {integrity: sha512-wIU1eHk3Op7dFgELRdmOYlPYS4gP8HhH1ZmZa13QZF59y0fblzFDFmKPhyc05phCy2hze9OEvNZAsoljrs+72w==} + engines: {node: '>= 6.0.0'} + + docker-modem@5.0.6: + resolution: {integrity: sha512-ens7BiayssQz/uAxGzH8zGXCtiV24rRWXdjNha5V4zSOcxmAZsfGVm/PPFbwQdqEkDnhG+SyR9E3zSHUbOKXBQ==} + engines: {node: '>= 8.0'} + + dockerode@4.0.7: + resolution: {integrity: sha512-R+rgrSRTRdU5mH14PZTCPZtW/zw3HDWNTS/1ZAQpL/5Upe/ye5K9WQkIysu4wBoiMwKynsz0a8qWuGsHgEvSAA==} + engines: {node: '>= 8.0'} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -9091,6 +9272,9 @@ packages: electron-to-chromium@1.5.114: resolution: {integrity: sha512-DFptFef3iktoKlFQK/afbo274/XNWD00Am0xa7M8FZUepHlHT8PEuiNBoRfFHbH1okqN58AlhbJ4QTkcnXorjA==} + electron-to-chromium@1.5.173: + resolution: {integrity: sha512-2bFhXP2zqSfQHugjqJIDFVwa+qIxyNApenmXTp9EjaKtdPrES5Qcn9/aSFy/NaP2E+fWG/zxKu/LBvY36p5VNQ==} + element-plus@2.4.3: resolution: {integrity: sha512-b3q26j+lM4SBqiyzw8HybybGnP2pk4MWgrnzzzYW5qKQUgV6EG1Zg7nMCfgCVccI8tNvZoTiUHb2mFaiB9qT8w==} peerDependencies: @@ -9216,8 +9400,8 @@ packages: peerDependencies: esbuild: ^0.24.0 - esbuild@0.24.0: - resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + esbuild@0.24.2: + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} engines: {node: '>=18'} hasBin: true @@ -9267,8 +9451,8 @@ packages: eslint-config-riot@1.0.0: resolution: {integrity: sha512-NB/L/1Y30qyJcG5xZxCJKW/+bqyj+llbcCwo9DEz8bESIP0SLTOQ8T1DWCCFc+wJ61AMEstj4511PSScqMMfCw==} - eslint-import-context@0.1.9: - resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} + eslint-import-context@0.1.8: + resolution: {integrity: sha512-bq+F7nyc65sKpZGT09dY0S0QrOnQtuDVIfyTGQ8uuvtMIF7oHp6CEP3mouN0rrnYF3Jqo6Ke0BfU/5wASZue1w==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} peerDependencies: unrs-resolver: ^1.0.0 @@ -9279,8 +9463,8 @@ packages: eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - eslint-import-resolver-typescript@4.4.4: - resolution: {integrity: sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==} + eslint-import-resolver-typescript@4.4.3: + resolution: {integrity: sha512-elVDn1eWKFrWlzxlWl9xMt8LltjKl161Ix50JFC50tHXI5/TRP32SNEqlJ/bo/HV+g7Rou/tlPQU2AcRtIhrOg==} engines: {node: ^16.17.0 || >=18.6.0} peerDependencies: eslint: '*' @@ -9318,8 +9502,8 @@ packages: peerDependencies: eslint: '>=9' - eslint-plugin-import-x@4.16.1: - resolution: {integrity: sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==} + eslint-plugin-import-x@4.15.2: + resolution: {integrity: sha512-J5gx7sN6DTm0LRT//eP3rVVQ2Yi4hrX0B+DbWxa5er8PZ6JjLo9GUBwogIFvEDdwJaSqZplpQT+haK/cXhb7VQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/utils': ^8.0.0 @@ -9354,6 +9538,12 @@ packages: resolution: {integrity: sha512-edLX42Vg4B+y0kzkitTVDmHZQrG5/wUZO874N5Z9leBuxt5TG1pqMY4zdr35RlpM4p4REr/T9x+6DpsQSL63WA==} engines: {node: '>=20.15', pnpm: '>=9.6'} + eslint-plugin-playwright@2.2.0: + resolution: {integrity: sha512-qSQpAw7RcSzE3zPp8FMGkthaCWovHZ/BsXtpmnGax9vQLIovlh1bsZHEa2+j2lv9DWhnyeLM/qZmp7ffQZfQvg==} + engines: {node: '>=16.6.0'} + peerDependencies: + eslint: '>=8.40.0' + eslint-plugin-unicorn@59.0.1: resolution: {integrity: sha512-EtNXYuWPUmkgSU2E7Ttn57LbRREQesIP1BiLn7OZLKodopKfDXfBUkC/0j6mpw2JExwf43Uf3qLSvrSvppgy8Q==} engines: {node: ^18.20.0 || ^20.10.0 || >=21.0.0} @@ -9376,10 +9566,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 vue-eslint-parser: ^10.0.0 - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-scope@8.4.0: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9409,10 +9595,6 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - esprima-next@5.8.4: resolution: {integrity: sha512-8nYVZ4ioIH4Msjb/XmhnBdz5WRRBaYqevKa1cv9nGJdCehMbzZCPNEEnqfLCZVetUVrUPEcb5IYyu1GG4hFqgg==} engines: {node: '>=12'} @@ -9494,6 +9676,10 @@ packages: resolution: {integrity: sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA==} engines: {node: '>=18.0.0'} + execa@1.0.0: + resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} + engines: {node: '>=6'} + execa@4.1.0: resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} engines: {node: '>=10'} @@ -9502,6 +9688,10 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + execa@9.6.0: + resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==} + engines: {node: ^18.19.0 || >=20.5.0} + executable@4.1.1: resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} engines: {node: '>=4'} @@ -9587,12 +9777,15 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-glob@3.2.12: resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} engines: {node: '>=8.6.0'} - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: @@ -9601,6 +9794,10 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} @@ -9662,6 +9859,10 @@ packages: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -9858,8 +10059,8 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} deprecated: This package is no longer supported. - gaxios@5.1.0: - resolution: {integrity: sha512-aezGIjb+/VfsJtIcHGcBSerNEDdfdHeMros+RbYbGpmonKWQCOVOes0LVZhn1lDtIgq55qq0HaxymIoae3Fl/A==} + gaxios@5.1.3: + resolution: {integrity: sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==} engines: {node: '>=12'} gaxios@6.6.0: @@ -9920,10 +10121,18 @@ packages: resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} engines: {node: '>=8'} + get-port@7.1.0: + resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} + engines: {node: '>=16'} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-stream@4.1.0: + resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} + engines: {node: '>=6'} + get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} @@ -9932,6 +10141,10 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + get-symbol-description@1.0.2: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} @@ -9944,9 +10157,6 @@ packages: resolution: {integrity: sha512-zzlgaYnHMIEgHRrfC7x0Qp0Ylhw/sHpM6MHXeVBTYIsvGf5GpbnClB+Q6rAPdn+0gd2oZZIo6Tj3EaWrt4VhDQ==} engines: {node: '>8.0.0'} - get-tsconfig@4.10.0: - resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} - get-tsconfig@4.10.1: resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} @@ -9956,6 +10166,10 @@ packages: getpass@0.1.7: resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + giget@1.2.5: + resolution: {integrity: sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==} + hasBin: true + github-buttons@2.29.1: resolution: {integrity: sha512-TV3YgAKda5hPz75n7QXmGCsSzgVya1vvmBieebg3EB5ScmashTZ0FldViG1aU2d4V5rcAGrtQ7k5uAaCo0A4PA==} @@ -10001,6 +10215,10 @@ packages: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -10084,6 +10302,10 @@ packages: has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} @@ -10231,6 +10453,10 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + humanize-duration@3.27.3: resolution: {integrity: sha512-iimHkHPfIAQ8zCDQLgn08pRqSVioyWvnGfaQ8gond2wf7Jq2jJ+24ykmnRyiz3fIldcn4oUuQXpjqKLhSVR7lw==} @@ -10476,6 +10702,10 @@ packages: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -10487,9 +10717,6 @@ packages: is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - is-map@2.0.2: - resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} - is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -10521,6 +10748,10 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-plain-object@5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} @@ -10549,9 +10780,6 @@ packages: resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} engines: {node: '>=10'} - is-set@2.0.2: - resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} - is-set@2.0.3: resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} @@ -10564,10 +10792,18 @@ packages: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} + is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -10599,8 +10835,9 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} - is-weakmap@2.0.1: - resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} @@ -10613,9 +10850,6 @@ packages: resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} engines: {node: '>= 0.4'} - is-weakset@2.0.2: - resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} - is-weakset@2.0.4: resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} engines: {node: '>= 0.4'} @@ -10862,6 +11096,10 @@ packages: resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} hasBin: true + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} @@ -11149,6 +11387,10 @@ packages: resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} engines: {node: '> 0.8'} + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + ldapts@4.2.6: resolution: {integrity: sha512-r1eOj2PtTJi+9aZxLirktoHntuYXlbQD9ZXCjiZmJx0VBQtBcWc+rueqABuh/AxMcFHNPDSJLJAXxoj5VevTwQ==} engines: {node: '>=14'} @@ -11240,69 +11482,9 @@ packages: lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} - lightningcss-darwin-arm64@1.30.1: - resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.30.1: - resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.30.1: - resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.30.1: - resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.30.1: - resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-arm64-musl@1.30.1: - resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - - lightningcss-linux-x64-gnu@1.30.1: - resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - lightningcss-linux-x64-musl@1.30.1: - resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - - lightningcss-win32-arm64-msvc@1.30.1: - resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.30.1: - resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.30.1: - resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} - engines: {node: '>= 12.0.0'} + lil-http-terminator@1.2.3: + resolution: {integrity: sha512-vQcHSwAFq/kTR2cG6peOVS7SjgksGgSPeH0G2lkw+buue33thE/FCHdn10wJXXshc5RswFy0Iaz48qA2Busw5Q==} + engines: {node: '>=12'} lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} @@ -11312,6 +11494,10 @@ packages: resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} engines: {node: '>=14'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -11456,8 +11642,8 @@ packages: lossless-json@4.0.2: resolution: {integrity: sha512-+z0EaLi2UcWi8MZRxA5iTb6m4Ys4E80uftGY+yG5KNFJb5EceQXOhdW/pWJZ8m97s26u7yZZAYMcKWNztSZssA==} - loupe@3.1.3: - resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + loupe@3.1.4: + resolution: {integrity: sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==} lower-case@1.1.4: resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} @@ -11679,8 +11865,8 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} engines: {node: 20 || >=22} minimatch@3.0.8: @@ -11689,8 +11875,8 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@5.1.5: - resolution: {integrity: sha512-CI8wwdrll4ehjPAqs8TL8lBPyNnpZlQI02Wn8C1weNz/QbUbjh3OMxgMKSnvqfKFdLlks3EzHB9tO0BqGc3phQ==} + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} minimatch@9.0.1: @@ -11867,6 +12053,9 @@ packages: engines: {node: '>=10'} hasBin: true + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + mlly@1.7.4: resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} @@ -11908,33 +12097,9 @@ packages: moment@2.29.4: resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} - mongodb-connection-string-url@2.6.0: - resolution: {integrity: sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==} - mongodb-connection-string-url@3.0.0: resolution: {integrity: sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==} - mongodb@5.9.2: - resolution: {integrity: sha512-H60HecKO4Bc+7dhOv4sJlgvenK4fQNqqUIlXxZYQNbfEWSALGAwGoyJd/0Qwk4TttFXUOHJ2ZJQe/52ScaUwtQ==} - engines: {node: '>=14.20.1'} - peerDependencies: - '@aws-sdk/credential-providers': ^3.188.0 - '@mongodb-js/zstd': ^1.0.0 - kerberos: ^1.0.0 || ^2.0.0 - mongodb-client-encryption: '>=2.3.0 <3' - snappy: ^7.2.2 - peerDependenciesMeta: - '@aws-sdk/credential-providers': - optional: true - '@mongodb-js/zstd': - optional: true - kerberos: - optional: true - mongodb-client-encryption: - optional: true - snappy: - optional: true - mongodb@6.11.0: resolution: {integrity: sha512-yVbPw0qT268YKhG241vAMLaDQAPbRyTgo++odSgGc9kXnzOujQI60Iyj23B9sQQFPSvmNPvMZ3dsFz0aN55KgA==} engines: {node: '>=16.20.1'} @@ -12070,6 +12235,9 @@ packages: nice-grpc@2.1.12: resolution: {integrity: sha512-J1n4Wg+D3IhRhGQb+iqh2OpiM0GzTve/kf2lnlW4S+xczmIEd0aHUDV1OsJ5a3q8GSTqJf+s4Rgg1M8uJltarw==} + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + no-case@2.3.2: resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} @@ -12110,6 +12278,9 @@ packages: resolution: {integrity: sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==} engines: {node: 4.x || >=6.0.0} + node-fetch-native@1.6.6: + resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -12209,10 +12380,18 @@ packages: engines: {node: ^18.17.0 || >=20.5.0, npm: '>= 9'} hasBin: true + npm-run-path@2.0.2: + resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} + engines: {node: '>=4'} + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + npmlog@6.0.2: resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -12230,6 +12409,11 @@ packages: nwsapi@2.2.7: resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} + nypm@0.5.4: + resolution: {integrity: sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + oas-kit-common@1.0.8: resolution: {integrity: sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==} @@ -12275,6 +12459,9 @@ packages: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} + object-sizeof@2.6.5: + resolution: {integrity: sha512-Mu3udRqIsKpneKjIEJ2U/s1KmEgpl+N6cEX1o+dDl2aZ+VW5piHqNgomqAk5YMsDoSkpcA8HnIKx1eqGTKzdfw==} + object.assign@4.1.5: resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} @@ -12298,12 +12485,19 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + ohash@1.1.6: + resolution: {integrity: sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg==} + ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} ollama@0.5.16: resolution: {integrity: sha512-OEbxxOIUZtdZgOaTPAULo051F5y+Z1vosxEYOoABPnQKeW7i4O8tJNlxCB+xioyoorVqgjkdj+TA1f1Hy2ug/w==} + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -12389,6 +12583,10 @@ packages: resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} engines: {node: '>=8'} + p-debounce@2.1.0: + resolution: {integrity: sha512-M9bMt62TTnozdZhqFgs+V7XD2MnuKCaz+7fZdlu2/T7xruI3uIE5CicQ0vx1hV7HIUYF0jF+4/R1AgfOkl74Qw==} + engines: {node: '>=6'} + p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -12456,6 +12654,14 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse-ms@2.1.0: + resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} + engines: {node: '>=6'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + parse-passwd@1.0.0: resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} engines: {node: '>=0.10.0'} @@ -12502,10 +12708,18 @@ packages: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -12556,6 +12770,9 @@ packages: pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + perfect-scrollbar@1.5.5: resolution: {integrity: sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g==} @@ -12647,8 +12864,18 @@ packages: typescript: optional: true - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + + pino@9.7.0: + resolution: {integrity: sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==} + hasBin: true + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} pkce-challenge@5.0.0: @@ -12659,19 +12886,22 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + pkg-types@1.1.3: + resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==} + pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} pkg-types@2.1.0: resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} - playwright-core@1.49.1: - resolution: {integrity: sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==} + playwright-core@1.53.0: + resolution: {integrity: sha512-mGLg8m0pm4+mmtB7M89Xw/GSqoNC+twivl8ITteqvAndachozYe2ZA7srU6uleV1vEdAHYqjq+SV8SNxRRFYBw==} engines: {node: '>=18'} hasBin: true - playwright@1.49.1: - resolution: {integrity: sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==} + playwright@1.53.0: + resolution: {integrity: sha512-ghGNnIEYZC4E+YtclRn4/p6oYbdPiASELBIYkBXfaTVKreQUYbMUYQDwS12a8F0/HtIjr/CkGjtwABeFPGcS4Q==} engines: {node: '>=18'} hasBin: true @@ -12690,6 +12920,10 @@ packages: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + postcss-import@15.1.0: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} @@ -12742,6 +12976,10 @@ packages: resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} engines: {node: '>=4'} + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -12753,10 +12991,6 @@ packages: resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.3: - resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -12837,6 +13071,14 @@ packages: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-ms@7.0.1: + resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} + engines: {node: '>=10'} + + pretty-ms@9.2.0: + resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==} + engines: {node: '>=18'} + prismjs@1.29.0: resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} engines: {node: '>=6'} @@ -12844,6 +13086,9 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} @@ -12887,6 +13132,13 @@ packages: resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} engines: {node: '>= 8'} + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + + properties-reader@2.3.0: + resolution: {integrity: sha512-z597WicA7nDZxK12kZqHr2TcvwNU1GCfA5UwfDY/HDp3hXPoPlb5rlEx9bwGTiJnc0OqbBTkU975jDToth8Gxw==} + engines: {node: '>=14'} + property-expr@2.0.5: resolution: {integrity: sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==} @@ -13004,10 +13256,16 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + quoted-printable@1.0.1: resolution: {integrity: sha512-cihC68OcGiQOjGiXuo5Jk6XHANTHl1K4JLk/xlEJRTIXfy19Sg6XzB95XonYgr+1rB88bCpr7WZE7D7AlZow4g==} hasBin: true + ramda@0.26.1: + resolution: {integrity: sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==} + random-bytes@1.0.0: resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==} engines: {node: '>= 0.8'} @@ -13023,6 +13281,9 @@ packages: resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} engines: {node: '>= 0.8'} + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -13085,14 +13346,25 @@ packages: resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==} engines: {node: '>=8'} + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + readdirp@4.0.2: resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} engines: {node: '>= 14.16.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + readline-sync@1.4.10: resolution: {integrity: sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==} engines: {node: '>= 0.8.0'} + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + recast@0.22.0: resolution: {integrity: sha512-5AAx+mujtXijsEavc5lWXBPQqrM4+Dl5qNH96N2aNeuJFUzpiiToKPsxQD/zAIJHspz7zz0maX0PCtCTFVlixQ==} engines: {node: '>= 4'} @@ -13160,6 +13432,10 @@ packages: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true + regexp.escape@2.0.1: + resolution: {integrity: sha512-JItRb4rmyTzmERBkAf6J87LjDPy/RscIwmaJQ3gsFlAzrmZbZU8LwBw5IydFZXW9hqpgbPlGbMhtpqtuAhMgtg==} + engines: {node: '>= 0.4'} + regexp.prototype.flags@1.5.3: resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} @@ -13239,6 +13515,11 @@ packages: resolution: {integrity: sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==} engines: {node: '>=10'} + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -13301,8 +13582,8 @@ packages: rndm@1.2.0: resolution: {integrity: sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw==} - rollup@4.44.1: - resolution: {integrity: sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==} + rollup@4.44.0: + resolution: {integrity: sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -13473,10 +13754,18 @@ packages: resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} @@ -13617,6 +13906,9 @@ packages: resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + sortablejs@1.14.0: resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==} @@ -13648,6 +13940,9 @@ packages: resolution: {integrity: sha512-VNiXjFp6R4ldPbVRYbpxlD35yRHceecVXlct1J4/X80KuuPnW2AXMq3sGwhnJOhKkUsOxAT6nRGfGE5pocVw5w==} engines: {node: '>=10.0.0'} + split-ca@1.0.1: + resolution: {integrity: sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==} + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -13671,6 +13966,9 @@ packages: resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} engines: {node: '>= 0.6'} + ssh-remote-port-forward@1.0.4: + resolution: {integrity: sha512-x0LV1eVDwjf1gmG7TTnfqIzf+3VPRz7vrNIjX6oYLbeCrf/PeVY6hkT68Mg+q02qXxQhrLjB0jfgvhevoCRmLQ==} + ssh2-sftp-client@7.2.3: resolution: {integrity: sha512-Bmq4Uewu3e0XOwu5bnPbiS5KRQYv+dff5H6+85V4GZrPrt0Fkt1nUH+uXanyAkoNxUpzjnAPEEoLdOaBO9c3xw==} engines: {node: '>=10.24.1'} @@ -13688,8 +13986,8 @@ packages: resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} engines: {node: '>= 8'} - stable-hash-x@0.2.0: - resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} + stable-hash-x@0.1.1: + resolution: {integrity: sha512-l0x1D6vhnsNUGPFVDx45eif0y6eedVC8nm5uACTrVFJFtl2mLRW17aWtVyxFCpn5t94VUPkjU8vSLwIuwwqtJQ==} engines: {node: '>=12.0.0'} stack-trace@0.0.10: @@ -13723,10 +14021,6 @@ packages: stickyfill@1.1.1: resolution: {integrity: sha512-GCp7vHAfpao+Qh/3Flh9DXEJ/qSi0KJwJw6zYlZOtRYXWUIpMM6mC2rIep/dK8RQqwW0KxGJIllmjPIBOGN8AA==} - stop-iteration-iterator@1.0.0: - resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} - engines: {node: '>= 0.4'} - stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -13760,6 +14054,9 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + streamx@2.22.1: + resolution: {integrity: sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==} + strict-event-emitter-types@2.0.0: resolution: {integrity: sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==} @@ -13790,9 +14087,6 @@ packages: resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} engines: {node: '>= 0.4'} - string.prototype.trimend@1.0.8: - resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} - string.prototype.trimend@1.0.9: resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} engines: {node: '>= 0.4'} @@ -13826,10 +14120,18 @@ packages: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} + strip-eof@1.0.0: + resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} + engines: {node: '>=0.10.0'} + strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -13940,6 +14242,9 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} @@ -13976,6 +14281,12 @@ packages: resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} + testcontainers@11.0.3: + resolution: {integrity: sha512-Xu6ZAaE1FaLyHzFSYdCsd+xMPxUegUjkum0r6zgO8SinnFDHRX/PllIHMt1D+DVUmJqBvPQI6vge/J5jgE5vng==} + + text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + text-hex@1.0.0: resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} @@ -13990,6 +14301,9 @@ packages: resolution: {integrity: sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==} engines: {node: '>=0.2.6'} + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + throttleit@1.0.0: resolution: {integrity: sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==} @@ -14012,8 +14326,8 @@ packages: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} - tinypool@1.0.2: - resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} tinyrainbow@1.2.0: @@ -14049,10 +14363,6 @@ packages: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} - tmp@0.2.1: - resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} - engines: {node: '>=8.17.0'} - tmp@0.2.3: resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} engines: {node: '>=14.14'} @@ -14138,9 +14448,9 @@ packages: triple-beam@1.3.0: resolution: {integrity: sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==} - ts-api-utils@1.0.1: - resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==} - engines: {node: '>=16.13.0'} + ts-api-utils@1.4.3: + resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} + engines: {node: '>=16'} peerDependencies: typescript: 5.8.3 @@ -14173,7 +14483,7 @@ packages: ts-ics@1.2.2: resolution: {integrity: sha512-L7T5JQi99qQ2Uv7AoCHUZ8Mx1bJYo7qBZtBckuHueR90I3WVdW5NC/tOqTVgu18c3zj08du+xlgWlTIcE+Foxw==} peerDependencies: - date-fns: ^2 + date-fns: 2.30.0 lodash: ^4 zod: 3.25.67 @@ -14218,6 +14528,9 @@ packages: '@swc/wasm': optional: true + ts-pattern@5.7.1: + resolution: {integrity: sha512-EGs8PguQqAAUIcQfK4E9xdXxB6s2GK4sJfT/vcc9V1ELIvC4LH/zXu2t/5fajtv6oiRCxdv7BgtVK3vWgROxag==} + ts-toolbelt@9.6.0: resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} @@ -14336,6 +14649,10 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} @@ -14419,6 +14736,9 @@ packages: ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + uglify-js@3.17.4: resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} engines: {node: '>=0.8.0'} @@ -14447,6 +14767,9 @@ packages: undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici@6.21.3: resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} engines: {node: '>=18.17'} @@ -14471,6 +14794,10 @@ packages: resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} engines: {node: '>=4'} + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + unique-filename@1.1.1: resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} @@ -14539,6 +14866,12 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + upper-case-first@2.0.2: resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} @@ -14826,11 +15159,11 @@ packages: peerDependencies: vue: '>=2' - vue-eslint-parser@9.4.2: - resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==} - engines: {node: ^14.17.0 || >=16.0.0} + vue-eslint-parser@10.1.3: + resolution: {integrity: sha512-dbCBnd2e02dYWsXoqX5yKUZlOt+ExIpq7hmHKPb5ZqKcjf++Eo0hMseFTZMLKThrUk61m+Uv6A2YSBve6ZvuDQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: '>=6.0.0' + eslint: ^8.57.0 || ^9.0.0 vue-github-button@3.1.3: resolution: {integrity: sha512-ZdOnUuYJL/wUsxISsC96TARzCdf1twaWooZoI14+g4RHsJltPY+Agw6Ox6pjuMqMX0uhSK1JOMFUFNCQGlcZGA==} @@ -15002,9 +15335,6 @@ packages: resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} engines: {node: '>= 0.4'} - which-collection@1.0.1: - resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} - which-collection@1.0.2: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} @@ -15017,6 +15347,10 @@ packages: resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} engines: {node: '>= 0.4'} + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -15246,10 +15580,18 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + yup@0.32.11: resolution: {integrity: sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==} engines: {node: '>=10'} + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + zod-class@0.0.16: resolution: {integrity: sha512-3A1l81VEUOxvSTGoNPsU4fTUY9CKin/HSySnXT3bIc+TJTDGCPbzSPE8W1VvwXqyzHEIWK608eFZja2uew9Ivw==} peerDependencies: @@ -15307,7 +15649,7 @@ snapshots: '@anthropic-ai/sdk@0.27.3(encoding@0.1.13)': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/node-fetch': 2.6.12 abort-controller: 3.0.0 agentkeepalive: 4.6.0 @@ -15319,7 +15661,7 @@ snapshots: '@anthropic-ai/sdk@0.39.0(encoding@0.1.13)': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/node-fetch': 2.6.12 abort-controller: 3.0.0 agentkeepalive: 4.6.0 @@ -16407,6 +16749,12 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/compat-data@7.26.8': {} '@babel/compat-data@7.27.5': {} @@ -16434,10 +16782,10 @@ snapshots: '@babel/generator@7.26.10': dependencies: '@babel/parser': 7.27.5 - '@babel/types': 7.26.10 + '@babel/types': 7.27.6 '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - jsesc: 3.0.2 + jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.25.9': dependencies: @@ -16486,7 +16834,7 @@ snapshots: '@babel/helper-plugin-utils': 7.27.1 debug: 4.4.1(supports-color@8.1.1) lodash.debounce: 4.0.8 - resolve: 1.22.8 + resolve: 1.22.10 transitivePeerDependencies: - supports-color @@ -16542,7 +16890,7 @@ snapshots: '@babel/helper-skip-transparent-expression-wrappers@7.25.9': dependencies: '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color @@ -16560,14 +16908,14 @@ snapshots: dependencies: '@babel/template': 7.26.9 '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 + '@babel/types': 7.27.6 transitivePeerDependencies: - supports-color '@babel/helpers@7.26.10': dependencies: '@babel/template': 7.26.9 - '@babel/types': 7.26.10 + '@babel/types': 7.27.6 '@babel/parser@7.26.10': dependencies: @@ -17096,7 +17444,7 @@ snapshots: babel-plugin-polyfill-corejs2: 0.4.12(@babel/core@7.26.10) babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.26.10) babel-plugin-polyfill-regenerator: 0.6.3(@babel/core@7.26.10) - core-js-compat: 3.41.0 + core-js-compat: 3.43.0 semver: 7.7.2 transitivePeerDependencies: - supports-color @@ -17105,7 +17453,7 @@ snapshots: dependencies: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.27.1 - '@babel/types': 7.26.10 + '@babel/types': 7.27.6 esutils: 2.0.3 '@babel/runtime@7.26.10': @@ -17124,7 +17472,7 @@ snapshots: '@babel/generator': 7.26.10 '@babel/parser': 7.27.5 '@babel/template': 7.26.9 - '@babel/types': 7.26.10 + '@babel/types': 7.27.6 debug: 4.4.1(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: @@ -17140,6 +17488,8 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@balena/dockerignore@1.0.2': {} + '@bcoe/v8-coverage@0.2.3': {} '@bcoe/v8-coverage@1.0.2': {} @@ -17181,7 +17531,7 @@ snapshots: '@browserbasehq/sdk@2.6.0(encoding@0.1.13)': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/node-fetch': 2.6.12 abort-controller: 3.0.0 agentkeepalive: 4.6.0 @@ -17191,11 +17541,11 @@ snapshots: transitivePeerDependencies: - encoding - '@browserbasehq/stagehand@1.9.0(@playwright/test@1.49.1)(deepmerge@4.3.1)(dotenv@16.5.0)(encoding@0.1.13)(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67))(zod@3.25.67)': + '@browserbasehq/stagehand@1.9.0(@playwright/test@1.53.0)(deepmerge@4.3.1)(dotenv@16.5.0)(encoding@0.1.13)(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67))(zod@3.25.67)': dependencies: '@anthropic-ai/sdk': 0.27.3(encoding@0.1.13) '@browserbasehq/sdk': 2.6.0(encoding@0.1.13) - '@playwright/test': 1.49.1 + '@playwright/test': 1.53.0 deepmerge: 4.3.1 dotenv: 16.5.0 openai: 4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67) @@ -17327,6 +17677,10 @@ snapshots: '@colors/colors@1.6.0': {} + '@commander-js/extra-typings@12.1.0(commander@12.1.0)': + dependencies: + commander: 12.1.0 + '@common.js/is-network-error@1.0.1': {} '@cspotcode/source-map-support@0.8.1': @@ -17336,6 +17690,60 @@ snapshots: '@ctrl/tinycolor@3.6.0': {} + '@currents/commit-info@1.0.1-beta.0': + dependencies: + bluebird: 3.5.5 + check-more-types: 2.24.0 + debug: 4.3.4 + execa: 1.0.0 + lazy-ass: 1.6.0 + ramda: 0.26.1 + transitivePeerDependencies: + - supports-color + + '@currents/playwright@1.14.1(magicast@0.3.5)': + dependencies: + '@babel/code-frame': 7.27.1 + '@commander-js/extra-typings': 12.1.0(commander@12.1.0) + '@currents/commit-info': 1.0.1-beta.0 + async-retry: 1.3.3 + axios: 1.10.0(debug@4.4.1) + axios-retry: 4.5.0(axios@1.10.0(debug@4.4.1)) + c12: 1.11.2(magicast@0.3.5) + chalk: 4.1.2 + commander: 12.1.0 + date-fns: 2.30.0 + debug: 4.4.1(supports-color@8.1.1) + dotenv: 16.5.0 + execa: 9.6.0 + getos: 3.2.1 + https-proxy-agent: 7.0.6 + istanbul-lib-coverage: 3.2.2 + json-stringify-safe: 5.0.1 + lil-http-terminator: 1.2.3 + lodash: 4.17.21 + nanoid: 3.3.8 + object-sizeof: 2.6.5 + p-debounce: 2.1.0 + p-map: 4.0.0 + p-queue: 6.6.2 + pino: 9.7.0 + pluralize: 8.0.0 + pretty-ms: 7.0.1 + proxy-from-env: 1.1.0 + regexp.escape: 2.0.1 + source-map-support: 0.5.21 + stack-utils: 2.0.6 + tmp: 0.2.3 + tmp-promise: 3.0.3 + ts-pattern: 5.7.1 + ws: 8.18.2 + transitivePeerDependencies: + - bufferutil + - magicast + - supports-color + - utf-8-validate + '@cypress/grep@4.1.0(@babel/core@7.26.10)(cypress@14.4.0)': dependencies: cypress: 14.4.0 @@ -17414,86 +17822,89 @@ snapshots: '@emotion/unitless@0.8.0': {} - '@esbuild/aix-ppc64@0.24.0': + '@esbuild/aix-ppc64@0.24.2': optional: true - '@esbuild/android-arm64@0.24.0': + '@esbuild/android-arm64@0.24.2': optional: true - '@esbuild/android-arm@0.24.0': + '@esbuild/android-arm@0.24.2': optional: true - '@esbuild/android-x64@0.24.0': + '@esbuild/android-x64@0.24.2': optional: true - '@esbuild/darwin-arm64@0.24.0': + '@esbuild/darwin-arm64@0.24.2': optional: true - '@esbuild/darwin-x64@0.24.0': + '@esbuild/darwin-x64@0.24.2': optional: true - '@esbuild/freebsd-arm64@0.24.0': + '@esbuild/freebsd-arm64@0.24.2': optional: true - '@esbuild/freebsd-x64@0.24.0': + '@esbuild/freebsd-x64@0.24.2': optional: true - '@esbuild/linux-arm64@0.24.0': + '@esbuild/linux-arm64@0.24.2': optional: true - '@esbuild/linux-arm@0.24.0': + '@esbuild/linux-arm@0.24.2': optional: true - '@esbuild/linux-ia32@0.24.0': + '@esbuild/linux-ia32@0.24.2': optional: true - '@esbuild/linux-loong64@0.24.0': + '@esbuild/linux-loong64@0.24.2': optional: true - '@esbuild/linux-mips64el@0.24.0': + '@esbuild/linux-mips64el@0.24.2': optional: true - '@esbuild/linux-ppc64@0.24.0': + '@esbuild/linux-ppc64@0.24.2': optional: true - '@esbuild/linux-riscv64@0.24.0': + '@esbuild/linux-riscv64@0.24.2': optional: true - '@esbuild/linux-s390x@0.24.0': + '@esbuild/linux-s390x@0.24.2': optional: true - '@esbuild/linux-x64@0.24.0': + '@esbuild/linux-x64@0.24.2': optional: true - '@esbuild/netbsd-x64@0.24.0': + '@esbuild/netbsd-arm64@0.24.2': optional: true - '@esbuild/openbsd-arm64@0.24.0': + '@esbuild/netbsd-x64@0.24.2': optional: true - '@esbuild/openbsd-x64@0.24.0': + '@esbuild/openbsd-arm64@0.24.2': optional: true - '@esbuild/sunos-x64@0.24.0': + '@esbuild/openbsd-x64@0.24.2': optional: true - '@esbuild/win32-arm64@0.24.0': + '@esbuild/sunos-x64@0.24.2': optional: true - '@esbuild/win32-ia32@0.24.0': + '@esbuild/win32-arm64@0.24.2': optional: true - '@esbuild/win32-x64@0.24.0': + '@esbuild/win32-ia32@0.24.2': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.29.0(jiti@1.21.0))': + '@esbuild/win32-x64@0.24.2': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@9.29.0(jiti@1.21.7))': dependencies: - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@1.21.0))': + '@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@1.21.7))': dependencies: - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -17516,7 +17927,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@0.15.1': + '@eslint/core@0.15.0': dependencies: '@types/json-schema': 7.0.15 @@ -17543,9 +17954,9 @@ snapshots: '@eslint/core': 0.13.0 levn: 0.4.1 - '@eslint/plugin-kit@0.3.3': + '@eslint/plugin-kit@0.3.2': dependencies: - '@eslint/core': 0.15.1 + '@eslint/core': 0.15.0 levn: 0.4.1 '@ewoudenberg/difflib@0.1.0': @@ -17600,7 +18011,7 @@ snapshots: '@gar/promisify@1.1.3': optional: true - '@getzep/zep-cloud@1.0.12(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.28(d0079d2993dfd2a4e9e2c2f03851bb21))': + '@getzep/zep-cloud@1.0.12(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.28(f9561c3b67724aa0f177a38a80041072))': dependencies: form-data: 4.0.0 node-fetch: 2.7.0(encoding@0.1.13) @@ -17609,7 +18020,7 @@ snapshots: zod: 3.25.67 optionalDependencies: '@langchain/core': 0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)) - langchain: 0.3.28(d0079d2993dfd2a4e9e2c2f03851bb21) + langchain: 0.3.28(f9561c3b67724aa0f177a38a80041072) transitivePeerDependencies: - encoding @@ -17686,7 +18097,7 @@ snapshots: '@grpc/proto-loader@0.7.13': dependencies: lodash.camelcase: 4.3.0 - long: 5.2.3 + long: 5.3.2 protobufjs: 7.4.0 yargs: 17.7.2 @@ -17717,7 +18128,7 @@ snapshots: '@ibm-cloud/watsonx-ai@1.1.2': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 extend: 3.0.2 ibm-cloud-sdk-core: 5.3.2 transitivePeerDependencies: @@ -17747,7 +18158,7 @@ snapshots: debug: 4.4.1(supports-color@8.1.1) kolorist: 1.8.0 local-pkg: 0.5.0 - mlly: 1.7.4 + mlly: 1.7.1 transitivePeerDependencies: - supports-color @@ -17850,6 +18261,12 @@ snapshots: '@ioredis/commands@1.2.0': {} + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -17872,7 +18289,7 @@ snapshots: '@jest/console@29.6.2': dependencies: '@jest/types': 29.6.1 - '@types/node': 20.17.57 + '@types/node': 20.19.1 chalk: 4.1.2 jest-message-util: 29.6.2 jest-util: 29.6.2 @@ -17913,6 +18330,41 @@ snapshots: - supports-color - ts-node + '@jest/core@29.6.2(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3))': + dependencies: + '@jest/console': 29.6.2 + '@jest/reporters': 29.6.2 + '@jest/test-result': 29.6.2 + '@jest/transform': 29.6.2 + '@jest/types': 29.6.1 + '@types/node': 20.17.57 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.8.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.5.0 + jest-config: 29.6.2(@types/node@20.17.57)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) + jest-haste-map: 29.6.2 + jest-message-util: 29.6.2 + jest-regex-util: 29.4.3 + jest-resolve: 29.6.2 + jest-resolve-dependencies: 29.6.2 + jest-runner: 29.6.2 + jest-runtime: 29.6.2 + jest-snapshot: 29.6.2 + jest-util: 29.6.2 + jest-validate: 29.6.2 + jest-watcher: 29.6.2 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + '@jest/environment@29.6.2': dependencies: '@jest/fake-timers': 29.6.2 @@ -17957,7 +18409,7 @@ snapshots: '@jest/transform': 29.6.2 '@jest/types': 29.6.1 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.17.57 + '@types/node': 20.19.1 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -18024,7 +18476,7 @@ snapshots: jest-regex-util: 29.4.3 jest-util: 29.6.2 micromatch: 4.0.8 - pirates: 4.0.6 + pirates: 4.0.7 slash: 3.0.0 write-file-atomic: 4.0.2 transitivePeerDependencies: @@ -18124,9 +18576,9 @@ snapshots: - aws-crt - encoding - '@langchain/community@0.3.46(10ae15256126511fe3944d0a838f3cc8)': + '@langchain/community@0.3.46(6de8a673a24e563cf8f4ca63f57e8b8d)': dependencies: - '@browserbasehq/stagehand': 1.9.0(@playwright/test@1.49.1)(deepmerge@4.3.1)(dotenv@16.5.0)(encoding@0.1.13)(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67))(zod@3.25.67) + '@browserbasehq/stagehand': 1.9.0(@playwright/test@1.53.0)(deepmerge@4.3.1)(dotenv@16.5.0)(encoding@0.1.13)(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67))(zod@3.25.67) '@ibm-cloud/watsonx-ai': 1.1.2 '@langchain/core': 0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)) '@langchain/openai': 0.5.13(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(encoding@0.1.13)(ws@8.18.2) @@ -18136,7 +18588,7 @@ snapshots: flat: 5.0.2 ibm-cloud-sdk-core: 5.3.2 js-yaml: 4.1.0 - langchain: 0.3.28(d0079d2993dfd2a4e9e2c2f03851bb21) + langchain: 0.3.28(f9561c3b67724aa0f177a38a80041072) langsmith: 0.3.33(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)) openai: 4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67) uuid: 10.0.0 @@ -18150,7 +18602,7 @@ snapshots: '@aws-sdk/credential-provider-node': 3.808.0 '@azure/storage-blob': 12.26.0 '@browserbasehq/sdk': 2.6.0(encoding@0.1.13) - '@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.28(d0079d2993dfd2a4e9e2c2f03851bb21)) + '@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.28(f9561c3b67724aa0f177a38a80041072)) '@getzep/zep-js': 0.9.0 '@google-ai/generativelanguage': 2.6.0(encoding@0.1.13) '@google-cloud/storage': 7.12.1(encoding@0.1.13) @@ -18183,7 +18635,7 @@ snapshots: mysql2: 3.11.0 pdf-parse: 1.1.1 pg: 8.12.0 - playwright: 1.49.1 + playwright: 1.53.0 redis: 4.6.12 weaviate-client: 3.6.2(encoding@0.1.13) ws: 8.18.2 @@ -18400,23 +18852,23 @@ snapshots: '@types/react': 18.0.27 react: 18.2.0 - '@microsoft/api-extractor-model@7.30.4(@types/node@20.17.57)': + '@microsoft/api-extractor-model@7.30.4(@types/node@20.19.1)': dependencies: '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.12.0(@types/node@20.17.57) + '@rushstack/node-core-library': 5.12.0(@types/node@20.19.1) transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.52.1(@types/node@20.17.57)': + '@microsoft/api-extractor@7.52.1(@types/node@20.19.1)': dependencies: - '@microsoft/api-extractor-model': 7.30.4(@types/node@20.17.57) + '@microsoft/api-extractor-model': 7.30.4(@types/node@20.19.1) '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.12.0(@types/node@20.17.57) + '@rushstack/node-core-library': 5.12.0(@types/node@20.19.1) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.15.1(@types/node@20.17.57) - '@rushstack/ts-command-line': 4.23.6(@types/node@20.17.57) + '@rushstack/terminal': 0.15.1(@types/node@20.19.1) + '@rushstack/ts-command-line': 4.23.6(@types/node@20.19.1) lodash: 4.17.21 minimatch: 3.0.8 resolve: 1.22.8 @@ -18503,7 +18955,7 @@ snapshots: '@n8n/localtunnel@3.0.0': dependencies: - axios: 1.9.0(debug@4.3.6) + axios: 1.10.0(debug@4.3.6) debug: 4.3.6(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -18521,39 +18973,7 @@ snapshots: esprima-next: 5.8.4 recast: 0.22.0 - '@n8n/typeorm@0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mongodb@5.9.2(@aws-sdk/credential-providers@3.808.0))(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.14)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3))': - dependencies: - '@n8n/p-retry': 6.2.0-2 - '@sqltools/formatter': 1.2.5 - app-root-path: 3.1.0 - async-mutex: 0.5.0 - buffer: 6.0.3 - chalk: 4.1.2 - dayjs: 1.11.10 - debug: 4.4.1(supports-color@8.1.1) - dotenv: 16.5.0 - glob: 10.4.5 - mkdirp: 2.1.3 - reflect-metadata: 0.2.2 - sha.js: 2.4.11 - tarn: 3.0.2 - tslib: 2.8.1 - uuid: 9.0.1 - yargs: 17.7.2 - optionalDependencies: - '@sentry/node': 8.52.1 - ioredis: 5.3.2 - mongodb: 5.9.2(@aws-sdk/credential-providers@3.808.0) - mssql: 10.0.2 - mysql2: 3.11.0 - pg: 8.12.0 - redis: 4.6.14 - sqlite3: 5.1.7 - ts-node: 10.9.2(@types/node@20.17.57)(typescript@5.8.3) - transitivePeerDependencies: - - supports-color - - '@n8n/typeorm@0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mongodb@6.11.0(@aws-sdk/credential-providers@3.808.0)(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.8.3))(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.12)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3))': + '@n8n/typeorm@0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mongodb@6.11.0(@aws-sdk/credential-providers@3.808.0)(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.8.3))(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.12)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3))': dependencies: '@n8n/p-retry': 6.2.0-2 '@sqltools/formatter': 1.2.5 @@ -18581,7 +19001,38 @@ snapshots: pg: 8.12.0 redis: 4.6.12 sqlite3: 5.1.7 - ts-node: 10.9.2(@types/node@20.17.57)(typescript@5.8.3) + ts-node: 10.9.2(@types/node@20.19.1)(typescript@5.8.3) + transitivePeerDependencies: + - supports-color + + '@n8n/typeorm@0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.14)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3))': + dependencies: + '@n8n/p-retry': 6.2.0-2 + '@sqltools/formatter': 1.2.5 + app-root-path: 3.1.0 + async-mutex: 0.5.0 + buffer: 6.0.3 + chalk: 4.1.2 + dayjs: 1.11.10 + debug: 4.4.1(supports-color@8.1.1) + dotenv: 16.5.0 + glob: 10.4.5 + mkdirp: 2.1.3 + reflect-metadata: 0.2.2 + sha.js: 2.4.11 + tarn: 3.0.2 + tslib: 2.8.1 + uuid: 9.0.1 + yargs: 17.7.2 + optionalDependencies: + '@sentry/node': 8.52.1 + ioredis: 5.3.2 + mssql: 10.0.2 + mysql2: 3.11.0 + pg: 8.12.0 + redis: 4.6.14 + sqlite3: 5.1.7 + ts-node: 10.9.2(@types/node@20.19.1)(typescript@5.8.3) transitivePeerDependencies: - supports-color @@ -18603,48 +19054,48 @@ snapshots: dependencies: eslint-config-riot: 1.0.0 - '@napi-rs/canvas-android-arm64@0.1.71': + '@napi-rs/canvas-android-arm64@0.1.70': optional: true - '@napi-rs/canvas-darwin-arm64@0.1.71': + '@napi-rs/canvas-darwin-arm64@0.1.70': optional: true - '@napi-rs/canvas-darwin-x64@0.1.71': + '@napi-rs/canvas-darwin-x64@0.1.70': optional: true - '@napi-rs/canvas-linux-arm-gnueabihf@0.1.71': + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.70': optional: true - '@napi-rs/canvas-linux-arm64-gnu@0.1.71': + '@napi-rs/canvas-linux-arm64-gnu@0.1.70': optional: true - '@napi-rs/canvas-linux-arm64-musl@0.1.71': + '@napi-rs/canvas-linux-arm64-musl@0.1.70': optional: true - '@napi-rs/canvas-linux-riscv64-gnu@0.1.71': + '@napi-rs/canvas-linux-riscv64-gnu@0.1.70': optional: true - '@napi-rs/canvas-linux-x64-gnu@0.1.71': + '@napi-rs/canvas-linux-x64-gnu@0.1.70': optional: true - '@napi-rs/canvas-linux-x64-musl@0.1.71': + '@napi-rs/canvas-linux-x64-musl@0.1.70': optional: true - '@napi-rs/canvas-win32-x64-msvc@0.1.71': + '@napi-rs/canvas-win32-x64-msvc@0.1.70': optional: true - '@napi-rs/canvas@0.1.71': + '@napi-rs/canvas@0.1.70': optionalDependencies: - '@napi-rs/canvas-android-arm64': 0.1.71 - '@napi-rs/canvas-darwin-arm64': 0.1.71 - '@napi-rs/canvas-darwin-x64': 0.1.71 - '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.71 - '@napi-rs/canvas-linux-arm64-gnu': 0.1.71 - '@napi-rs/canvas-linux-arm64-musl': 0.1.71 - '@napi-rs/canvas-linux-riscv64-gnu': 0.1.71 - '@napi-rs/canvas-linux-x64-gnu': 0.1.71 - '@napi-rs/canvas-linux-x64-musl': 0.1.71 - '@napi-rs/canvas-win32-x64-msvc': 0.1.71 + '@napi-rs/canvas-android-arm64': 0.1.70 + '@napi-rs/canvas-darwin-arm64': 0.1.70 + '@napi-rs/canvas-darwin-x64': 0.1.70 + '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.70 + '@napi-rs/canvas-linux-arm64-gnu': 0.1.70 + '@napi-rs/canvas-linux-arm64-musl': 0.1.70 + '@napi-rs/canvas-linux-riscv64-gnu': 0.1.70 + '@napi-rs/canvas-linux-x64-gnu': 0.1.70 + '@napi-rs/canvas-linux-x64-musl': 0.1.70 + '@napi-rs/canvas-win32-x64-msvc': 0.1.70 optional: true '@napi-rs/wasm-runtime@0.2.11': @@ -19033,9 +19484,9 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@playwright/test@1.49.1': + '@playwright/test@1.53.0': dependencies: - playwright: 1.49.1 + playwright: 1.53.0 '@prisma/instrumentation@5.22.0': dependencies: @@ -19173,7 +19624,7 @@ snapshots: https-proxy-agent: 7.0.6 js-levenshtein: 1.1.6 js-yaml: 4.1.0 - minimatch: 5.1.5 + minimatch: 5.1.6 pluralize: 8.0.0 yaml-ast-parser: 0.0.43 transitivePeerDependencies: @@ -19185,72 +19636,72 @@ snapshots: '@codemirror/state': 6.4.1 '@codemirror/view': 6.26.3 - '@rollup/pluginutils@5.1.4(rollup@4.44.1)': + '@rollup/pluginutils@5.1.4(rollup@4.44.0)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.2 optionalDependencies: - rollup: 4.44.1 + rollup: 4.44.0 - '@rollup/rollup-android-arm-eabi@4.44.1': + '@rollup/rollup-android-arm-eabi@4.44.0': optional: true - '@rollup/rollup-android-arm64@4.44.1': + '@rollup/rollup-android-arm64@4.44.0': optional: true - '@rollup/rollup-darwin-arm64@4.44.1': + '@rollup/rollup-darwin-arm64@4.44.0': optional: true - '@rollup/rollup-darwin-x64@4.44.1': + '@rollup/rollup-darwin-x64@4.44.0': optional: true - '@rollup/rollup-freebsd-arm64@4.44.1': + '@rollup/rollup-freebsd-arm64@4.44.0': optional: true - '@rollup/rollup-freebsd-x64@4.44.1': + '@rollup/rollup-freebsd-x64@4.44.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.44.1': + '@rollup/rollup-linux-arm-gnueabihf@4.44.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.44.1': + '@rollup/rollup-linux-arm-musleabihf@4.44.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.44.1': + '@rollup/rollup-linux-arm64-gnu@4.44.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.44.1': + '@rollup/rollup-linux-arm64-musl@4.44.0': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.44.1': + '@rollup/rollup-linux-loongarch64-gnu@4.44.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.44.1': + '@rollup/rollup-linux-powerpc64le-gnu@4.44.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.44.1': + '@rollup/rollup-linux-riscv64-gnu@4.44.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.44.1': + '@rollup/rollup-linux-riscv64-musl@4.44.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.44.1': + '@rollup/rollup-linux-s390x-gnu@4.44.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.44.1': + '@rollup/rollup-linux-x64-gnu@4.44.0': optional: true - '@rollup/rollup-linux-x64-musl@4.44.1': + '@rollup/rollup-linux-x64-musl@4.44.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.44.1': + '@rollup/rollup-win32-arm64-msvc@4.44.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.44.1': + '@rollup/rollup-win32-ia32-msvc@4.44.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.44.1': + '@rollup/rollup-win32-x64-msvc@4.44.0': optional: true '@rtsao/scc@1.1.0': {} @@ -19275,7 +19726,7 @@ snapshots: - debug - supports-color - '@rushstack/node-core-library@5.12.0(@types/node@20.17.57)': + '@rushstack/node-core-library@5.12.0(@types/node@20.19.1)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -19286,29 +19737,31 @@ snapshots: resolve: 1.22.8 semver: 7.7.2 optionalDependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@rushstack/rig-package@0.5.3': dependencies: resolve: 1.22.8 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.15.1(@types/node@20.17.57)': + '@rushstack/terminal@0.15.1(@types/node@20.19.1)': dependencies: - '@rushstack/node-core-library': 5.12.0(@types/node@20.17.57) + '@rushstack/node-core-library': 5.12.0(@types/node@20.19.1) supports-color: 8.1.1 optionalDependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 - '@rushstack/ts-command-line@4.23.6(@types/node@20.17.57)': + '@rushstack/ts-command-line@4.23.6(@types/node@20.19.1)': dependencies: - '@rushstack/terminal': 0.15.1(@types/node@20.17.57) + '@rushstack/terminal': 0.15.1(@types/node@20.19.1) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.1 transitivePeerDependencies: - '@types/node' + '@sec-ant/readable-stream@0.4.1': {} + '@selderee/plugin-htmlparser2@0.11.0': dependencies: domhandler: 5.0.3 @@ -19434,6 +19887,8 @@ snapshots: '@sinclair/typebox@0.27.8': {} + '@sindresorhus/merge-streams@4.0.0': {} + '@sinonjs/commons@2.0.0': dependencies: type-detect: 4.0.8 @@ -19999,13 +20454,13 @@ snapshots: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - '@storybook/builder-vite@8.6.4(storybook@8.6.4(prettier@3.3.3))(vite@7.0.0(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(terser@5.16.1)(tsx@4.19.3))': + '@storybook/builder-vite@8.6.4(storybook@8.6.4(prettier@3.3.3))(vite@7.0.0(@types/node@20.19.1)(jiti@1.21.7)(terser@5.16.1)(tsx@4.19.3))': dependencies: '@storybook/csf-plugin': 8.6.4(storybook@8.6.4(prettier@3.3.3)) browser-assert: 1.2.1 storybook: 8.6.4(prettier@3.3.3) ts-dedent: 2.2.0 - vite: 7.0.0(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(terser@5.16.1)(tsx@4.19.3) + vite: 7.0.0(@types/node@20.19.1)(jiti@1.21.7)(terser@5.16.1)(tsx@4.19.3) '@storybook/components@8.6.4(storybook@8.6.4(prettier@3.3.3))': dependencies: @@ -20016,8 +20471,8 @@ snapshots: '@storybook/theming': 8.6.4(storybook@8.6.4(prettier@3.3.3)) better-opn: 3.0.2 browser-assert: 1.2.1 - esbuild: 0.24.0 - esbuild-register: 3.5.0(esbuild@0.24.0) + esbuild: 0.24.2 + esbuild-register: 3.5.0(esbuild@0.24.2) jsdoc-type-pratt-parser: 4.1.0 process: 0.11.10 recast: 0.23.6 @@ -20079,15 +20534,15 @@ snapshots: dependencies: storybook: 8.6.4(prettier@3.3.3) - '@storybook/vue3-vite@8.6.4(storybook@8.6.4(prettier@3.3.3))(vite@7.0.0(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3))': + '@storybook/vue3-vite@8.6.4(storybook@8.6.4(prettier@3.3.3))(vite@7.0.0(@types/node@20.19.1)(jiti@1.21.7)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3))': dependencies: - '@storybook/builder-vite': 8.6.4(storybook@8.6.4(prettier@3.3.3))(vite@7.0.0(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(terser@5.16.1)(tsx@4.19.3)) + '@storybook/builder-vite': 8.6.4(storybook@8.6.4(prettier@3.3.3))(vite@7.0.0(@types/node@20.19.1)(jiti@1.21.7)(terser@5.16.1)(tsx@4.19.3)) '@storybook/vue3': 8.6.4(storybook@8.6.4(prettier@3.3.3))(vue@3.5.13(typescript@5.8.3)) find-package-json: 1.2.0 magic-string: 0.30.17 storybook: 8.6.4(prettier@3.3.3) typescript: 5.8.3 - vite: 7.0.0(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(terser@5.16.1)(tsx@4.19.3) + vite: 7.0.0(@types/node@20.19.1)(jiti@1.21.7)(terser@5.16.1)(tsx@4.19.3) vue-component-meta: 2.1.10(typescript@5.8.3) vue-docgen-api: 4.76.0(vue@3.5.13(typescript@5.8.3)) transitivePeerDependencies: @@ -20107,11 +20562,11 @@ snapshots: vue: 3.5.13(typescript@5.8.3) vue-component-type-helpers: 2.2.10 - '@stylistic/eslint-plugin@5.0.0(eslint@9.29.0(jiti@1.21.0))': + '@stylistic/eslint-plugin@5.0.0(eslint@9.29.0(jiti@1.21.7))': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@1.21.0)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@1.21.7)) '@typescript-eslint/types': 8.35.0 - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -20191,6 +20646,18 @@ snapshots: '@tediousjs/connection-string@0.5.0': {} + '@testcontainers/postgresql@11.0.3': + dependencies: + testcontainers: 11.0.3 + transitivePeerDependencies: + - supports-color + + '@testcontainers/redis@11.0.3': + dependencies: + testcontainers: 11.0.3 + transitivePeerDependencies: + - supports-color + '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.26.2 @@ -20204,7 +20671,7 @@ snapshots: '@testing-library/dom@9.3.4': dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.27.1 '@babel/runtime': 7.26.10 '@types/aria-query': 5.0.1 aria-query: 5.1.3 @@ -20315,7 +20782,7 @@ snapshots: '@types/basic-auth@1.1.3': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/bcryptjs@2.4.2': {} @@ -20324,7 +20791,7 @@ snapshots: '@types/body-parser@1.19.2': dependencies: '@types/connect': 3.4.36 - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/caseless@0.12.5': {} @@ -20338,7 +20805,7 @@ snapshots: '@types/connect@3.4.36': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/convict@6.1.1': dependencies: @@ -20356,18 +20823,31 @@ snapshots: dependencies: '@types/ms': 2.1.0 + '@types/docker-modem@3.0.6': + dependencies: + '@types/node': 20.19.1 + '@types/ssh2': 1.11.6 + + '@types/dockerode@3.3.41': + dependencies: + '@types/docker-modem': 3.0.6 + '@types/node': 20.19.1 + '@types/ssh2': 1.11.6 + '@types/eslint@9.6.1': dependencies: '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 + '@types/estree@1.0.6': {} + '@types/estree@1.0.8': {} '@types/eventsource@1.1.9': {} '@types/express-serve-static-core@5.0.6(patch_hash=d602248fcd302cf5a794d1e85a411633ba9635ea5d566d6f2e0429c7ae0fa3eb)': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/qs': 6.9.15 '@types/range-parser': 1.2.4 '@types/send': 0.17.4 @@ -20407,7 +20887,7 @@ snapshots: '@types/graceful-fs@4.1.6': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/html-to-text@9.0.4': {} @@ -20467,7 +20947,7 @@ snapshots: '@types/jsonwebtoken@9.0.9': dependencies: '@types/ms': 2.1.0 - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/k6@0.52.0': {} @@ -20535,7 +21015,7 @@ snapshots: '@types/mysql@2.15.26': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/node-fetch@2.6.12': dependencies: @@ -20546,6 +21026,10 @@ snapshots: dependencies: undici-types: 6.19.8 + '@types/node@20.19.1': + dependencies: + undici-types: 6.21.0 + '@types/nodemailer@6.4.14': dependencies: '@types/node': 20.17.57 @@ -20562,7 +21046,7 @@ snapshots: '@types/pg@8.6.1': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 pg-protocol: 1.6.1 pg-types: 2.2.0 @@ -20577,7 +21061,7 @@ snapshots: '@types/node': 20.17.57 '@types/promise-ftp-common': 1.1.0 - '@types/prop-types@15.7.14': {} + '@types/prop-types@15.7.15': {} '@types/proxy-from-env@1.0.4': dependencies: @@ -20593,13 +21077,13 @@ snapshots: '@types/react@18.0.27': dependencies: - '@types/prop-types': 15.7.14 + '@types/prop-types': 15.7.15 '@types/scheduler': 0.26.0 csstype: 3.1.3 '@types/readable-stream@4.0.10': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 safe-buffer: 5.1.2 '@types/replacestream@4.0.1': {} @@ -20607,7 +21091,7 @@ snapshots: '@types/request@2.48.12': dependencies: '@types/caseless': 0.12.5 - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/tough-cookie': 4.0.5 form-data: 2.5.1 @@ -20628,7 +21112,7 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/serve-static@1.15.0': dependencies: @@ -20652,6 +21136,15 @@ snapshots: dependencies: '@types/ssh2': 1.11.6 + '@types/ssh2-streams@0.1.12': + dependencies: + '@types/node': 20.17.57 + + '@types/ssh2@0.5.52': + dependencies: + '@types/node': 20.17.57 + '@types/ssh2-streams': 0.1.12 + '@types/ssh2@1.11.6': dependencies: '@types/node': 20.17.57 @@ -20688,7 +21181,7 @@ snapshots: '@types/tedious@4.0.14': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/tedious@4.0.9': dependencies: @@ -20736,19 +21229,13 @@ snapshots: dependencies: '@types/webidl-conversions': 7.0.0 - '@types/whatwg-url@8.2.2': - dependencies: - '@types/node': 20.17.57 - '@types/webidl-conversions': 7.0.0 - optional: true - '@types/ws@8.18.1(patch_hash=682b44b740be55e5d7018e6fe335880851dadf2524b6c723c9ed0c29cb2fa7fb)': dependencies: '@types/node': 20.17.57 '@types/xml2js@0.4.14': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/yamljs@0.2.31': {} @@ -20760,18 +21247,18 @@ snapshots: '@types/yauzl@2.10.0': dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 optional: true - '@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/scope-manager': 8.35.0 - '@typescript-eslint/type-utils': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + '@typescript-eslint/type-utils': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.35.0 - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -20780,14 +21267,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3)': + '@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 8.35.0 '@typescript-eslint/types': 8.35.0 '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.35.0 debug: 4.4.1(supports-color@8.1.1) - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -20801,13 +21288,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/rule-tester@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3)': + '@typescript-eslint/rule-tester@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: - '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) ajv: 6.12.6 - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 semver: 7.7.2 @@ -20829,12 +21316,12 @@ snapshots: dependencies: typescript: 5.8.3 - '@typescript-eslint/type-utils@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) debug: 4.4.1(supports-color@8.1.1) - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: @@ -20853,7 +21340,7 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.3 semver: 7.7.2 - ts-api-utils: 1.0.1(typescript@5.8.3) + ts-api-utils: 1.4.3(typescript@5.8.3) optionalDependencies: typescript: 5.8.3 transitivePeerDependencies: @@ -20866,7 +21353,7 @@ snapshots: '@typescript-eslint/types': 8.35.0 '@typescript-eslint/visitor-keys': 8.35.0 debug: 4.4.1(supports-color@8.1.1) - fast-glob: 3.3.2 + fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.2 @@ -20875,27 +21362,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@6.21.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3)': + '@typescript-eslint/utils@6.21.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.29.0(jiti@1.21.0)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@1.21.7)) '@types/json-schema': 7.0.15 '@types/semver': 7.7.0 '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.8.3) - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) semver: 7.7.2 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3)': + '@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@1.21.0)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@1.21.7)) '@typescript-eslint/scope-manager': 8.35.0 '@typescript-eslint/types': 8.35.0 '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -20984,7 +21471,7 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.9.2': optional: true - '@vitejs/plugin-legacy@6.0.2(terser@5.16.1)(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))': + '@vitejs/plugin-legacy@6.0.2(terser@5.16.1)(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))': dependencies: '@babel/core': 7.26.10 '@babel/preset-env': 7.26.9(@babel/core@7.26.10) @@ -20995,16 +21482,16 @@ snapshots: regenerator-runtime: 0.14.1 systemjs: 6.15.1 terser: 5.16.1 - vite: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + vite: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3))': + '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))(vue@3.5.13(typescript@5.8.3))': dependencies: - vite: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + vite: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vue: 3.5.13(typescript@5.8.3) - '@vitest/coverage-v8@3.2.4(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))': + '@vitest/coverage-v8@3.2.4(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -21019,7 +21506,7 @@ snapshots: std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + vitest: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) transitivePeerDependencies: - supports-color @@ -21037,13 +21524,13 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.1.3(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))': + '@vitest/mocker@3.1.3(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3))': dependencies: '@vitest/spy': 3.1.3 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + vite: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) '@vitest/pretty-format@2.0.5': dependencies: @@ -21057,6 +21544,10 @@ snapshots: dependencies: tinyrainbow: 2.0.0 + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + '@vitest/runner@3.1.3': dependencies: '@vitest/utils': 3.1.3 @@ -21080,19 +21571,19 @@ snapshots: dependencies: '@vitest/pretty-format': 2.0.5 estree-walker: 3.0.3 - loupe: 3.1.3 + loupe: 3.1.4 tinyrainbow: 1.2.0 '@vitest/utils@2.1.8': dependencies: '@vitest/pretty-format': 2.1.8 - loupe: 3.1.3 + loupe: 3.1.4 tinyrainbow: 1.2.0 '@vitest/utils@3.1.3': dependencies: '@vitest/pretty-format': 3.1.3 - loupe: 3.1.3 + loupe: 3.1.4 tinyrainbow: 2.0.0 '@volar/language-core@2.4.12': @@ -21163,7 +21654,7 @@ snapshots: '@vue/shared': 3.5.13 estree-walker: 2.0.2 magic-string: 0.30.17 - postcss: 8.5.3 + postcss: 8.5.6 source-map-js: 1.2.1 '@vue/compiler-ssr@3.5.13': @@ -21361,10 +21852,6 @@ snapshots: dependencies: acorn: 8.14.0 - acorn-jsx@5.3.2(acorn@8.14.0): - dependencies: - acorn: 8.14.0 - acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -21510,6 +21997,26 @@ snapshots: arch@2.2.0: {} + archiver-utils@5.0.2: + dependencies: + glob: 10.4.5 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.17.21 + normalize-path: 3.0.0 + readable-stream: 4.5.2 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.4 + buffer-crc32: 1.0.0 + readable-stream: 4.5.2 + readdir-glob: 1.1.3 + tar-stream: 3.1.7 + zip-stream: 6.0.1 + are-we-there-yet@3.0.1: dependencies: delegates: 1.0.0 @@ -21541,7 +22048,7 @@ snapshots: array-buffer-byte-length@1.0.1: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 is-array-buffer: 3.0.4 array-buffer-byte-length@1.0.2: @@ -21606,9 +22113,9 @@ snapshots: arraybuffer.prototype.slice@1.0.3: dependencies: array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.0 es-errors: 1.3.0 get-intrinsic: 1.3.0 is-array-buffer: 3.0.4 @@ -21682,6 +22189,8 @@ snapshots: async-function@1.0.0: {} + async-lock@1.4.1: {} + async-mutex@0.5.0: dependencies: tslib: 2.8.1 @@ -21698,6 +22207,8 @@ snapshots: at-least-node@1.0.0: {} + atomic-sleep@1.0.0: {} + autoprefixer@10.4.19(postcss@8.4.49): dependencies: browserslist: 4.24.4 @@ -21722,15 +22233,52 @@ snapshots: axe-core@4.7.2: {} + axios-retry@4.5.0(axios@1.10.0(debug@4.4.1)): + dependencies: + axios: 1.10.0(debug@4.4.1) + is-retry-allowed: 2.2.0 + + axios-retry@4.5.0(axios@1.10.0): + dependencies: + axios: 1.10.0 + is-retry-allowed: 2.2.0 + axios-retry@4.5.0(axios@1.8.3): dependencies: axios: 1.8.3 is-retry-allowed: 2.2.0 - axios-retry@4.5.0(axios@1.9.0): + axios@1.10.0: dependencies: - axios: 1.9.0 - is-retry-allowed: 2.2.0 + follow-redirects: 1.15.9(debug@4.3.6) + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axios@1.10.0(debug@4.3.6): + dependencies: + follow-redirects: 1.15.9(debug@4.3.6) + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axios@1.10.0(debug@4.4.0): + dependencies: + follow-redirects: 1.15.9(debug@4.4.0) + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axios@1.10.0(debug@4.4.1): + dependencies: + follow-redirects: 1.15.9(debug@4.4.1) + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug axios@1.8.3: dependencies: @@ -21740,37 +22288,7 @@ snapshots: transitivePeerDependencies: - debug - axios@1.9.0: - dependencies: - follow-redirects: 1.15.9(debug@4.3.6) - form-data: 4.0.2 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - axios@1.9.0(debug@4.3.6): - dependencies: - follow-redirects: 1.15.9(debug@4.3.6) - form-data: 4.0.2 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - axios@1.9.0(debug@4.4.0): - dependencies: - follow-redirects: 1.15.9(debug@4.4.0) - form-data: 4.0.2 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - axios@1.9.0(debug@4.4.1): - dependencies: - follow-redirects: 1.15.9(debug@4.4.1) - form-data: 4.0.2 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug + b4a@1.6.7: {} babel-jest@29.6.2(@babel/core@7.26.10): dependencies: @@ -21815,7 +22333,7 @@ snapshots: dependencies: '@babel/core': 7.26.10 '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.10) - core-js-compat: 3.41.0 + core-js-compat: 3.43.0 transitivePeerDependencies: - supports-color @@ -21860,6 +22378,9 @@ snapshots: balanced-match@1.0.2: {} + bare-events@2.5.4: + optional: true + base64-js@1.5.1: {} basic-auth@2.0.1: @@ -21909,6 +22430,8 @@ snapshots: bluebird@3.4.7: {} + bluebird@3.5.5: {} + bluebird@3.7.2: {} bn.js@4.12.2: {} @@ -21966,6 +22489,13 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.1(browserslist@4.24.4) + browserslist@4.25.0: + dependencies: + caniuse-lite: 1.0.30001724 + electron-to-chromium: 1.5.173 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.25.0) + bs-logger@0.2.6: dependencies: fast-json-stable-stringify: 2.1.0 @@ -21974,13 +22504,12 @@ snapshots: dependencies: node-int64: 0.4.0 - bson@5.5.1: - optional: true - bson@6.10.0: {} buffer-crc32@0.2.13: {} + buffer-crc32@1.0.0: {} + buffer-equal-constant-time@1.0.1: {} buffer-from@1.1.2: {} @@ -22014,9 +22543,9 @@ snapshots: transitivePeerDependencies: - supports-color - bundle-require@5.1.0(esbuild@0.24.0): + bundle-require@5.1.0(esbuild@0.24.2): dependencies: - esbuild: 0.24.0 + esbuild: 0.24.2 load-tsconfig: 0.2.5 bundlemon-utils@2.0.1: @@ -22025,8 +22554,8 @@ snapshots: bundlemon@3.1.0(typescript@5.8.3): dependencies: - axios: 1.9.0 - axios-retry: 4.5.0(axios@1.9.0) + axios: 1.10.0 + axios-retry: 4.5.0(axios@1.10.0) brotli-size: 4.0.0 bundlemon-utils: 2.0.1 bytes: 3.1.2 @@ -22044,8 +22573,27 @@ snapshots: dependencies: streamsearch: 1.1.0 + byline@5.0.0: {} + bytes@3.1.2: {} + c12@1.11.2(magicast@0.3.5): + dependencies: + chokidar: 4.0.1 + confbox: 0.1.8 + defu: 6.1.4 + dotenv: 16.5.0 + giget: 1.2.5 + jiti: 1.21.7 + mlly: 1.7.4 + ohash: 1.1.6 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + pkg-types: 1.3.1 + rc9: 2.1.2 + optionalDependencies: + magicast: 0.3.5 + cac@6.7.14: {} cacache@15.3.0: @@ -22130,6 +22678,8 @@ snapshots: caniuse-lite@1.0.30001703: {} + caniuse-lite@1.0.30001724: {} + capital-case@1.0.4: dependencies: no-case: 3.0.4 @@ -22143,7 +22693,7 @@ snapshots: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.3 + loupe: 3.1.4 pathval: 2.0.0 chai@5.2.0: @@ -22151,7 +22701,7 @@ snapshots: assertion-error: 2.0.1 check-error: 2.1.1 deep-eql: 5.0.2 - loupe: 3.1.3 + loupe: 3.1.4 pathval: 2.0.0 chalk@3.0.0: @@ -22255,6 +22805,10 @@ snapshots: dependencies: readdirp: 4.0.2 + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + chownr@1.1.4: {} chownr@2.0.0: {} @@ -22265,6 +22819,10 @@ snapshots: ci-info@4.2.0: {} + citty@0.1.6: + dependencies: + consola: 3.4.2 + cjs-module-lexer@1.2.2: {} class-transformer@0.5.1: {} @@ -22413,6 +22971,8 @@ snapshots: commander@11.1.0: {} + commander@12.1.0: {} + commander@2.20.3: {} commander@4.1.1: {} @@ -22435,6 +22995,14 @@ snapshots: component-type@2.0.0: {} + compress-commons@6.0.2: + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.5.2 + compressible@2.0.18: dependencies: mime-db: 1.52.0 @@ -22481,7 +23049,7 @@ snapshots: ini: 1.3.8 proto-list: 1.2.4 - consola@3.4.0: {} + consola@3.4.2: {} console-control-strings@1.1.0: optional: true @@ -22499,7 +23067,7 @@ snapshots: constantinople@4.0.1: dependencies: '@babel/parser': 7.27.5 - '@babel/types': 7.26.10 + '@babel/types': 7.27.6 content-disposition@1.0.0: dependencies: @@ -22529,9 +23097,9 @@ snapshots: cookiejar@2.1.4: {} - core-js-compat@3.41.0: + core-js-compat@3.43.0: dependencies: - browserslist: 4.24.4 + browserslist: 4.25.0 core-js@3.40.0: {} @@ -22559,6 +23127,13 @@ snapshots: nan: 2.20.0 optional: true + crc-32@1.2.2: {} + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.5.2 + create-require@1.1.1: optional: true @@ -22595,6 +23170,14 @@ snapshots: transitivePeerDependencies: - encoding + cross-spawn@6.0.6: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 7.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -22804,7 +23387,7 @@ snapshots: data-view-buffer@1.0.1: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 es-errors: 1.3.0 is-data-view: 1.0.1 @@ -22816,7 +23399,7 @@ snapshots: data-view-byte-length@1.0.1: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 es-errors: 1.3.0 is-data-view: 1.0.1 @@ -22828,7 +23411,7 @@ snapshots: data-view-byte-offset@1.0.0: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 es-errors: 1.3.0 is-data-view: 1.0.1 @@ -22912,23 +23495,23 @@ snapshots: deep-equal@2.2.0: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 es-get-iterator: 1.1.3 get-intrinsic: 1.3.0 is-arguments: 1.1.1 - is-array-buffer: 3.0.4 - is-date-object: 1.0.5 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.3 + is-array-buffer: 3.0.5 + is-date-object: 1.1.0 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 isarray: 2.0.5 object-is: 1.1.6 object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.3 + object.assign: 4.1.7 + regexp.prototype.flags: 1.5.4 side-channel: 1.1.0 - which-boxed-primitive: 1.0.2 - which-collection: 1.0.1 - which-typed-array: 1.1.15 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 deep-extend@0.6.0: {} @@ -22963,6 +23546,8 @@ snapshots: dequal@2.0.3: {} + destr@2.0.5: {} + detect-libc@2.0.4: {} detect-newline@3.1.0: {} @@ -22989,6 +23574,31 @@ snapshots: dlv@1.1.3: {} + docker-compose@1.2.0: + dependencies: + yaml: 2.3.4 + + docker-modem@5.0.6: + dependencies: + debug: 4.4.1(supports-color@8.1.1) + readable-stream: 3.6.0 + split-ca: 1.0.1 + ssh2: 1.15.0 + transitivePeerDependencies: + - supports-color + + dockerode@4.0.7: + dependencies: + '@balena/dockerignore': 1.0.2 + '@grpc/grpc-js': 1.13.2 + '@grpc/proto-loader': 0.7.13 + docker-modem: 5.0.6 + protobufjs: 7.4.0 + tar-fs: 2.1.3 + uuid: 10.0.0 + transitivePeerDependencies: + - supports-color + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -23105,6 +23715,8 @@ snapshots: electron-to-chromium@1.5.114: {} + electron-to-chromium@1.5.173: {} + element-plus@2.4.3(patch_hash=3bc4ea0a42ad52c6bbc3d06c12c2963d55b57d6b5b8d436e46e7fd8ff8c10661)(vue@3.5.13(typescript@5.8.3)): dependencies: '@ctrl/tinycolor': 3.6.0 @@ -23226,7 +23838,7 @@ snapshots: safe-array-concat: 1.1.2 safe-regex-test: 1.0.3 string.prototype.trim: 1.2.9 - string.prototype.trimend: 1.0.8 + string.prototype.trimend: 1.0.9 string.prototype.trimstart: 1.0.8 typed-array-buffer: 1.0.2 typed-array-byte-length: 1.0.1 @@ -23296,7 +23908,7 @@ snapshots: dependencies: define-data-property: 1.1.4 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.0 es-errors: 1.3.0 function-bind: 1.1.2 globalthis: 1.0.4 @@ -23309,15 +23921,15 @@ snapshots: es-get-iterator@1.1.3: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 get-intrinsic: 1.3.0 has-symbols: 1.1.0 is-arguments: 1.1.1 - is-map: 2.0.2 - is-set: 2.0.2 - is-string: 1.0.7 + is-map: 2.0.3 + is-set: 2.0.3 + is-string: 1.1.1 isarray: 2.0.5 - stop-iteration-iterator: 1.0.0 + stop-iteration-iterator: 1.1.0 es-module-lexer@1.7.0: {} @@ -23345,44 +23957,45 @@ snapshots: es-to-primitive@1.3.0: dependencies: is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 + is-date-object: 1.1.0 + is-symbol: 1.1.1 es6-promise@3.3.1: {} - esbuild-register@3.5.0(esbuild@0.24.0): + esbuild-register@3.5.0(esbuild@0.24.2): dependencies: debug: 4.4.1(supports-color@8.1.1) - esbuild: 0.24.0 + esbuild: 0.24.2 transitivePeerDependencies: - supports-color - esbuild@0.24.0: + esbuild@0.24.2: optionalDependencies: - '@esbuild/aix-ppc64': 0.24.0 - '@esbuild/android-arm': 0.24.0 - '@esbuild/android-arm64': 0.24.0 - '@esbuild/android-x64': 0.24.0 - '@esbuild/darwin-arm64': 0.24.0 - '@esbuild/darwin-x64': 0.24.0 - '@esbuild/freebsd-arm64': 0.24.0 - '@esbuild/freebsd-x64': 0.24.0 - '@esbuild/linux-arm': 0.24.0 - '@esbuild/linux-arm64': 0.24.0 - '@esbuild/linux-ia32': 0.24.0 - '@esbuild/linux-loong64': 0.24.0 - '@esbuild/linux-mips64el': 0.24.0 - '@esbuild/linux-ppc64': 0.24.0 - '@esbuild/linux-riscv64': 0.24.0 - '@esbuild/linux-s390x': 0.24.0 - '@esbuild/linux-x64': 0.24.0 - '@esbuild/netbsd-x64': 0.24.0 - '@esbuild/openbsd-arm64': 0.24.0 - '@esbuild/openbsd-x64': 0.24.0 - '@esbuild/sunos-x64': 0.24.0 - '@esbuild/win32-arm64': 0.24.0 - '@esbuild/win32-ia32': 0.24.0 - '@esbuild/win32-x64': 0.24.0 + '@esbuild/aix-ppc64': 0.24.2 + '@esbuild/android-arm': 0.24.2 + '@esbuild/android-arm64': 0.24.2 + '@esbuild/android-x64': 0.24.2 + '@esbuild/darwin-arm64': 0.24.2 + '@esbuild/darwin-x64': 0.24.2 + '@esbuild/freebsd-arm64': 0.24.2 + '@esbuild/freebsd-x64': 0.24.2 + '@esbuild/linux-arm': 0.24.2 + '@esbuild/linux-arm64': 0.24.2 + '@esbuild/linux-ia32': 0.24.2 + '@esbuild/linux-loong64': 0.24.2 + '@esbuild/linux-mips64el': 0.24.2 + '@esbuild/linux-ppc64': 0.24.2 + '@esbuild/linux-riscv64': 0.24.2 + '@esbuild/linux-s390x': 0.24.2 + '@esbuild/linux-x64': 0.24.2 + '@esbuild/netbsd-arm64': 0.24.2 + '@esbuild/netbsd-x64': 0.24.2 + '@esbuild/openbsd-arm64': 0.24.2 + '@esbuild/openbsd-x64': 0.24.2 + '@esbuild/sunos-x64': 0.24.2 + '@esbuild/win32-arm64': 0.24.2 + '@esbuild/win32-ia32': 0.24.2 + '@esbuild/win32-x64': 0.24.2 escalade@3.1.1: {} @@ -23416,16 +24029,16 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-prettier@10.1.5(eslint@9.29.0(jiti@1.21.0)): + eslint-config-prettier@10.1.5(eslint@9.29.0(jiti@1.21.7)): dependencies: - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) eslint-config-riot@1.0.0: {} - eslint-import-context@0.1.9(unrs-resolver@1.9.2): + eslint-import-context@0.1.8(unrs-resolver@1.9.2): dependencies: get-tsconfig: 4.10.1 - stable-hash-x: 0.2.0 + stable-hash-x: 0.1.1 optionalDependencies: unrs-resolver: 1.9.2 @@ -23433,61 +24046,61 @@ snapshots: dependencies: debug: 3.2.7(supports-color@5.5.0) is-core-module: 2.16.1 - resolve: 1.22.8 + resolve: 1.22.10 transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.0)))(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@1.21.0)): + eslint-import-resolver-typescript@4.4.3(eslint-plugin-import-x@4.15.2(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.7)))(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@1.21.7)): dependencies: debug: 4.4.1(supports-color@8.1.1) - eslint: 9.29.0(jiti@1.21.0) - eslint-import-context: 0.1.9(unrs-resolver@1.9.2) + eslint: 9.29.0(jiti@1.21.7) + eslint-import-context: 0.1.8(unrs-resolver@1.9.2) get-tsconfig: 4.10.1 is-bun-module: 2.0.0 - stable-hash-x: 0.2.0 + stable-hash-x: 0.1.1 tinyglobby: 0.2.14 unrs-resolver: 1.9.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.29.0(jiti@1.21.0)) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.0)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.3)(eslint@9.29.0(jiti@1.21.7)) + eslint-plugin-import-x: 4.15.2(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.29.0(jiti@1.21.0)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.3)(eslint@9.29.0(jiti@1.21.7)): dependencies: debug: 3.2.7(supports-color@5.5.0) optionalDependencies: - '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) - eslint: 9.29.0(jiti@1.21.0) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + eslint: 9.29.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.0)))(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@1.21.0)) + eslint-import-resolver-typescript: 4.4.3(eslint-plugin-import-x@4.15.2(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.7)))(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@1.21.7)) transitivePeerDependencies: - supports-color - eslint-plugin-cypress@4.3.0(eslint@9.29.0(jiti@1.21.0)): + eslint-plugin-cypress@4.3.0(eslint@9.29.0(jiti@1.21.7)): dependencies: - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) globals: 15.15.0 - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.0)): + eslint-plugin-import-x@4.15.2(@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.29.0(jiti@1.21.7)): dependencies: '@typescript-eslint/types': 8.35.0 comment-parser: 1.4.1 debug: 4.4.1(supports-color@8.1.1) - eslint: 9.29.0(jiti@1.21.0) - eslint-import-context: 0.1.9(unrs-resolver@1.9.2) + eslint: 9.29.0(jiti@1.21.7) + eslint-import-context: 0.1.8(unrs-resolver@1.9.2) is-glob: 4.0.3 - minimatch: 10.0.1 + minimatch: 10.0.3 semver: 7.7.2 - stable-hash-x: 0.2.0 + stable-hash-x: 0.1.1 unrs-resolver: 1.9.2 optionalDependencies: - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.29.0(jiti@1.21.0)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.3)(eslint@9.29.0(jiti@1.21.7)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -23496,9 +24109,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7(supports-color@5.5.0) doctrine: 2.1.0 - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.4)(eslint@9.29.0(jiti@1.21.0)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.3)(eslint@9.29.0(jiti@1.21.7)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -23510,7 +24123,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 4.2.0 optionalDependencies: - '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -23518,14 +24131,14 @@ snapshots: eslint-plugin-local@1.0.0: {} - eslint-plugin-lodash@8.0.0(eslint@9.29.0(jiti@1.21.0)): + eslint-plugin-lodash@8.0.0(eslint@9.29.0(jiti@1.21.7)): dependencies: - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) lodash: 4.17.21 - eslint-plugin-n8n-nodes-base@1.16.3(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3): + eslint-plugin-n8n-nodes-base@1.16.3(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3): dependencies: - '@typescript-eslint/utils': 6.21.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + '@typescript-eslint/utils': 6.21.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) camel-case: 4.1.2 eslint-plugin-local: 1.0.0 indefinite: 2.5.1 @@ -23538,15 +24151,20 @@ snapshots: - supports-color - typescript - eslint-plugin-unicorn@59.0.1(eslint@9.29.0(jiti@1.21.0)): + eslint-plugin-playwright@2.2.0(eslint@9.29.0(jiti@1.21.7)): + dependencies: + eslint: 9.29.0(jiti@1.21.7) + globals: 13.24.0 + + eslint-plugin-unicorn@59.0.1(eslint@9.29.0(jiti@1.21.7)): dependencies: '@babel/helper-validator-identifier': 7.27.1 - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@1.21.0)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@1.21.7)) '@eslint/plugin-kit': 0.2.8 ci-info: 4.2.0 clean-regexp: 1.0.0 - core-js-compat: 3.41.0 - eslint: 9.29.0(jiti@1.21.0) + core-js-compat: 3.43.0 + eslint: 9.29.0(jiti@1.21.7) esquery: 1.6.0 find-up-simple: 1.0.1 globals: 16.2.0 @@ -23559,28 +24177,23 @@ snapshots: semver: 7.7.2 strip-indent: 4.0.0 - eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.0)): + eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7)): dependencies: - eslint: 9.29.0(jiti@1.21.0) + eslint: 9.29.0(jiti@1.21.7) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) + '@typescript-eslint/eslint-plugin': 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) - eslint-plugin-vue@10.2.0(eslint@9.29.0(jiti@1.21.0))(vue-eslint-parser@9.4.2(eslint@9.29.0(jiti@1.21.0))): + eslint-plugin-vue@10.2.0(eslint@9.29.0(jiti@1.21.7))(vue-eslint-parser@10.1.3(eslint@9.29.0(jiti@1.21.7))): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.29.0(jiti@1.21.0)) - eslint: 9.29.0(jiti@1.21.0) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@1.21.7)) + eslint: 9.29.0(jiti@1.21.7) natural-compare: 1.4.0 nth-check: 2.1.1 - postcss-selector-parser: 6.0.16 + postcss-selector-parser: 6.1.2 semver: 7.7.2 - vue-eslint-parser: 9.4.2(eslint@9.29.0(jiti@1.21.0)) + vue-eslint-parser: 10.1.3(eslint@9.29.0(jiti@1.21.7)) xml-name-validator: 4.0.0 - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 @@ -23590,20 +24203,20 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.29.0(jiti@1.21.0): + eslint@9.29.0(jiti@1.21.7): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.29.0(jiti@1.21.0)) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.29.0(jiti@1.21.7)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.20.1 '@eslint/config-helpers': 0.2.3 '@eslint/core': 0.14.0 '@eslint/eslintrc': 3.3.1 '@eslint/js': 9.29.0 - '@eslint/plugin-kit': 0.3.3 + '@eslint/plugin-kit': 0.3.2 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 + '@types/estree': 1.0.6 '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 @@ -23628,7 +24241,7 @@ snapshots: natural-compare: 1.4.0 optionator: 0.9.3 optionalDependencies: - jiti: 1.21.0 + jiti: 1.21.7 transitivePeerDependencies: - supports-color @@ -23640,12 +24253,6 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 4.2.1 - espree@9.6.1: - dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) - eslint-visitor-keys: 3.4.3 - esprima-next@5.8.4: {} esprima@1.2.2: {} @@ -23706,6 +24313,16 @@ snapshots: dependencies: eventsource-parser: 3.0.1 + execa@1.0.0: + dependencies: + cross-spawn: 6.0.6 + get-stream: 4.1.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + execa@4.1.0: dependencies: cross-spawn: 7.0.6 @@ -23730,6 +24347,21 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + execa@9.6.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.2.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.1 + executable@4.1.1: dependencies: pify: 2.3.0 @@ -23755,7 +24387,7 @@ snapshots: expect@29.6.2: dependencies: '@jest/expect-utils': 29.6.2 - '@types/node': 20.17.57 + '@types/node': 20.19.1 jest-get-type: 29.4.3 jest-matcher-utils: 29.6.2 jest-message-util: 29.6.2 @@ -23858,6 +24490,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-fifo@1.3.2: {} + fast-glob@3.2.12: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -23866,7 +24500,7 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 - fast-glob@3.3.2: + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 @@ -23878,6 +24512,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-redact@3.5.0: {} + fast-safe-stringify@2.1.1: {} fast-unique-numbers@8.0.13: @@ -23936,6 +24572,10 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -23952,7 +24592,7 @@ snapshots: filelist@1.0.4: dependencies: - minimatch: 5.1.5 + minimatch: 5.1.6 filesize@10.1.0: {} @@ -24003,7 +24643,7 @@ snapshots: dependencies: magic-string: 0.30.17 mlly: 1.7.4 - rollup: 4.44.1 + rollup: 4.44.0 flat-cache@4.0.1: dependencies: @@ -24128,9 +24768,9 @@ snapshots: function.prototype.name@1.1.6: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.0 functions-have-names: 1.2.3 function.prototype.name@1.1.8: @@ -24156,7 +24796,7 @@ snapshots: wide-align: 1.1.5 optional: true - gaxios@5.1.0(encoding@0.1.13): + gaxios@5.1.3(encoding@0.1.13): dependencies: extend: 3.0.2 https-proxy-agent: 5.0.1 @@ -24188,7 +24828,7 @@ snapshots: gcp-metadata@5.3.0(encoding@0.1.13): dependencies: - gaxios: 5.1.0(encoding@0.1.13) + gaxios: 5.1.3(encoding@0.1.13) json-bigint: 1.0.0 transitivePeerDependencies: - encoding @@ -24253,20 +24893,31 @@ snapshots: get-port@5.1.1: {} + get-port@7.1.0: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + get-stream@4.1.0: + dependencies: + pump: 3.0.0 + get-stream@5.2.0: dependencies: pump: 3.0.0 get-stream@6.0.1: {} + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + get-symbol-description@1.0.2: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 es-errors: 1.3.0 get-intrinsic: 1.3.0 @@ -24278,10 +24929,6 @@ snapshots: get-system-fonts@2.0.2: {} - get-tsconfig@4.10.0: - dependencies: - resolve-pkg-maps: 1.0.0 - get-tsconfig@4.10.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -24294,6 +24941,16 @@ snapshots: dependencies: assert-plus: 1.0.0 + giget@1.2.5: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + defu: 6.1.4 + node-fetch-native: 1.6.6 + nypm: 0.5.4 + pathe: 2.0.3 + tar: 6.2.1 + github-buttons@2.29.1: {} github-from-package@0.0.0: {} @@ -24327,7 +24984,7 @@ snapshots: dependencies: foreground-child: 3.1.1 jackspeak: 4.1.0 - minimatch: 10.0.1 + minimatch: 10.0.3 minipass: 7.1.2 package-json-from-dist: 1.0.0 path-scurry: 2.0.0 @@ -24346,7 +25003,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.1.5 + minimatch: 5.1.6 once: 1.4.0 global-dirs@3.0.0: @@ -24355,6 +25012,10 @@ snapshots: globals@11.12.0: {} + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + globals@14.0.0: {} globals@15.15.0: {} @@ -24370,7 +25031,7 @@ snapshots: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.2 + fast-glob: 3.3.3 ignore: 5.2.4 merge2: 1.4.1 slash: 3.0.0 @@ -24486,6 +25147,8 @@ snapshots: has-bigints@1.0.2: {} + has-bigints@1.1.0: {} + has-flag@3.0.0: {} has-flag@4.0.0: {} @@ -24667,6 +25330,8 @@ snapshots: human-signals@2.1.0: {} + human-signals@8.0.1: {} + humanize-duration@3.27.3: {} humanize-ms@1.2.1: @@ -24676,9 +25341,9 @@ snapshots: ibm-cloud-sdk-core@5.3.2: dependencies: '@types/debug': 4.1.12 - '@types/node': 20.17.57 + '@types/node': 20.19.1 '@types/tough-cookie': 4.0.5 - axios: 1.9.0(debug@4.4.1) + axios: 1.10.0(debug@4.4.1) camelcase: 6.3.0 debug: 4.4.1(supports-color@8.1.1) dotenv: 16.5.0 @@ -24688,7 +25353,7 @@ snapshots: isstream: 0.1.2 jsonwebtoken: 9.0.2 mime-types: 2.1.35 - retry-axios: 2.6.0(axios@1.9.0) + retry-axios: 2.6.0(axios@1.10.0) tough-cookie: 4.1.4 transitivePeerDependencies: - supports-color @@ -24705,7 +25370,7 @@ snapshots: ics@2.40.0: dependencies: - nanoid: 3.3.8 + nanoid: 3.3.11 yup: 0.32.11 ieee754@1.2.1: {} @@ -24757,7 +25422,7 @@ snapshots: infisical-node@1.3.0: dependencies: - axios: 1.9.0 + axios: 1.10.0 dotenv: 16.3.1 tweetnacl: 1.0.3 tweetnacl-util: 0.15.1 @@ -24841,12 +25506,12 @@ snapshots: is-arguments@1.1.1: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 has-tostringtag: 1.0.2 is-array-buffer@3.0.4: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 get-intrinsic: 1.3.0 is-array-buffer@3.0.5: @@ -24873,11 +25538,11 @@ snapshots: is-bigint@1.1.0: dependencies: - has-bigints: 1.0.2 + has-bigints: 1.1.0 is-boolean-object@1.1.2: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 has-tostringtag: 1.0.2 is-boolean-object@1.2.2: @@ -24947,6 +25612,13 @@ snapshots: dependencies: has-tostringtag: 1.0.2 + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -24959,13 +25631,11 @@ snapshots: is-lambda@1.0.1: optional: true - is-map@2.0.2: {} - is-map@2.0.3: {} is-nan@1.3.2: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 is-negative-zero@2.0.3: {} @@ -24985,6 +25655,8 @@ snapshots: is-path-inside@3.0.3: {} + is-plain-obj@4.1.0: {} + is-plain-object@5.0.0: {} is-potential-custom-element-name@1.0.1: {} @@ -24997,7 +25669,7 @@ snapshots: is-regex@1.1.4: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 has-tostringtag: 1.0.2 is-regex@1.2.1: @@ -25009,20 +25681,22 @@ snapshots: is-retry-allowed@2.2.0: {} - is-set@2.0.2: {} - is-set@2.0.3: {} is-shared-array-buffer@1.0.3: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 is-shared-array-buffer@1.0.4: dependencies: call-bound: 1.0.4 + is-stream@1.1.0: {} + is-stream@2.0.1: {} + is-stream@4.0.1: {} + is-string@1.0.7: dependencies: has-tostringtag: 1.0.2 @@ -25054,23 +25728,18 @@ snapshots: is-unicode-supported@0.1.0: {} - is-weakmap@2.0.1: {} + is-unicode-supported@2.1.0: {} is-weakmap@2.0.2: {} is-weakref@1.0.2: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 is-weakref@1.1.1: dependencies: call-bound: 1.0.4 - is-weakset@2.0.2: - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.3.0 - is-weakset@2.0.4: dependencies: call-bound: 1.0.4 @@ -25169,7 +25838,7 @@ snapshots: '@jest/expect': 29.6.2 '@jest/test-result': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 20.17.57 + '@types/node': 20.19.1 chalk: 4.1.2 co: 4.6.0 dedent: 1.3.0 @@ -25209,6 +25878,26 @@ snapshots: - supports-color - ts-node + jest-cli@29.6.2(@types/node@20.19.1)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)): + dependencies: + '@jest/core': 29.6.2(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) + '@jest/test-result': 29.6.2 + '@jest/types': 29.6.1 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + import-local: 3.1.0 + jest-config: 29.6.2(@types/node@20.19.1)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) + jest-util: 29.6.2 + jest-validate: 29.6.2 + prompts: 2.4.2 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest-config@29.6.2(@types/node@20.17.57)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)): dependencies: '@babel/core': 7.26.10 @@ -25240,6 +25929,68 @@ snapshots: - babel-plugin-macros - supports-color + jest-config@29.6.2(@types/node@20.17.57)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)): + dependencies: + '@babel/core': 7.26.10 + '@jest/test-sequencer': 29.6.2 + '@jest/types': 29.6.1 + babel-jest: 29.6.2(@babel/core@7.26.10) + chalk: 4.1.2 + ci-info: 3.8.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.6.2 + jest-environment-node: 29.6.2 + jest-get-type: 29.4.3 + jest-regex-util: 29.4.3 + jest-resolve: 29.6.2 + jest-runner: 29.6.2 + jest-util: 29.6.2 + jest-validate: 29.6.2 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.17.57 + ts-node: 10.9.2(@types/node@20.19.1)(typescript@5.8.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-config@29.6.2(@types/node@20.19.1)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)): + dependencies: + '@babel/core': 7.26.10 + '@jest/test-sequencer': 29.6.2 + '@jest/types': 29.6.1 + babel-jest: 29.6.2(@babel/core@7.26.10) + chalk: 4.1.2 + ci-info: 3.8.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.6.2 + jest-environment-node: 29.6.2 + jest-get-type: 29.4.3 + jest-regex-util: 29.4.3 + jest-resolve: 29.6.2 + jest-runner: 29.6.2 + jest-util: 29.6.2 + jest-validate: 29.6.2 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.19.1 + ts-node: 10.9.2(@types/node@20.19.1)(typescript@5.8.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-diff@29.5.0: dependencies: chalk: 4.1.2 @@ -25286,7 +26037,7 @@ snapshots: '@jest/environment': 29.6.2 '@jest/fake-timers': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 20.17.57 + '@types/node': 20.19.1 jest-mock: 29.6.2 jest-util: 29.6.2 @@ -25298,7 +26049,7 @@ snapshots: dependencies: '@jest/types': 29.6.1 '@types/graceful-fs': 4.1.6 - '@types/node': 20.17.57 + '@types/node': 20.19.1 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -25366,6 +26117,12 @@ snapshots: ts-essentials: 7.0.3(typescript@5.8.3) typescript: 5.8.3 + jest-mock-extended@3.0.4(jest@29.6.2(@types/node@20.19.1)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)))(typescript@5.8.3): + dependencies: + jest: 29.6.2(@types/node@20.19.1)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) + ts-essentials: 7.0.3(typescript@5.8.3) + typescript: 5.8.3 + jest-mock@29.6.2: dependencies: '@jest/types': 29.6.1 @@ -25404,7 +26161,7 @@ snapshots: '@jest/test-result': 29.6.2 '@jest/transform': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 20.17.57 + '@types/node': 20.19.1 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -25432,7 +26189,7 @@ snapshots: '@jest/test-result': 29.6.2 '@jest/transform': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 20.17.57 + '@types/node': 20.19.1 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -25456,7 +26213,7 @@ snapshots: '@babel/generator': 7.26.10 '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.26.10) '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.26.10) - '@babel/types': 7.26.10 + '@babel/types': 7.27.6 '@jest/expect-utils': 29.6.2 '@jest/transform': 29.6.2 '@jest/types': 29.6.1 @@ -25506,7 +26263,7 @@ snapshots: dependencies: '@jest/test-result': 29.6.2 '@jest/types': 29.6.1 - '@types/node': 20.17.57 + '@types/node': 20.19.1 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -25515,7 +26272,7 @@ snapshots: jest-worker@29.6.2: dependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 jest-util: 29.6.2 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -25532,8 +26289,22 @@ snapshots: - supports-color - ts-node + jest@29.6.2(@types/node@20.19.1)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)): + dependencies: + '@jest/core': 29.6.2(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) + '@jest/types': 29.6.1 + import-local: 3.1.0 + jest-cli: 29.6.2(@types/node@20.19.1)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jiti@1.21.0: {} + jiti@1.21.7: {} + jju@1.4.0: {} jmespath@0.16.0: {} @@ -25600,7 +26371,7 @@ snapshots: jsdom@20.0.2: dependencies: abab: 2.0.6 - acorn: 8.14.0 + acorn: 8.12.1 acorn-globals: 7.0.1 cssom: 0.5.0 cssstyle: 2.3.0 @@ -25790,7 +26561,7 @@ snapshots: kuler@2.0.0: {} - langchain@0.3.28(d0079d2993dfd2a4e9e2c2f03851bb21): + langchain@0.3.28(f9561c3b67724aa0f177a38a80041072): dependencies: '@langchain/core': 0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)) '@langchain/openai': 0.5.13(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(encoding@0.1.13)(ws@8.18.2) @@ -25813,7 +26584,7 @@ snapshots: '@langchain/groq': 0.2.3(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(encoding@0.1.13) '@langchain/mistralai': 0.2.1(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67)))(zod@3.25.67) '@langchain/ollama': 0.2.2(@langchain/core@0.3.59(openai@4.103.0(encoding@0.1.13)(ws@8.18.2)(zod@3.25.67))) - axios: 1.9.0 + axios: 1.10.0 cheerio: 1.0.0 handlebars: 4.7.8 transitivePeerDependencies: @@ -25847,6 +26618,10 @@ snapshots: lazy-ass@1.6.0: {} + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.7 + ldapts@4.2.6: dependencies: '@types/asn1': 0.2.0 @@ -25940,56 +26715,14 @@ snapshots: dependencies: immediate: 3.0.6 - lightningcss-darwin-arm64@1.30.1: - optional: true - - lightningcss-darwin-x64@1.30.1: - optional: true - - lightningcss-freebsd-x64@1.30.1: - optional: true - - lightningcss-linux-arm-gnueabihf@1.30.1: - optional: true - - lightningcss-linux-arm64-gnu@1.30.1: - optional: true - - lightningcss-linux-arm64-musl@1.30.1: - optional: true - - lightningcss-linux-x64-gnu@1.30.1: - optional: true - - lightningcss-linux-x64-musl@1.30.1: - optional: true - - lightningcss-win32-arm64-msvc@1.30.1: - optional: true - - lightningcss-win32-x64-msvc@1.30.1: - optional: true - - lightningcss@1.30.1: - dependencies: - detect-libc: 2.0.4 - optionalDependencies: - lightningcss-darwin-arm64: 1.30.1 - lightningcss-darwin-x64: 1.30.1 - lightningcss-freebsd-x64: 1.30.1 - lightningcss-linux-arm-gnueabihf: 1.30.1 - lightningcss-linux-arm64-gnu: 1.30.1 - lightningcss-linux-arm64-musl: 1.30.1 - lightningcss-linux-x64-gnu: 1.30.1 - lightningcss-linux-x64-musl: 1.30.1 - lightningcss-win32-arm64-msvc: 1.30.1 - lightningcss-win32-x64-msvc: 1.30.1 - optional: true + lil-http-terminator@1.2.3: {} lilconfig@2.1.0: {} lilconfig@3.1.2: {} + lilconfig@3.1.3: {} + lines-and-columns@1.2.4: {} linkify-it@4.0.1: @@ -26123,7 +26856,7 @@ snapshots: lossless-json@4.0.2: {} - loupe@3.1.3: {} + loupe@3.1.4: {} lower-case@1.1.4: {} @@ -26329,14 +27062,14 @@ snapshots: minifaker@1.34.1: dependencies: '@types/uuid': 8.3.4 - nanoid: 3.3.8 + nanoid: 3.3.11 uuid: 8.3.2 minimalistic-assert@1.0.1: {} - minimatch@10.0.1: + minimatch@10.0.3: dependencies: - brace-expansion: 2.0.2 + '@isaacs/brace-expansion': 5.0.0 minimatch@3.0.8: dependencies: @@ -26346,7 +27079,7 @@ snapshots: dependencies: brace-expansion: 1.1.12 - minimatch@5.1.5: + minimatch@5.1.6: dependencies: brace-expansion: 2.0.2 @@ -26450,7 +27183,7 @@ snapshots: mjml-cli@4.15.3(encoding@0.1.13): dependencies: '@babel/runtime': 7.26.10 - chokidar: 4.0.1 + chokidar: 4.0.3 glob: 10.4.5 html-minifier: 4.0.0 js-beautify: 1.14.9 @@ -26722,12 +27455,19 @@ snapshots: mkdirp@2.1.3: {} + mlly@1.7.1: + dependencies: + acorn: 8.14.0 + pathe: 1.1.2 + pkg-types: 1.1.3 + ufo: 1.5.4 + mlly@1.7.4: dependencies: acorn: 8.14.0 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.5.4 + ufo: 1.6.1 mobx-react-lite@4.0.7(mobx@6.12.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: @@ -26755,27 +27495,11 @@ snapshots: moment@2.29.4: {} - mongodb-connection-string-url@2.6.0: - dependencies: - '@types/whatwg-url': 8.2.2 - whatwg-url: 11.0.0 - optional: true - mongodb-connection-string-url@3.0.0: dependencies: '@types/whatwg-url': 11.0.4 whatwg-url: 13.0.0 - mongodb@5.9.2(@aws-sdk/credential-providers@3.808.0): - dependencies: - bson: 5.5.1 - mongodb-connection-string-url: 2.6.0 - socks: 2.8.3 - optionalDependencies: - '@aws-sdk/credential-providers': 3.808.0 - '@mongodb-js/saslprep': 1.1.9 - optional: true - mongodb@6.11.0(@aws-sdk/credential-providers@3.808.0)(gcp-metadata@5.3.0(encoding@0.1.13))(socks@2.8.3): dependencies: '@mongodb-js/saslprep': 1.1.9 @@ -26928,6 +27652,8 @@ snapshots: abort-controller-x: 0.4.3 nice-grpc-common: 2.0.2 + nice-try@1.0.5: {} + no-case@2.3.2: dependencies: lower-case: 1.1.4 @@ -26963,6 +27689,8 @@ snapshots: dependencies: http2-client: 1.3.5 + node-fetch-native@1.6.6: {} + node-fetch@2.7.0(encoding@0.1.13): dependencies: whatwg-url: 5.0.0 @@ -27078,10 +27806,19 @@ snapshots: shell-quote: 1.8.1 which: 5.0.0 + npm-run-path@2.0.2: + dependencies: + path-key: 2.0.1 + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + npmlog@6.0.2: dependencies: are-we-there-yet: 3.0.1 @@ -27105,6 +27842,15 @@ snapshots: nwsapi@2.2.7: {} + nypm@0.5.4: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + pathe: 2.0.3 + pkg-types: 1.3.1 + tinyexec: 0.3.2 + ufo: 1.6.1 + oas-kit-common@1.0.8: dependencies: fast-safe-stringify: 2.1.1 @@ -27150,14 +27896,18 @@ snapshots: object-is@1.1.6: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 object-keys@1.1.1: {} + object-sizeof@2.6.5: + dependencies: + buffer: 6.0.3 + object.assign@4.1.5: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 has-symbols: 1.1.0 object-keys: 1.1.1 @@ -27173,16 +27923,16 @@ snapshots: object.fromentries@2.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.0 es-object-atoms: 1.1.1 object.groupby@1.0.3: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.3 + es-abstract: 1.24.0 object.values@1.2.1: dependencies: @@ -27193,12 +27943,16 @@ snapshots: obuf@1.1.2: {} + ohash@1.1.6: {} + ohash@2.0.11: {} ollama@0.5.16: dependencies: whatwg-fetch: 3.6.20 + on-exit-leak-free@2.1.2: {} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -27303,6 +28057,8 @@ snapshots: p-cancelable@2.1.1: {} + p-debounce@2.1.0: {} + p-finally@1.0.0: {} p-lazy@3.1.0: {} @@ -27369,6 +28125,10 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse-ms@2.1.0: {} + + parse-ms@4.0.0: {} + parse-passwd@1.0.0: {} parse-srcset@1.0.2: {} @@ -27415,8 +28175,12 @@ snapshots: path-is-absolute@1.0.1: {} + path-key@2.0.1: {} + path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} path-scurry@1.11.1: @@ -27452,7 +28216,7 @@ snapshots: pdfjs-dist@5.3.31(patch_hash=421253c8e411cdaef58ba96d2bb44ae0784e1b3e446f5caca50710daa1fa5dcd): optionalDependencies: - '@napi-rs/canvas': 0.1.71 + '@napi-rs/canvas': 0.1.70 peberminta@0.9.0: {} @@ -27460,6 +28224,8 @@ snapshots: pend@1.2.0: {} + perfect-debounce@1.0.0: {} + perfect-scrollbar@1.5.5: {} performance-now@2.1.0: {} @@ -27542,7 +28308,27 @@ snapshots: optionalDependencies: typescript: 5.8.3 - pirates@4.0.6: {} + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-std-serializers@7.0.0: {} + + pino@9.7.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.0.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.4.0 + sonic-boom: 4.2.0 + thread-stream: 3.1.0 + + pirates@4.0.7: {} pkce-challenge@5.0.0(patch_hash=651e785d0b7bbf5be9210e1e895c39a16dc3ce8a5a3843b4819565fb6e175b90): {} @@ -27550,6 +28336,12 @@ snapshots: dependencies: find-up: 4.1.0 + pkg-types@1.1.3: + dependencies: + confbox: 0.1.8 + mlly: 1.7.4 + pathe: 1.1.2 + pkg-types@1.3.1: dependencies: confbox: 0.1.8 @@ -27562,11 +28354,11 @@ snapshots: exsolve: 1.0.4 pathe: 2.0.3 - playwright-core@1.49.1: {} + playwright-core@1.53.0: {} - playwright@1.49.1: + playwright@1.53.0: dependencies: - playwright-core: 1.49.1 + playwright-core: 1.53.0 optionalDependencies: fsevents: 2.3.2 @@ -27582,6 +28374,8 @@ snapshots: possible-typed-array-names@1.0.0: {} + possible-typed-array-names@1.1.0: {} + postcss-import@15.1.0(postcss@8.4.49): dependencies: postcss: 8.4.49 @@ -27594,19 +28388,19 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.4.49 - postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)): + postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)): dependencies: lilconfig: 3.1.2 yaml: 2.3.4 optionalDependencies: postcss: 8.4.49 - ts-node: 10.9.2(@types/node@20.17.57)(typescript@5.8.3) + ts-node: 10.9.2(@types/node@20.19.1)(typescript@5.8.3) - postcss-load-config@6.0.1(jiti@1.21.0)(postcss@8.5.6)(tsx@4.19.3): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3): dependencies: - lilconfig: 3.1.2 + lilconfig: 3.1.3 optionalDependencies: - jiti: 1.21.0 + jiti: 1.21.7 postcss: 8.5.6 tsx: 4.19.3 @@ -27620,6 +28414,11 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + postcss-value-parser@4.2.0: {} postcss@8.4.31: @@ -27629,12 +28428,6 @@ snapshots: source-map-js: 1.2.1 postcss@8.4.49: - dependencies: - nanoid: 3.3.8 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - postcss@8.5.3: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -27670,7 +28463,7 @@ snapshots: posthog-node@3.2.1: dependencies: - axios: 1.9.0 + axios: 1.10.0 rusha: 0.8.14 transitivePeerDependencies: - debug @@ -27721,10 +28514,20 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.2.0 + pretty-ms@7.0.1: + dependencies: + parse-ms: 2.1.0 + + pretty-ms@9.2.0: + dependencies: + parse-ms: 4.0.0 + prismjs@1.29.0: {} process-nextick-args@2.0.1: {} + process-warning@5.0.0: {} + process@0.11.10: {} prom-client@15.1.3: @@ -27765,6 +28568,16 @@ snapshots: propagate@2.0.1: {} + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + + properties-reader@2.3.0: + dependencies: + mkdirp: 1.0.4 + property-expr@2.0.5: {} proto-list@1.2.4: {} @@ -27786,7 +28599,7 @@ snapshots: '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 '@types/node': 20.17.57 - long: 5.2.3 + long: 5.3.2 proxy-addr@2.0.7: dependencies: @@ -27830,7 +28643,7 @@ snapshots: jstransformer: 1.0.0 pug-error: 2.1.0 pug-walk: 2.0.0 - resolve: 1.22.8 + resolve: 1.22.10 pug-lexer@5.0.1: dependencies: @@ -27916,10 +28729,14 @@ snapshots: queue-microtask@1.2.3: {} + quick-format-unescaped@4.0.4: {} + quoted-printable@1.0.1: dependencies: utf8: 2.1.2 + ramda@0.26.1: {} + random-bytes@1.0.0: {} randombytes@2.1.0: @@ -27935,6 +28752,11 @@ snapshots: iconv-lite: 0.6.3 unpipe: 1.0.0 + rc9@2.1.2: + dependencies: + defu: 6.1.4 + destr: 2.0.5 + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -28021,10 +28843,18 @@ snapshots: dependencies: readable-stream: 3.6.0 + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.6 + readdirp@4.0.2: {} + readdirp@4.1.2: {} + readline-sync@1.4.10: {} + real-require@0.2.0: {} + recast@0.22.0: dependencies: assert: 2.1.0 @@ -28136,9 +28966,18 @@ snapshots: regexp-tree@0.1.27: {} + regexp.escape@2.0.1: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + for-each: 0.3.5 + safe-regex-test: 1.1.0 + regexp.prototype.flags@1.5.3: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 es-errors: 1.3.0 set-function-name: 2.0.2 @@ -28214,7 +29053,7 @@ snapshots: dependencies: debug: 4.4.1(supports-color@8.1.1) module-details-from-path: 1.0.3 - resolve: 1.22.8 + resolve: 1.22.10 transitivePeerDependencies: - supports-color @@ -28232,6 +29071,12 @@ snapshots: resolve.exports@2.0.0: {} + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + resolve@1.22.8: dependencies: is-core-module: 2.13.1 @@ -28243,9 +29088,9 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 - retry-axios@2.6.0(axios@1.9.0): + retry-axios@2.6.0(axios@1.10.0): dependencies: - axios: 1.9.0 + axios: 1.10.0 retry-request@7.0.2(encoding@0.1.13): dependencies: @@ -28281,6 +29126,7 @@ snapshots: rimraf@3.0.2: dependencies: glob: 7.2.3 + optional: true rimraf@5.0.1: dependencies: @@ -28293,30 +29139,30 @@ snapshots: rndm@1.2.0: {} - rollup@4.44.1: + rollup@4.44.0: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.44.1 - '@rollup/rollup-android-arm64': 4.44.1 - '@rollup/rollup-darwin-arm64': 4.44.1 - '@rollup/rollup-darwin-x64': 4.44.1 - '@rollup/rollup-freebsd-arm64': 4.44.1 - '@rollup/rollup-freebsd-x64': 4.44.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.44.1 - '@rollup/rollup-linux-arm-musleabihf': 4.44.1 - '@rollup/rollup-linux-arm64-gnu': 4.44.1 - '@rollup/rollup-linux-arm64-musl': 4.44.1 - '@rollup/rollup-linux-loongarch64-gnu': 4.44.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.44.1 - '@rollup/rollup-linux-riscv64-gnu': 4.44.1 - '@rollup/rollup-linux-riscv64-musl': 4.44.1 - '@rollup/rollup-linux-s390x-gnu': 4.44.1 - '@rollup/rollup-linux-x64-gnu': 4.44.1 - '@rollup/rollup-linux-x64-musl': 4.44.1 - '@rollup/rollup-win32-arm64-msvc': 4.44.1 - '@rollup/rollup-win32-ia32-msvc': 4.44.1 - '@rollup/rollup-win32-x64-msvc': 4.44.1 + '@rollup/rollup-android-arm-eabi': 4.44.0 + '@rollup/rollup-android-arm64': 4.44.0 + '@rollup/rollup-darwin-arm64': 4.44.0 + '@rollup/rollup-darwin-x64': 4.44.0 + '@rollup/rollup-freebsd-arm64': 4.44.0 + '@rollup/rollup-freebsd-x64': 4.44.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.44.0 + '@rollup/rollup-linux-arm-musleabihf': 4.44.0 + '@rollup/rollup-linux-arm64-gnu': 4.44.0 + '@rollup/rollup-linux-arm64-musl': 4.44.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.44.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.44.0 + '@rollup/rollup-linux-riscv64-gnu': 4.44.0 + '@rollup/rollup-linux-riscv64-musl': 4.44.0 + '@rollup/rollup-linux-s390x-gnu': 4.44.0 + '@rollup/rollup-linux-x64-gnu': 4.44.0 + '@rollup/rollup-linux-x64-musl': 4.44.0 + '@rollup/rollup-win32-arm64-msvc': 4.44.0 + '@rollup/rollup-win32-ia32-msvc': 4.44.0 + '@rollup/rollup-win32-x64-msvc': 4.44.0 fsevents: 2.3.3 route-recognizer@0.3.4: {} @@ -28364,7 +29210,7 @@ snapshots: safe-array-concat@1.1.2: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 get-intrinsic: 1.3.0 has-symbols: 1.1.0 isarray: 2.0.5 @@ -28388,7 +29234,7 @@ snapshots: safe-regex-test@1.0.3: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 es-errors: 1.3.0 is-regex: 1.1.4 @@ -28558,10 +29404,16 @@ snapshots: '@img/sharp-win32-ia32': 0.33.5 '@img/sharp-win32-x64': 0.33.5 + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 + shebang-regex@1.0.0: {} + shebang-regex@3.0.0: {} shell-escape@0.2.0: {} @@ -28726,7 +29578,7 @@ snapshots: asn1.js: 5.4.1 asn1.js-rfc2560: 5.0.1(asn1.js@5.4.1) asn1.js-rfc5280: 3.0.0 - axios: 1.9.0 + axios: 1.10.0 big-integer: 1.6.52 bignumber.js: 9.1.2 binascii: 0.0.2 @@ -28772,6 +29624,10 @@ snapshots: smart-buffer: 4.2.0 optional: true + sonic-boom@4.2.0: + dependencies: + atomic-sleep: 1.0.0 + sortablejs@1.14.0: {} source-map-js@1.2.1: {} @@ -28800,6 +29656,8 @@ snapshots: spex@3.3.0: {} + split-ca@1.0.1: {} + split2@4.2.0: {} split@0.3.3: @@ -28826,6 +29684,11 @@ snapshots: sqlstring@2.3.3: {} + ssh-remote-port-forward@1.0.4: + dependencies: + '@types/ssh2': 0.5.52 + ssh2: 1.15.0 + ssh2-sftp-client@7.2.3: dependencies: concat-stream: 2.0.0 @@ -28857,7 +29720,7 @@ snapshots: minipass: 3.3.6 optional: true - stable-hash-x@0.2.0: {} + stable-hash-x@0.1.1: {} stack-trace@0.0.10: {} @@ -28892,10 +29755,6 @@ snapshots: stickyfill@1.1.1: {} - stop-iteration-iterator@1.0.0: - dependencies: - internal-slot: 1.0.7 - stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 @@ -28930,6 +29789,13 @@ snapshots: streamsearch@1.1.0: {} + streamx@2.22.1: + dependencies: + fast-fifo: 1.3.2 + text-decoder: 1.2.3 + optionalDependencies: + bare-events: 2.5.4 + strict-event-emitter-types@2.0.0: {} strict-event-emitter@0.5.1: {} @@ -28965,15 +29831,9 @@ snapshots: string.prototype.trim@1.2.9: dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.1.1 - - string.prototype.trimend@1.0.8: - dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 + es-abstract: 1.24.0 es-object-atoms: 1.1.1 string.prototype.trimend@1.0.9: @@ -28985,7 +29845,7 @@ snapshots: string.prototype.trimstart@1.0.8: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 define-properties: 1.2.1 es-object-atoms: 1.1.1 @@ -29011,8 +29871,12 @@ snapshots: strip-bom@4.0.0: {} + strip-eof@1.0.0: {} + strip-final-newline@2.0.0: {} + strip-final-newline@4.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -29061,7 +29925,7 @@ snapshots: glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 - pirates: 4.0.6 + pirates: 4.0.7 ts-interface-checker: 0.1.13 superagent@10.2.1: @@ -29138,14 +30002,14 @@ snapshots: systemjs@6.15.1: {} - tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)): + tailwindcss@3.4.3(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 chokidar: 4.0.1 didyoumean: 1.2.2 dlv: 1.1.3 - fast-glob: 3.3.2 + fast-glob: 3.3.3 glob-parent: 6.0.2 is-glob: 4.0.3 jiti: 1.21.0 @@ -29157,7 +30021,7 @@ snapshots: postcss: 8.4.49 postcss-import: 15.1.0(postcss@8.4.49) postcss-js: 4.0.1(postcss@8.4.49) - postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@types/node@20.17.57)(typescript@5.8.3)) + postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3)) postcss-nested: 6.0.1(postcss@8.4.49) postcss-selector-parser: 6.0.16 resolve: 1.22.8 @@ -29180,6 +30044,12 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.0 + tar-stream@3.1.7: + dependencies: + b4a: 1.6.7 + fast-fifo: 1.3.2 + streamx: 2.22.1 + tar@6.2.1: dependencies: chownr: 2.0.0 @@ -29246,6 +30116,30 @@ snapshots: glob: 10.4.5 minimatch: 9.0.5 + testcontainers@11.0.3: + dependencies: + '@balena/dockerignore': 1.0.2 + '@types/dockerode': 3.3.41 + archiver: 7.0.1 + async-lock: 1.4.1 + byline: 5.0.0 + debug: 4.4.1(supports-color@8.1.1) + docker-compose: 1.2.0 + dockerode: 4.0.7 + get-port: 7.1.0 + proper-lockfile: 4.1.2 + properties-reader: 2.3.0 + ssh-remote-port-forward: 1.0.4 + tar-fs: 2.1.3 + tmp: 0.2.3 + undici: 7.10.0 + transitivePeerDependencies: + - supports-color + + text-decoder@1.2.3: + dependencies: + b4a: 1.6.7 + text-hex@1.0.0: {} thenify-all@1.6.0: @@ -29258,6 +30152,10 @@ snapshots: thirty-two@1.0.2: {} + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 + throttleit@1.0.0: {} through@2.3.8: {} @@ -29275,7 +30173,7 @@ snapshots: fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 - tinypool@1.0.2: {} + tinypool@1.1.1: {} tinyrainbow@1.2.0: {} @@ -29297,16 +30195,12 @@ snapshots: tmp-promise@3.0.3: dependencies: - tmp: 0.2.1 + tmp: 0.2.3 tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 - tmp@0.2.1: - dependencies: - rimraf: 3.0.2 - tmp@0.2.3: {} tmpl@1.0.5: {} @@ -29388,7 +30282,7 @@ snapshots: triple-beam@1.3.0: {} - ts-api-utils@1.0.1(typescript@5.8.3): + ts-api-utils@1.4.3(typescript@5.8.3): dependencies: typescript: 5.8.3 @@ -29455,6 +30349,27 @@ snapshots: yn: 3.1.1 optional: true + ts-node@10.9.2(@types/node@20.19.1)(typescript@5.8.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.19.1 + acorn: 8.14.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.8.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optional: true + + ts-pattern@5.7.1: {} + ts-toolbelt@9.6.0: {} ts-type@3.0.1(ts-toolbelt@9.6.0): @@ -29493,27 +30408,27 @@ snapshots: tsscmp@1.0.6: {} - tsup@8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.17.57))(jiti@1.21.0)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3): + tsup@8.5.0(@microsoft/api-extractor@7.52.1(@types/node@20.19.1))(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3)(typescript@5.8.3): dependencies: - bundle-require: 5.1.0(esbuild@0.24.0) + bundle-require: 5.1.0(esbuild@0.24.2) cac: 6.7.14 - chokidar: 4.0.1 - consola: 3.4.0 + chokidar: 4.0.3 + consola: 3.4.2 debug: 4.4.1(supports-color@8.1.1) - esbuild: 0.24.0 + esbuild: 0.24.2 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@1.21.0)(postcss@8.5.6)(tsx@4.19.3) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3) resolve-from: 5.0.0 - rollup: 4.44.1 + rollup: 4.44.0 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tinyexec: 0.3.2 tinyglobby: 0.2.14 tree-kill: 1.2.2 optionalDependencies: - '@microsoft/api-extractor': 7.52.1(@types/node@20.17.57) + '@microsoft/api-extractor': 7.52.1(@types/node@20.19.1) postcss: 8.5.6 typescript: 5.8.3 transitivePeerDependencies: @@ -29524,8 +30439,8 @@ snapshots: tsx@4.19.3: dependencies: - esbuild: 0.24.0 - get-tsconfig: 4.10.0 + esbuild: 0.24.2 + get-tsconfig: 4.10.1 optionalDependencies: fsevents: 2.3.3 @@ -29578,6 +30493,8 @@ snapshots: type-detect@4.0.8: {} + type-fest@0.20.2: {} + type-fest@0.21.3: {} type-fest@2.19.0: {} @@ -29599,7 +30516,7 @@ snapshots: typed-array-buffer@1.0.2: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 es-errors: 1.3.0 is-typed-array: 1.1.13 @@ -29611,7 +30528,7 @@ snapshots: typed-array-byte-length@1.0.1: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 for-each: 0.3.3 gopd: 1.2.0 has-proto: 1.0.3 @@ -29620,7 +30537,7 @@ snapshots: typed-array-byte-length@1.0.3: dependencies: call-bind: 1.0.8 - for-each: 0.3.3 + for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 is-typed-array: 1.1.15 @@ -29628,7 +30545,7 @@ snapshots: typed-array-byte-offset@1.0.2: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.7 + call-bind: 1.0.8 for-each: 0.3.3 gopd: 1.2.0 has-proto: 1.0.3 @@ -29638,7 +30555,7 @@ snapshots: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.8 - for-each: 0.3.3 + for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 is-typed-array: 1.1.15 @@ -29646,7 +30563,7 @@ snapshots: typed-array-length@1.0.6: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 for-each: 0.3.3 gopd: 1.2.0 has-proto: 1.0.3 @@ -29656,22 +30573,22 @@ snapshots: typed-array-length@1.0.7: dependencies: call-bind: 1.0.8 - for-each: 0.3.3 + for-each: 0.3.5 gopd: 1.2.0 is-typed-array: 1.1.15 - possible-typed-array-names: 1.0.0 + possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 typedarray-dts@1.0.0: {} typedarray@0.0.6: {} - typescript-eslint@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3): + typescript-eslint@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) - '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.0))(typescript@5.8.3) - eslint: 9.29.0(jiti@1.21.0) + '@typescript-eslint/eslint-plugin': 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3))(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.8.3) + eslint: 9.29.0(jiti@1.21.7) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -29684,6 +30601,8 @@ snapshots: ufo@1.5.4: {} + ufo@1.6.1: {} + uglify-js@3.17.4: {} uid-safe@2.1.5: @@ -29692,7 +30611,7 @@ snapshots: unbox-primitive@1.0.2: dependencies: - call-bind: 1.0.7 + call-bind: 1.0.8 has-bigints: 1.0.2 has-symbols: 1.1.0 which-boxed-primitive: 1.0.2 @@ -29700,7 +30619,7 @@ snapshots: unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 - has-bigints: 1.0.2 + has-bigints: 1.1.0 has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 @@ -29712,6 +30631,8 @@ snapshots: undici-types@6.19.8: {} + undici-types@6.21.0: {} + undici@6.21.3: {} undici@7.10.0: {} @@ -29727,6 +30648,8 @@ snapshots: unicode-property-aliases-ecmascript@2.1.0: {} + unicorn-magic@0.3.0: {} + unique-filename@1.1.1: dependencies: unique-slug: 2.0.2 @@ -29748,7 +30671,7 @@ snapshots: '@antfu/install-pkg': 0.3.3 '@antfu/utils': 0.7.10 '@iconify/utils': 2.1.25 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.0 kolorist: 1.8.0 local-pkg: 0.5.0 unplugin: 1.11.0 @@ -29757,13 +30680,13 @@ snapshots: transitivePeerDependencies: - supports-color - unplugin-vue-components@0.27.3(@babel/parser@7.27.5)(rollup@4.44.1)(vue@3.5.13(typescript@5.8.3)): + unplugin-vue-components@0.27.3(@babel/parser@7.27.5)(rollup@4.44.0)(vue@3.5.13(typescript@5.8.3)): dependencies: '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.4(rollup@4.44.1) - chokidar: 4.0.1 + '@rollup/pluginutils': 5.1.4(rollup@4.44.0) + chokidar: 4.0.3 debug: 4.4.1(supports-color@8.1.1) - fast-glob: 3.3.2 + fast-glob: 3.3.3 local-pkg: 0.5.0 magic-string: 0.30.17 minimatch: 9.0.5 @@ -29779,7 +30702,7 @@ snapshots: unplugin@1.11.0: dependencies: acorn: 8.14.0 - chokidar: 4.0.1 + chokidar: 4.0.3 webpack-sources: 3.2.3 webpack-virtual-modules: 0.6.1 @@ -29815,6 +30738,12 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + update-browserslist-db@1.1.3(browserslist@4.25.0): + dependencies: + browserslist: 4.25.0 + escalade: 3.2.0 + picocolors: 1.1.1 + upper-case-first@2.0.2: dependencies: tslib: 2.8.1 @@ -29899,13 +30828,13 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite-node@3.1.3(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3): + vite-node@3.1.3(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3): dependencies: cac: 6.7.14 debug: 4.4.1(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + vite: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) transitivePeerDependencies: - '@types/node' - jiti @@ -29920,10 +30849,10 @@ snapshots: - tsx - yaml - vite-plugin-dts@4.5.3(@types/node@20.17.57)(rollup@4.44.1)(typescript@5.8.3)(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)): + vite-plugin-dts@4.5.3(@types/node@20.19.1)(rollup@4.44.0)(typescript@5.8.3)(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)): dependencies: - '@microsoft/api-extractor': 7.52.1(@types/node@20.17.57) - '@rollup/pluginutils': 5.1.4(rollup@4.44.1) + '@microsoft/api-extractor': 7.52.1(@types/node@20.19.1) + '@rollup/pluginutils': 5.1.4(rollup@4.44.0) '@volar/typescript': 2.4.12 '@vue/language-core': 2.2.0(typescript@5.8.3) compare-versions: 6.1.1 @@ -29933,69 +30862,67 @@ snapshots: magic-string: 0.30.17 typescript: 5.8.3 optionalDependencies: - vite: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + vite: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite-plugin-static-copy@2.2.0(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)): + vite-plugin-static-copy@2.2.0(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)): dependencies: chokidar: 4.0.1 - fast-glob: 3.3.2 + fast-glob: 3.3.3 fs-extra: 11.3.0 picocolors: 1.1.1 - vite: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + vite: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) vite-svg-loader@5.1.0(vue@3.5.13(typescript@5.8.3)): dependencies: svgo: 3.3.2 vue: 3.5.13(typescript@5.8.3) - vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3): + vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3): dependencies: - esbuild: 0.24.0 + esbuild: 0.24.2 fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 postcss: 8.5.6 - rollup: 4.44.1 + rollup: 4.44.0 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 fsevents: 2.3.3 - jiti: 1.21.0 - lightningcss: 1.30.1 + jiti: 1.21.7 sass: 1.64.1 terser: 5.16.1 tsx: 4.19.3 - vite@7.0.0(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(terser@5.16.1)(tsx@4.19.3): + vite@7.0.0(@types/node@20.19.1)(jiti@1.21.7)(terser@5.16.1)(tsx@4.19.3): dependencies: - esbuild: 0.24.0 + esbuild: 0.24.2 fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 postcss: 8.5.6 - rollup: 4.44.1 + rollup: 4.44.0 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 20.17.57 + '@types/node': 20.19.1 fsevents: 2.3.3 - jiti: 1.21.0 - lightningcss: 1.30.1 + jiti: 1.21.7 terser: 5.16.1 tsx: 4.19.3 - vitest-mock-extended@3.1.0(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)): + vitest-mock-extended@3.1.0(typescript@5.8.3)(vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)): dependencies: ts-essentials: 10.0.2(typescript@5.8.3) typescript: 5.8.3 - vitest: 3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + vitest: 3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) - vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.17.57)(jiti@1.21.0)(jsdom@23.0.1)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3): + vitest@3.1.3(@types/debug@4.1.12)(@types/node@20.19.1)(jiti@1.21.7)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3): dependencies: '@vitest/expect': 3.1.3 - '@vitest/mocker': 3.1.3(vite@6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) - '@vitest/pretty-format': 3.1.3 + '@vitest/mocker': 3.1.3(vite@6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3)) + '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.1.3 '@vitest/snapshot': 3.1.3 '@vitest/spy': 3.1.3 @@ -30009,14 +30936,14 @@ snapshots: tinybench: 2.9.0 tinyexec: 0.3.2 tinyglobby: 0.2.14 - tinypool: 1.0.2 + tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) - vite-node: 3.1.3(@types/node@20.17.57)(jiti@1.21.0)(lightningcss@1.30.1)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + vite: 6.3.5(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) + vite-node: 3.1.3(@types/node@20.19.1)(jiti@1.21.7)(sass@1.64.1)(terser@5.16.1)(tsx@4.19.3) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 20.17.57 + '@types/node': 20.19.1 jsdom: 23.0.1 transitivePeerDependencies: - jiti @@ -30083,13 +31010,13 @@ snapshots: vue: 3.5.13(typescript@5.8.3) vue-inbrowser-compiler-independent-utils: 4.71.1(vue@3.5.13(typescript@5.8.3)) - vue-eslint-parser@9.4.2(eslint@9.29.0(jiti@1.21.0)): + vue-eslint-parser@10.1.3(eslint@9.29.0(jiti@1.21.7)): dependencies: debug: 4.4.1(supports-color@8.1.1) - eslint: 9.29.0(jiti@1.21.0) - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 + eslint: 9.29.0(jiti@1.21.7) + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 esquery: 1.6.0 lodash: 4.17.21 semver: 7.7.2 @@ -30175,7 +31102,7 @@ snapshots: wait-on@8.0.2(debug@4.4.0): dependencies: - axios: 1.9.0(debug@4.4.0) + axios: 1.10.0(debug@4.4.0) joi: 17.13.3 lodash: 4.17.21 minimist: 1.2.8 @@ -30272,7 +31199,7 @@ snapshots: is-bigint: 1.0.4 is-boolean-object: 1.1.2 is-number-object: 1.0.7 - is-string: 1.0.7 + is-string: 1.1.1 is-symbol: 1.0.4 which-boxed-primitive@1.1.1: @@ -30291,7 +31218,7 @@ snapshots: is-async-function: 2.1.1 is-date-object: 1.1.0 is-finalizationregistry: 1.1.1 - is-generator-function: 1.0.10 + is-generator-function: 1.1.0 is-regex: 1.2.1 is-weakref: 1.1.1 isarray: 2.0.5 @@ -30299,13 +31226,6 @@ snapshots: which-collection: 1.0.2 which-typed-array: 1.1.19 - which-collection@1.0.1: - dependencies: - is-map: 2.0.2 - is-set: 2.0.2 - is-weakmap: 2.0.1 - is-weakset: 2.0.2 - which-collection@1.0.2: dependencies: is-map: 2.0.3 @@ -30316,7 +31236,7 @@ snapshots: which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.7 + call-bind: 1.0.8 for-each: 0.3.3 gopd: 1.2.0 has-tostringtag: 1.0.2 @@ -30331,6 +31251,10 @@ snapshots: gopd: 1.2.0 has-tostringtag: 1.0.2 + which@1.3.1: + dependencies: + isexe: 2.0.0 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -30388,7 +31312,7 @@ snapshots: with@7.0.2: dependencies: '@babel/parser': 7.27.5 - '@babel/types': 7.26.10 + '@babel/types': 7.27.6 assert-never: 1.2.1 babel-walk: 3.0.0-canary-5 @@ -30564,6 +31488,8 @@ snapshots: yocto-queue@0.1.0: {} + yoctocolors@2.1.1: {} + yup@0.32.11: dependencies: '@babel/runtime': 7.26.10 @@ -30574,6 +31500,12 @@ snapshots: property-expr: 2.0.5 toposort: 2.0.2 + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.5.2 + zod-class@0.0.16(zod@3.25.67): dependencies: type-fest: 4.26.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b00e2cf848..9eadbca9b3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,6 +4,7 @@ packages: - packages/frontend/** - packages/extensions/** - cypress + - packages/testing/** catalog: '@n8n/typeorm': 0.3.20-12 diff --git a/scripts/build-n8n.mjs b/scripts/build-n8n.mjs index 1cd02ca730..e5710c01d5 100755 --- a/scripts/build-n8n.mjs +++ b/scripts/build-n8n.mjs @@ -22,7 +22,7 @@ const scriptDir = path.dirname(new URL(import.meta.url).pathname); const isInScriptsDir = path.basename(scriptDir) === 'scripts'; const rootDir = isInScriptsDir ? path.join(scriptDir, '..') : scriptDir; -// --- Configuration --- +// #region ===== Configuration ===== const config = { compiledAppDir: process.env.BUILD_OUTPUT_DIR || path.join(rootDir, 'compiled'), rootDir: rootDir, @@ -31,7 +31,9 @@ const config = { // Define backend patches to keep during deployment const PATCHES_TO_KEEP = ['pdfjs-dist', 'pkce-challenge', 'bull']; -// --- Helper Functions --- +// #endregion ===== Configuration ===== + +// #region ===== Helper Functions ===== const timers = new Map(); function startTimer(name) { @@ -63,7 +65,9 @@ function printDivider() { echo(chalk.gray('-----------------------------------------------')); } -// --- Main Build Process --- +// #endregion ===== Helper Functions ===== + +// #region ===== Main Build Process ===== printHeader('n8n Build & Production Preparation'); echo(`INFO: Output Directory: ${config.compiledAppDir}`); printDivider(); @@ -196,7 +200,9 @@ printDivider(); // Calculate total time const totalBuildTime = getElapsedTime('total_build'); -// --- Final Output --- +// #endregion ===== Main Build Process ===== + +// #region ===== Final Output ===== echo(''); echo(chalk.green.bold('================ BUILD SUMMARY ================')); echo(chalk.green(`✅ n8n built successfully!`)); @@ -215,5 +221,7 @@ echo(chalk.blue('📋 Build Manifest:')); echo(` ${path.resolve(config.compiledAppDir)}/build-manifest.json`); echo(chalk.green.bold('==============================================')); +// #endregion ===== Final Output ===== + // Exit with success process.exit(0); diff --git a/scripts/dockerize-n8n.mjs b/scripts/dockerize-n8n.mjs index 522d293d52..5b3ec45a91 100755 --- a/scripts/dockerize-n8n.mjs +++ b/scripts/dockerize-n8n.mjs @@ -1,88 +1,170 @@ #!/usr/bin/env node /** - * This script is used to build the n8n docker image locally. - * It simulates how we build for CI and should allow for local testing. - * By default it outputs the tag 'dev' and the image name 'n8n-local:dev'. - * It can be overridden by setting the IMAGE_BASE_NAME and IMAGE_TAG environment variables. + * Build n8n Docker image locally + * + * This script simulates the CI build process for local testing. + * Default output: 'n8nio/n8n:local' + * Override with IMAGE_BASE_NAME and IMAGE_TAG environment variables. */ -import { $, echo, fs, chalk } from 'zx'; +import { $, echo, fs, chalk, os } from 'zx'; +import { fileURLToPath } from 'url'; import path from 'path'; // Disable verbose mode for cleaner output $.verbose = false; process.env.FORCE_COLOR = '1'; +process.env.DOCKER_BUILDKIT = '1'; -// --- Determine script location --- -const scriptDir = path.dirname(new URL(import.meta.url).pathname); -const isInScriptsDir = path.basename(scriptDir) === 'scripts'; -const rootDir = isInScriptsDir ? path.join(scriptDir, '..') : scriptDir; +// #region ===== Helper Functions ===== + +/** + * Get Docker platform string based on host architecture + * @returns {string} Platform string (e.g., 'linux/amd64') + */ +function getDockerPlatform() { + const arch = os.arch(); + const dockerArch = { + x64: 'amd64', + arm64: 'arm64', + }[arch]; + + if (!dockerArch) { + throw new Error(`Unsupported architecture: ${arch}. Only x64 and arm64 are supported.`); + } + + return `linux/${dockerArch}`; +} + +/** + * Format duration in seconds + * @param {number} ms - Duration in milliseconds + * @returns {string} Formatted duration + */ +function formatDuration(ms) { + return `${Math.floor(ms / 1000)}s`; +} + +/** + * Get Docker image size + * @param {string} imageName - Full image name with tag + * @returns {Promise} Image size or 'Unknown' + */ +async function getImageSize(imageName) { + try { + const { stdout } = await $`docker images ${imageName} --format "{{.Size}}"`; + return stdout.trim(); + } catch { + return 'Unknown'; + } +} + +/** + * Check if a command exists + * @param {string} command - Command to check + * @returns {Promise} True if command exists + */ +async function commandExists(command) { + try { + await $`command -v ${command}`; + return true; + } catch { + return false; + } +} + +// #endregion ===== Helper Functions ===== + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const isInScriptsDir = path.basename(__dirname) === 'scripts'; +const rootDir = isInScriptsDir ? path.join(__dirname, '..') : __dirname; -// --- Configuration --- const config = { dockerfilePath: path.join(rootDir, 'docker/images/n8n/Dockerfile'), - imageBaseName: process.env.IMAGE_BASE_NAME || 'n8n-local', - imageTag: process.env.IMAGE_TAG || 'dev', + imageBaseName: process.env.IMAGE_BASE_NAME || 'n8nio/n8n', + imageTag: process.env.IMAGE_TAG || 'local', buildContext: rootDir, compiledAppDir: path.join(rootDir, 'compiled'), + get fullImageName() { + return `${this.imageBaseName}:${this.imageTag}`; + }, }; -config.fullImageName = `${config.imageBaseName}:${config.imageTag}`; +// #region ===== Main Build Process ===== -// --- Check Prerequisites --- -echo(chalk.blue.bold('===== Docker Build for n8n =====')); -echo(`INFO: Image: ${config.fullImageName}`); -echo(chalk.gray('-----------------------------------------------')); +const platform = getDockerPlatform(); -// Check if compiled directory exists -if (!(await fs.pathExists(config.compiledAppDir))) { - echo(chalk.red(`Error: Compiled app directory not found at ${config.compiledAppDir}`)); - echo(chalk.yellow('Please run build-n8n.mjs first!')); +async function main() { + echo(chalk.blue.bold('===== Docker Build for n8n =====')); + echo(`INFO: Image: ${config.fullImageName}`); + echo(`INFO: Platform: ${platform}`); + echo(chalk.gray('-'.repeat(47))); + + await checkPrerequisites(); + + // Build Docker image + const buildTime = await buildDockerImage(); + + // Get image details + const imageSize = await getImageSize(config.fullImageName); + + // Display summary + displaySummary({ + imageName: config.fullImageName, + platform, + size: imageSize, + buildTime, + }); +} + +async function checkPrerequisites() { + if (!(await fs.pathExists(config.compiledAppDir))) { + echo(chalk.red(`Error: Compiled app directory not found at ${config.compiledAppDir}`)); + echo(chalk.yellow('Please run build-n8n.mjs first!')); + process.exit(1); + } + + if (!(await commandExists('docker'))) { + echo(chalk.red('Error: Docker is not installed or not in PATH')); + process.exit(1); + } +} + +async function buildDockerImage() { + const startTime = Date.now(); + echo(chalk.yellow('INFO: Building Docker image...')); + + try { + const { stdout } = await $`DOCKER_BUILDKIT=1 docker build \ + --platform ${platform} \ + -t ${config.fullImageName} \ + -f ${config.dockerfilePath} \ + ${config.buildContext}`; + + echo(stdout); + return formatDuration(Date.now() - startTime); + } catch (error) { + echo(chalk.red(`ERROR: Docker build failed: ${error.stderr || error.message}`)); + process.exit(1); + } +} + +function displaySummary({ imageName, platform, size, buildTime }) { + echo(''); + echo(chalk.green.bold('═'.repeat(54))); + echo(chalk.green.bold(' DOCKER BUILD COMPLETE')); + echo(chalk.green.bold('═'.repeat(54))); + echo(chalk.green(`✅ Image built: ${imageName}`)); + echo(` Platform: ${platform}`); + echo(` Size: ${size}`); + echo(` Build time: ${buildTime}`); + echo(chalk.green.bold('═'.repeat(54))); +} + +// #endregion ===== Main Build Process ===== + +main().catch((error) => { + echo(chalk.red(`Unexpected error: ${error.message}`)); process.exit(1); -} - -// Check Docker -try { - await $`command -v docker`; -} catch { - echo(chalk.red('Error: Docker is not installed or not in PATH')); - process.exit(1); -} - -// --- Build Docker Image --- -const startTime = Date.now(); -echo(chalk.yellow('INFO: Building Docker image...')); - -try { - const buildOutput = await $`docker build \ - -t ${config.fullImageName} \ - -f ${config.dockerfilePath} \ - ${config.buildContext}`; - - echo(buildOutput.stdout); -} catch (error) { - echo(chalk.red(`ERROR: Docker build failed: ${error.stderr || error.message}`)); - process.exit(1); -} - -const buildTime = Math.floor((Date.now() - startTime) / 1000); - -// Get image size -let imageSize = 'Unknown'; -try { - const sizeOutput = await $`docker images ${config.fullImageName} --format "{{.Size}}"`; - imageSize = sizeOutput.stdout.trim(); -} catch (error) { - echo(chalk.yellow('Warning: Could not get image size')); -} - -// --- Summary --- -echo(''); -echo(chalk.green.bold('================ DOCKER BUILD COMPLETE ================')); -echo(chalk.green(`✅ Image built: ${config.fullImageName}`)); -echo(` Size: ${imageSize}`); -echo(` Build time: ${buildTime}s`); -echo(chalk.green.bold('====================================================')); - -// Exit with success -process.exit(0); +}); diff --git a/scripts/scan-n8n-image.mjs b/scripts/scan-n8n-image.mjs index 6d42307bcd..79c3a5f88d 100755 --- a/scripts/scan-n8n-image.mjs +++ b/scripts/scan-n8n-image.mjs @@ -14,10 +14,10 @@ const scriptDir = path.dirname(new URL(import.meta.url).pathname); const isInScriptsDir = path.basename(scriptDir) === 'scripts'; const rootDir = isInScriptsDir ? path.join(scriptDir, '..') : scriptDir; -// --- Configuration --- +// #region ===== Configuration ===== const config = { - imageBaseName: process.env.IMAGE_BASE_NAME || 'n8n-local', - imageTag: process.env.IMAGE_TAG || 'dev', + imageBaseName: process.env.IMAGE_BASE_NAME || 'n8nio/n8n', + imageTag: process.env.IMAGE_TAG || 'local', trivyImage: process.env.TRIVY_IMAGE || 'aquasec/trivy:latest', severity: process.env.TRIVY_SEVERITY || 'CRITICAL,HIGH,MEDIUM,LOW', outputFormat: process.env.TRIVY_FORMAT || 'table', @@ -56,7 +56,9 @@ const printSummary = (status, time, message) => { echo(chalk.blue.bold('========================')); }; -// --- Main Process --- +// #endregion ===== Configuration ===== + +// #region ===== Main Process ===== (async () => { printHeader('Trivy Security Scan for n8n Image'); @@ -150,3 +152,5 @@ const printSummary = (status, time, message) => { } } })(); + +// #endregion ===== Main Process ===== diff --git a/turbo.json b/turbo.json index f439571867..c5b8a0f5b0 100644 --- a/turbo.json +++ b/turbo.json @@ -11,6 +11,9 @@ "clean": { "cache": false }, + "build:playwright": { + "dependsOn": ["install-browsers", "build"] + }, "build:backend": { "dependsOn": ["n8n#build"] }, @@ -139,6 +142,12 @@ "dev": { "cache": false, "persistent": true + }, + "install-browsers": { + "cache": true, + "inputs": ["package.json"], + "outputs": ["ms-playwright-cache/**"], + "env": ["PLAYWRIGHT_BROWSERS_PATH"] } } }