From 0a28d9b7644d2ecf0fa6613f35a8a7aa8b2ea3eb Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Wed, 16 Sep 2026 13:36:41 -0300 Subject: [PATCH] feat: add e2e tests for API (#15760) * feat: add e2e tests for API * fix pnpm * ci * test on push for now * workflow_dispatch * fix lint * fix CI build on mac * fix audit * fix tests * fix windows CI * fix tests * install driver fix * fix windows test * test ci * test * test * fix ci * actually fix windows ci test * test * pin * fix tests * remove api env override * bump actions, fix workaround * code review * bump deps --- .changes/macos-app-set-theme-window-theme.md | 5 + .github/workflows/lint-js.yml | 2 + .github/workflows/test-api-e2e.yml | 143 + .scripts/ci/collect-macos-crash-reports.sh | 50 + Cargo.lock | 52 +- crates/tauri-runtime-wry/src/lib.rs | 11 + examples/api/src-tauri/Cargo.toml | 8 + .../api/src-tauri/capabilities/run-app.json | 3 +- examples/api/src-tauri/src/lib.rs | 12 +- examples/api/src/App.svelte | 25 +- package.json | 1 + packages/api-e2e/README.md | 130 + packages/api-e2e/package.json | 26 + packages/api-e2e/tauri.e2e.conf.json | 16 + packages/api-e2e/test/helpers/index.ts | 163 + packages/api-e2e/test/specs/app.spec.ts | 57 + packages/api-e2e/test/specs/core.spec.ts | 92 + packages/api-e2e/test/specs/dpi.spec.ts | 65 + packages/api-e2e/test/specs/event.spec.ts | 125 + packages/api-e2e/test/specs/image.spec.ts | 41 + packages/api-e2e/test/specs/menu.spec.ts | 95 + packages/api-e2e/test/specs/path.spec.ts | 57 + packages/api-e2e/test/specs/tray.spec.ts | 42 + packages/api-e2e/test/specs/webview.spec.ts | 42 + .../api-e2e/test/specs/webviewWindow.spec.ts | 61 + packages/api-e2e/test/specs/window.spec.ts | 254 ++ packages/api-e2e/test/types/global.d.ts | 17 + packages/api-e2e/tsconfig.json | 25 + packages/api-e2e/wdio.conf.ts | 296 ++ pnpm-lock.yaml | 3380 ++++++++++++++++- pnpm-workspace.yaml | 26 + 31 files changed, 5282 insertions(+), 40 deletions(-) create mode 100644 .changes/macos-app-set-theme-window-theme.md create mode 100644 .github/workflows/test-api-e2e.yml create mode 100755 .scripts/ci/collect-macos-crash-reports.sh create mode 100644 packages/api-e2e/README.md create mode 100644 packages/api-e2e/package.json create mode 100644 packages/api-e2e/tauri.e2e.conf.json create mode 100644 packages/api-e2e/test/helpers/index.ts create mode 100644 packages/api-e2e/test/specs/app.spec.ts create mode 100644 packages/api-e2e/test/specs/core.spec.ts create mode 100644 packages/api-e2e/test/specs/dpi.spec.ts create mode 100644 packages/api-e2e/test/specs/event.spec.ts create mode 100644 packages/api-e2e/test/specs/image.spec.ts create mode 100644 packages/api-e2e/test/specs/menu.spec.ts create mode 100644 packages/api-e2e/test/specs/path.spec.ts create mode 100644 packages/api-e2e/test/specs/tray.spec.ts create mode 100644 packages/api-e2e/test/specs/webview.spec.ts create mode 100644 packages/api-e2e/test/specs/webviewWindow.spec.ts create mode 100644 packages/api-e2e/test/specs/window.spec.ts create mode 100644 packages/api-e2e/test/types/global.d.ts create mode 100644 packages/api-e2e/tsconfig.json create mode 100644 packages/api-e2e/wdio.conf.ts diff --git a/.changes/macos-app-set-theme-window-theme.md b/.changes/macos-app-set-theme-window-theme.md new file mode 100644 index 000000000..3482d9f96 --- /dev/null +++ b/.changes/macos-app-set-theme-window-theme.md @@ -0,0 +1,5 @@ +--- +"tauri-runtime-wry": patch:bug +--- + +On macOS, `App::set_theme` now also updates the theme each window reports, so `Window::theme` (and `getCurrentWindow().theme()` in JavaScript) reflects the app-level theme instead of keeping the previous value until the system appearance changes. diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml index afc3a9ef3..2d2ce6de4 100644 --- a/.github/workflows/lint-js.yml +++ b/.github/workflows/lint-js.yml @@ -40,4 +40,6 @@ jobs: node-version: 'lts/*' cache: 'pnpm' - run: pnpm i --frozen-lockfile + - run: pnpm build + working-directory: packages/api - run: pnpm ts:check diff --git a/.github/workflows/test-api-e2e.yml b/.github/workflows/test-api-e2e.yml new file mode 100644 index 000000000..d25db7c09 --- /dev/null +++ b/.github/workflows/test-api-e2e.yml @@ -0,0 +1,143 @@ +# Copyright 2019-2024 Tauri Programme within The Commons Conservancy +# SPDX-License-Identifier: Apache-2.0 +# SPDX-License-Identifier: MIT + +name: test `@tauri-apps/api` e2e + +on: + workflow_dispatch: + push: + branches: + - dev + pull_request: + paths: + - '.github/workflows/test-api-e2e.yml' + - 'packages/api/**' + - 'packages/api-e2e/**' + - 'examples/api/**' + +env: + RUST_BACKTRACE: 1 + CARGO_PROFILE_DEV_DEBUG: 0 # keeps the target folder small for better cache efficiency + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + test: + runs-on: ${{ matrix.platform.os }} + + strategy: + fail-fast: false + matrix: + platform: + - { name: Linux, os: ubuntu-latest } + - { name: Windows, os: windows-latest } + - { name: macOS, os: macos-latest } + + steps: + - uses: actions/checkout@v7 + + - name: install Rust stable + uses: dtolnay/rust-toolchain@stable + + - run: npm i -g --force corepack + - name: setup node + uses: actions/setup-node@v7 + with: + node-version: 'lts/*' + cache: 'pnpm' + + - name: install Linux dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y \ + libwebkit2gtk-4.1-dev \ + webkit2gtk-driver \ + libgtk-3-dev \ + libayatana-appindicator3-dev \ + librsvg2-dev \ + xvfb \ + fluxbox + + # install a matching Microsoft Edge Driver version using msedgedriver-tool + - name: install msedgedriver (Windows) + if: runner.os == 'Windows' + run: | + cargo install --git https://github.com/chippers/msedgedriver-tool + & "$HOME/.cargo/bin/msedgedriver-tool.exe" + $PWD.Path >> $env:GITHUB_PATH + + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.platform.os }} + + - name: install dependencies + run: pnpm i --frozen-lockfile + + - name: build @tauri-apps/api + run: pnpm build:api + + - name: build @tauri-apps/cli + run: pnpm build:cli + + - name: run e2e tests (Linux) + if: runner.os == 'Linux' + timeout-minutes: 45 + # A real window manager (fluxbox) is started so that window-state tests + # (minimize/maximize/fullscreen/position) behave. The tray host is absent + # in this environment, so the tray module is skipped. + run: | + xvfb-run --auto-servernum -- bash -c ' + fluxbox >/dev/null 2>&1 & + sleep 1 + E2E_SKIP=tray E2E_SPEC_RETRIES=1 pnpm test:api-e2e + ' + + - name: run e2e tests (Windows) + if: runner.os == 'Windows' + timeout-minutes: 45 + shell: pwsh + # msedgedriver hands the app the `--remote-debugging-port` it attaches to through + # `WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS`, and WebView2 ignores that variable in an + # elevated process, which is what the runner gives us. gsudo runs the suite at medium + # integrity instead, and the workspace is opened up so the de-elevated process can use it. + # See https://github.com/tauri-apps/wry/issues/1782 and + # https://github.com/MicrosoftEdge/WebView2Feedback/issues/5645. + # The runner has an interactive desktop session, so window-state tests run as-is; + # the tray module is skipped to match the Linux job. + env: + E2E_SKIP: tray + E2E_SPEC_RETRIES: '1' + run: | + winget install gerardog.gsudo --accept-source-agreements --accept-package-agreements + icacls "$env:GITHUB_WORKSPACE" /grant "Everyone:(OI)(CI)F" + sudo --integrity Medium pnpm test:api-e2e + + - name: run e2e tests (macOS) + if: runner.os == 'macOS' && env.CN_API_KEY != '' + timeout-minutes: 45 + # macOS has no native WebDriver for WKWebView, so the app is driven through the + # CrabNebula Webdriver (tauri-plugin-automation + test-runner-backend), which + # authenticates with CN_API_KEY. wdio.conf enables it automatically on darwin and + # builds the `.app` bundle it needs. The tray module is skipped to match the other jobs. + run: E2E_SKIP=tray E2E_SPEC_RETRIES=1 pnpm test:api-e2e + env: + CN_API_KEY: ${{ secrets.TAURI_E2E_CN_API_KEY }} + + - name: collect app crash reports (macOS) + if: runner.os == 'macOS' && failure() + run: .scripts/ci/collect-macos-crash-reports.sh "$RUNNER_TEMP/crash-reports" + + - name: upload app crash reports (macOS) + if: runner.os == 'macOS' && failure() + uses: actions/upload-artifact@v7 + with: + name: macos-crash-reports + path: ${{ runner.temp }}/crash-reports + if-no-files-found: ignore diff --git a/.scripts/ci/collect-macos-crash-reports.sh b/.scripts/ci/collect-macos-crash-reports.sh new file mode 100755 index 000000000..f404af65b --- /dev/null +++ b/.scripts/ci/collect-macos-crash-reports.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# Copyright 2019-2024 Tauri Programme within The Commons Conservancy +# SPDX-License-Identifier: Apache-2.0 +# SPDX-License-Identifier: MIT + +# Collects and prints macOS crash reports after a failed `@tauri-apps/api` e2e run. +# +# The CrabNebula Webdriver proxies every command to a server running *inside* the app +# process, so when the app dies the suite only ever reports `connection refused` — the +# actual cause is never in the job log. The app's stdout/stderr is inherited and no panic +# message is printed, which means it goes down on a signal. macOS records the reason in a +# crash report, and that is the only place it survives the run. +# +# Copies every report into $1 (default: $RUNNER_TEMP/crash-reports) for upload. + +set -euo pipefail + +dest="${1:-${RUNNER_TEMP:-/tmp}/crash-reports}" +mkdir -p "$dest" + +# ReportCrash writes asynchronously; give the last crash a moment to land. +sleep 5 + +found=0 +for f in "$HOME/Library/Logs/DiagnosticReports"/*.ips \ + "$HOME/Library/Logs/DiagnosticReports/Retired"/*.ips; do + [ -e "$f" ] || continue + found=$((found + 1)) + cp "$f" "$dest/" + echo "::group::$(basename "$f")" + # An .ips file is a one-line JSON header followed by the JSON report body. + head -n 1 "$f" + tail -n +2 "$f" | jq -r ' + "exception: \(.exception // {} | tojson)", + "termination: \(.termination // {} | tojson)", + "asi: \(.asi // {} | tojson)", + "faulting thread \(.faultingThread // 0):", + (. as $r + | $r.threads[$r.faultingThread // 0].frames[]? + | " \($r.usedImages[.imageIndex].name // "?") \(.symbol // "?") +\(.imageOffset)"), + "last ObjC exception:", + (. as $r + | $r.lastExceptionBacktrace[]? + | " \($r.usedImages[.imageIndex].name // "?") \(.symbol // "?") +\(.imageOffset)") + ' || cat "$f" + echo "::endgroup::" +done + +[ "$found" -gt 0 ] || echo "no crash reports under $HOME/Library/Logs/DiagnosticReports" diff --git a/Cargo.lock b/Cargo.lock index 97ed31bd0..23dc05358 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -240,6 +240,7 @@ dependencies = [ "serde_json", "tauri", "tauri-build", + "tauri-plugin-automation", "tauri-plugin-log", "tauri-plugin-sample", ] @@ -1202,9 +1203,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chacha20" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", "cpufeatures 0.3.0", @@ -4423,6 +4424,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link 0.2.1", +] + [[package]] name = "libloading" version = "0.9.0" @@ -5222,9 +5233,17 @@ checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ "bitflags 2.13.0", "block2 0.6.2", + "libc", "objc2 0.6.4", + "objc2-cloud-kit", + "objc2-core-data", "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image", + "objc2-core-text", + "objc2-core-video", "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", ] [[package]] @@ -5244,6 +5263,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" dependencies = [ + "bitflags 2.13.0", "objc2 0.6.4", "objc2-foundation 0.3.2", ] @@ -5304,6 +5324,19 @@ dependencies = [ "objc2-core-graphics", ] +[[package]] +name = "objc2-core-video" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +dependencies = [ + "bitflags 2.13.0", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-io-surface", +] + [[package]] name = "objc2-encode" version = "4.1.0" @@ -9177,6 +9210,21 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tauri-plugin-automation" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "314d4ba88ce4a5e17c5f1e2dad990edb5956643b6e04a6d127d39aa64d0f2a7d" +dependencies = [ + "libloading 0.8.9", + "objc2-app-kit", + "serde_json", + "tauri", + "tauri-plugin", + "tokio", + "tracing", +] + [[package]] name = "tauri-plugin-log" version = "2.9.0" diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 7298d87c1..08342dacc 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -4052,6 +4052,17 @@ fn handle_user_message( } EventLoopWindowTargetMessage::SetTheme(theme) => { event_loop.set_theme(to_tao_theme(theme)); + // On macOS tao caches each window's theme and only refreshes it from the + // system-wide appearance change notification, which the app-level + // `NSApp.setAppearance` call above never posts, so `Window::theme()` + // would keep reporting the previous value. tao's window-level setter + // does update the cache, so push the theme through it as well. + #[cfg(target_os = "macos")] + for window in windows.0.borrow().values() { + if let Some(inner) = &window.inner { + inner.set_theme(to_tao_theme(theme)); + } + } } EventLoopWindowTargetMessage::SetDeviceEventFilter(filter) => { event_loop.set_device_event_filter(DeviceEventFilterWrapper::from(filter).0); diff --git a/examples/api/src-tauri/Cargo.toml b/examples/api/src-tauri/Cargo.toml index ad81f624c..82c9772ad 100644 --- a/examples/api/src-tauri/Cargo.toml +++ b/examples/api/src-tauri/Cargo.toml @@ -23,6 +23,12 @@ log = "0.4.21" tauri-plugin-sample = { path = "./tauri-plugin-sample/" } tauri-plugin-log = "2" +# WebDriver automation bridge, used by the `@tauri-apps/api` e2e suite (packages/api-e2e). +# Desktop-only and behind the off-by-default `automation` feature so it never ships in a +# regular build. +[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies] +tauri-plugin-automation = { version = "0.1.4", optional = true } + [dependencies.tauri] workspace = true default-features = true @@ -41,3 +47,5 @@ features = ["test"] [features] prod = ["tauri/custom-protocol"] +# Enables the WebDriver automation bridge; set by the e2e suite's build (packages/api-e2e). +automation = ["dep:tauri-plugin-automation"] diff --git a/examples/api/src-tauri/capabilities/run-app.json b/examples/api/src-tauri/capabilities/run-app.json index 99a2c118c..27478d464 100644 --- a/examples/api/src-tauri/capabilities/run-app.json +++ b/examples/api/src-tauri/capabilities/run-app.json @@ -66,6 +66,7 @@ "core:window:allow-set-icon", "core:window:allow-toggle-maximize", "core:webview:allow-create-webview-window", - "core:webview:allow-print" + "core:webview:allow-print", + "core:webview:allow-set-webview-zoom" ] } diff --git a/examples/api/src-tauri/src/lib.rs b/examples/api/src-tauri/src/lib.rs index 876978fda..bceca14ae 100644 --- a/examples/api/src-tauri/src/lib.rs +++ b/examples/api/src-tauri/src/lib.rs @@ -38,6 +38,13 @@ pub fn run_app) + Send + 'static>( builder: tauri::Builder, setup: F, ) { + // WebDriver automation bridge for the `@tauri-apps/api` e2e suite (packages/api-e2e). + // Registered as early as possible per the plugin's docs. Behind the off-by-default + // `automation` feature, and `not(test)` so it never interferes with the mock-runtime + // unit test below. + #[cfg(all(desktop, feature = "automation", not(test)))] + let builder = builder.plugin(tauri_plugin_automation::init()); + let builder = builder .plugin( tauri_plugin_log::Builder::default() @@ -105,10 +112,7 @@ pub fn run_app) + Send + 'static>( }); } - let webview = window_builder.build()?; - - #[cfg(debug_assertions)] - webview.open_devtools(); + let _webview = window_builder.build()?; let value = Some("test".to_string()); let response = app.sample().ping(PingRequest { diff --git a/examples/api/src/App.svelte b/examples/api/src/App.svelte index db719567d..4c67c9ea8 100644 --- a/examples/api/src/App.svelte +++ b/examples/api/src/App.svelte @@ -85,7 +85,7 @@ (localStorage.getItem('theme') as Theme | null) || 'auto' ) - async function switchTheme() { + function switchTheme() { switch (theme) { case 'dark': theme = 'light' @@ -97,24 +97,21 @@ theme = 'dark' break } - applyTheme() } - function applyTheme() { + // Follows the selection, or the system when it is `auto`. + $effect(() => { const isDark = theme === 'auto' ? preferDark.current : theme === 'dark' - if (isDark) { - document.documentElement.classList.add('dark') - document.documentElement.classList.remove('light') - } else { - document.documentElement.classList.remove('dark') - document.documentElement.classList.add('light') - } + document.documentElement.classList.toggle('dark', isDark) + document.documentElement.classList.toggle('light', !isDark) + }) + + // Only the selection drives the app-wide theme. Reading `preferDark` here would + // make a system (or externally applied) theme change run this again and reset the + // app back to `auto`, undoing whatever just set it. + $effect(() => { setTheme(theme === 'auto' ? null : theme) localStorage.setItem('theme', theme) - } - - $effect(() => { - applyTheme() }) // Console diff --git a/package.json b/package.json index 5bf88cece..aaf6d92ee 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "build:cli": "pnpm run --filter \"@tauri-apps/cli\" build", "build:cli:debug": "pnpm run --filter \"@tauri-apps/cli\" build:debug", "test": "pnpm run -r test", + "test:api-e2e": "pnpm run --filter \"@tauri-apps/api-e2e\" e2e", "example:api:dev": "pnpm run --filter \"api\" tauri dev" }, "devDependencies": { diff --git a/packages/api-e2e/README.md b/packages/api-e2e/README.md new file mode 100644 index 000000000..42e86d9f7 --- /dev/null +++ b/packages/api-e2e/README.md @@ -0,0 +1,130 @@ +# `@tauri-apps/api` end-to-end tests + +WebdriverIO suite that exercises every [`@tauri-apps/api`](../api) module against a +**real** Tauri app — the [`examples/api`](../../examples/api) validation app — rather than +a mocked backend. Each module has its own spec file, and adding coverage for a new API is +normally just dropping in one more spec. + +## How it works + +- The example app is built with `withGlobalTauri: true`, so the entire API surface is + reachable on `window.__TAURI__` inside the webview. +- WebdriverIO drives the app through [`@crabnebula/tauri-driver`](https://www.npmjs.com/package/@crabnebula/tauri-driver), + which bridges the WebDriver protocol to each platform's webview: + - **macOS** — the CrabNebula Webdriver, which needs [`tauri-plugin-automation`](https://crates.io/crates/tauri-plugin-automation) + (registered in `examples/api` behind its off-by-default `automation` Cargo feature, which + the suite's build enables) and a locally-running `@crabnebula/test-runner-backend`, + authenticated with `CN_API_KEY`. + - **Linux** — `webkit2gtk-driver` (`WebKitWebDriver` on `PATH`). + - **Windows** — `msedgedriver.exe` on `PATH`. It hands the app the `--remote-debugging-port` + it attaches to through `WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS`, which WebView2 ignores in an + elevated process ([wry#1782](https://github.com/tauri-apps/wry/issues/1782)), so the suite has + to run unelevated. +- Specs never `eval` in the page. They pass a function to the [`tauri()`](test/helpers/index.ts) + helper, which serializes it and runs it via the driver's own (CSP-exempt) script injection, + handing it `window.__TAURI__` as the first argument and returning its JSON result. +- A fresh `tauri-driver` (and therefore a fresh app instance) is started per spec file, so + each module's suite runs in isolation. + +## Prerequisites + +```sh +# from the repo root +pnpm install +pnpm build:api # examples/api resolves @tauri-apps/api from packages/api/dist +pnpm build:cli # examples/api's `tauri` script uses the local native CLI +``` + +Platform driver dependencies: + +| Platform | Requirement | +| -------- | ------------------------------------------------------------------------------------------------------------ | +| macOS | `CN_API_KEY` env var (CrabNebula Cloud). The automation plugin and test-runner-backend are wired up already. | +| Linux | `webkit2gtk-driver` package (provides `WebKitWebDriver`). | +| Windows | `msedgedriver.exe` matching your Edge version, on `PATH`. Run the suite unelevated. | + +## Running + +```sh +# from the repo root +pnpm test:api-e2e + +# or from this package +pnpm e2e + +# iterate without rebuilding the app every run +E2E_SKIP_BUILD=1 pnpm e2e + +# run a single module's spec +pnpm exec wdio run ./wdio.conf.ts --spec test/specs/window.spec.ts +``` + +The first run builds the app with [`tauri.e2e.conf.json`](tauri.e2e.conf.json) as a config +override, which enables the example's `automation` feature; afterwards use `E2E_SKIP_BUILD=1` +to reuse the existing binary. A binary supplied through `E2E_SKIP_BUILD` or `E2E_APP_PATH` +must have been built with that feature whenever the CrabNebula Webdriver is in use (always +on macOS). + +## Environment variables + +| Variable | Purpose | +| ------------------- | --------------------------------------------------------------------------------- | +| `CN_API_KEY` | CrabNebula Cloud key. Required on macOS (and whenever `E2E_CN_WEBDRIVER=1`). | +| `E2E_SKIP_BUILD` | Skip the `tauri build` step and reuse the existing binary. | +| `E2E_APP_PATH` | Absolute path to a prebuilt app/binary to test (also implies skip-build). | +| `E2E_SKIP` | Comma-separated module names to skip, e.g. `E2E_SKIP=tray,menu`. | +| `E2E_SKIP_WM` | Skip window-manager-dependent tests (minimize/maximize/fullscreen/position/hide). | +| `E2E_SPEC_RETRIES` | Retry count for flaky spec files (default `0`). | +| `E2E_CN_WEBDRIVER` | Use the CrabNebula Webdriver on Linux/Windows too (instead of the native driver). | +| `E2E_NATIVE_DRIVER` | Path passed to `tauri-driver --native-driver` (e.g. a specific chromedriver). | +| `CARGO_TARGET_DIR` | Override the target dir the app binary is looked up in. | + +## Adding tests for a new API + +1. **Add a spec.** Create `test/specs/.spec.ts` and use `describeApi('', …)` + with the `tauri()` helper. It is picked up automatically by the `test/specs/**/*.spec.ts` + glob. Minimal example: + + ```ts + import { expect } from '@wdio/globals' + import { tauri, describeApi } from '../helpers/index.js' + + describeApi('app', () => { + it('reports the product name', async () => { + expect(await tauri((api) => api.app.getName())).toBe('Tauri API') + }) + }) + ``` + +2. **Grant permissions if needed.** If the API calls a command that is not allowed by + default, add the permission to + [`examples/api/src-tauri/capabilities/run-app.json`](../../examples/api/src-tauri/capabilities/run-app.json). + The default permission sets are documented under + `crates/tauri/permissions/*/autogenerated/reference.md`. + +3. **Add a Rust command if needed.** If the API needs a custom backend command, add it to + [`examples/api/src-tauri/src/cmd.rs`](../../examples/api/src-tauri/src/cmd.rs), register it + in the `generate_handler!` list in + [`src/lib.rs`](../../examples/api/src-tauri/src/lib.rs), add its permission, and grant it + in `run-app.json`. + +4. **Handle environment-sensitive cases.** Use `itWm` (instead of `it`) for assertions that + depend on a real window manager, and `eventually()` to poll for state a WM applies + asynchronously. Branch on `process.platform` (Node side) for platform-specific behavior. + +### Rules for `tauri()` page functions + +The function you pass to `tauri()` runs **inside the webview**, serialized as a string: + +- It **cannot** close over anything from the spec module — pass every value it needs through + the trailing `tauri(fn, ...args)` arguments. +- It may only reference `api` (the `window.__TAURI__` object), those args, and browser + globals (`window`, `document`, `setTimeout`, `Promise`, …). +- Its return value must be JSON-serializable — return plain objects/primitives, not class + instances (call methods and return their results instead). +- Restore any app state you mutate (title, size, theme, …); tests within a spec file share + the same app instance. +- For in-page waiting, wrap logic in a `Promise` with an explicit `setTimeout` rejection so a + failure surfaces as a message rather than an opaque driver timeout. + +Use `tauriError(fn, ...args)` to assert that a call rejects; it returns the rejection message. diff --git a/packages/api-e2e/package.json b/packages/api-e2e/package.json new file mode 100644 index 000000000..eac11caaa --- /dev/null +++ b/packages/api-e2e/package.json @@ -0,0 +1,26 @@ +{ + "name": "@tauri-apps/api-e2e", + "private": true, + "version": "0.0.0", + "description": "End-to-end test suite for @tauri-apps/api, driven against the examples/api app via WebdriverIO.", + "license": "Apache-2.0 OR MIT", + "type": "module", + "scripts": { + "e2e": "wdio run ./wdio.conf.ts", + "ts:check": "tsc --noEmit" + }, + "devDependencies": { + "@crabnebula/tauri-driver": "^2.0.9", + "@crabnebula/test-runner-backend": "^0.2.9", + "@tauri-apps/api": "../api/dist", + "@types/node": "^22.10.0", + "@wdio/cli": "^9.31.9", + "@wdio/globals": "^9.31.3", + "@wdio/local-runner": "^9.31.9", + "@wdio/mocha-framework": "^9.31.9", + "@wdio/spec-reporter": "^9.31.2", + "expect-webdriverio": "^5.0.0", + "typescript": "^6.0.3", + "webdriverio": "^9.31.9" + } +} diff --git a/packages/api-e2e/tauri.e2e.conf.json b/packages/api-e2e/tauri.e2e.conf.json new file mode 100644 index 000000000..4786b44bb --- /dev/null +++ b/packages/api-e2e/tauri.e2e.conf.json @@ -0,0 +1,16 @@ +{ + "$schema": "../../crates/tauri-schema-generator/schemas/config.schema.json", + "build": { + "removeUnusedCommands": false, + "features": ["automation"] + }, + "bundle": { + "icon": [ + "../../.icons/32x32.png", + "../../.icons/128x128.png", + "../../.icons/128x128@2x.png", + "../../.icons/icon.icns", + "../../.icons/icon.ico" + ] + } +} diff --git a/packages/api-e2e/test/helpers/index.ts b/packages/api-e2e/test/helpers/index.ts new file mode 100644 index 000000000..a90da165a --- /dev/null +++ b/packages/api-e2e/test/helpers/index.ts @@ -0,0 +1,163 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { browser } from '@wdio/globals' +import type * as TauriApi from '@tauri-apps/api' + +/** The full `@tauri-apps/api` surface, as exposed on `window.__TAURI__`. */ +export type Api = typeof TauriApi + +type PageOutcome = + | { ok: true; value: T } + | { ok: false; error: string; stack?: string } + +/** Thrown when the function passed to {@link tauri} rejects inside the webview. */ +export class TauriPageError extends Error { + pageStack?: string + constructor(message: string, pageStack?: string) { + super(message) + this.name = 'TauriPageError' + this.pageStack = pageStack + } +} + +/** + * Runs `fn` inside the app's webview with `window.__TAURI__` as its first argument + * and resolves with its (JSON-serializable) return value. + * + * `fn` is serialized with `Function.prototype.toString`, so it **cannot close over + * anything in the spec module** — every value it needs must be passed through `args`, + * and it may only reference `api`, those args, and browser globals (`window`, + * `document`, `setTimeout`, `Promise`, ...). + * + * @example + * const name = await tauri((api) => api.app.getName()) + * const sum = await tauri((api, a, b) => a + b, 2, 3) + */ +export async function tauri( + fn: (api: Api, ...args: A) => R, + ...args: A +): Promise> { + // A string body (rather than passing `fn` directly) keeps this working across + // both the classic and bidi WebDriver protocols and avoids any in-page eval of + // our own — the driver injects this script itself, which is exempt from the + // app's CSP. `executeAsync` is used because promise support in `execute` is not + // uniform across the platform drivers tauri-driver proxies to. + const script = ` + var done = arguments[arguments.length - 1]; + var args = Array.prototype.slice.call(arguments, 0, arguments.length - 1); + var fn = (${fn.toString()}); + Promise.resolve() + .then(function () { return fn.apply(null, [window.__TAURI__].concat(args)); }) + .then( + function (value) { done({ ok: true, value: value === undefined ? null : value }); }, + function (error) { + done({ + ok: false, + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined + }); + } + ); + ` + const outcome = (await browser.executeAsync(script, ...args)) as PageOutcome< + Awaited + > | null + if (!outcome || typeof outcome !== 'object' || !('ok' in outcome)) { + throw new Error( + `tauri() bridge returned an unexpected value: ${JSON.stringify(outcome)}` + ) + } + if (!outcome.ok) { + throw new TauriPageError(outcome.error, outcome.stack) + } + return outcome.value +} + +/** + * Asserts that the page-side call rejects and returns the rejection message, + * so specs can assert on it. Throws if the call unexpectedly resolves. + */ +export async function tauriError( + fn: (api: Api, ...args: A) => unknown, + ...args: A +): Promise { + try { + await tauri(fn, ...args) + } catch (error) { + if (error instanceof TauriPageError) { + return error.message + } + // Some platform drivers (notably the Linux WebKitWebDriver) surface a + // page-side `invoke` rejection as a WebDriver-level error on the + // `execute/async` command instead of letting the in-page bridge report it + // as an `{ ok: false }` outcome. Fall back to that error's message so the + // backend rejection is still assertable. This is safe for error-path specs: + // they match the message against an expected pattern, so a genuine driver + // failure (whose message won't match) still fails the test. + if (error instanceof Error) { + return error.message + } + throw error + } + throw new Error('expected the API call to reject, but it resolved') +} + +/** + * Polls `check` until it returns without throwing or `timeout` elapses. + * Use for state that a window manager applies asynchronously (focus, minimize, ...). + */ +export async function eventually( + check: () => T | Promise, + { + timeout = 10_000, + interval = 250 + }: { timeout?: number; interval?: number } = {} +): Promise { + const deadline = Date.now() + timeout + let lastError: unknown + for (;;) { + try { + return await check() + } catch (error) { + lastError = error + } + if (Date.now() > deadline) { + throw lastError instanceof Error + ? lastError + : new Error(String(lastError)) + } + await new Promise((resolve) => setTimeout(resolve, interval)) + } +} + +const skippedModules = (process.env.E2E_SKIP ?? '') + .split(',') + .map((entry) => entry.trim()) + .filter(Boolean) + +/** + * `describe` wrapper keyed by API module name. Any module listed in the + * comma-separated `E2E_SKIP` env var (e.g. `E2E_SKIP=tray,menu`) is skipped. + */ +export function describeApi(module: string, fn: () => void): void { + const title = `@tauri-apps/api/${module}` + if (skippedModules.includes(module)) { + describe.skip(title, fn) + } else { + describe(title, fn) + } +} + +/** + * `it` for assertions that depend on a real window manager (minimize, maximize, + * focus, ...). Skipped entirely when `E2E_SKIP_WM` is set (e.g. bare headless CI). + */ +export function itWm(title: string, fn: () => void | Promise): void { + if (process.env.E2E_SKIP_WM) { + it.skip(title, fn) + } else { + it(title, fn) + } +} diff --git a/packages/api-e2e/test/specs/app.spec.ts b/packages/api-e2e/test/specs/app.spec.ts new file mode 100644 index 000000000..2c113962d --- /dev/null +++ b/packages/api-e2e/test/specs/app.spec.ts @@ -0,0 +1,57 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { expect } from '@wdio/globals' +import { tauri, eventually, describeApi } from '../helpers/index.js' + +describeApi('app', () => { + it('getName returns the configured product name', async () => { + expect(await tauri((api) => api.app.getName())).toBe('Tauri API') + }) + + it('getVersion returns the configured version', async () => { + expect(await tauri((api) => api.app.getVersion())).toBe('1.0.0') + }) + + it('getTauriVersion returns a semver string', async () => { + expect(await tauri((api) => api.app.getTauriVersion())).toMatch( + /^\d+\.\d+\.\d+/ + ) + }) + + it('getIdentifier returns the bundle identifier', async () => { + expect(await tauri((api) => api.app.getIdentifier())).toBe('com.tauri.api') + }) + + it('defaultWindowIcon returns an image with a positive size', async () => { + const size = await tauri(async (api) => { + const icon = await api.app.defaultWindowIcon() + return icon ? await icon.size() : null + }) + expect(size).not.toBeNull() + expect(size!.width).toBeGreaterThan(0) + expect(size!.height).toBeGreaterThan(0) + }) + + it('setTheme applies a theme and can be reset to the system default', async () => { + await tauri((api) => api.app.setTheme('dark')) + // On Linux the app-level theme is not observable through `window.theme()`: + // tao's event-loop `set_theme` only flips the GTK `prefer-dark` setting and + // never updates the window's stored theme, so `theme()` keeps reporting the + // portal/system value (and blocks on a 5s dbus timeout when no portal runs, + // as in headless CI). Elsewhere the change is reflected on the window. + if (process.platform !== 'linux') { + await eventually(async () => { + const theme = await tauri((api) => + api.window.getCurrentWindow().theme() + ) + if (theme !== 'dark') { + throw new Error(`expected theme "dark", got "${theme}"`) + } + }) + } + // restore + await tauri((api) => api.app.setTheme(null)) + }) +}) diff --git a/packages/api-e2e/test/specs/core.spec.ts b/packages/api-e2e/test/specs/core.spec.ts new file mode 100644 index 000000000..449557077 --- /dev/null +++ b/packages/api-e2e/test/specs/core.spec.ts @@ -0,0 +1,92 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { expect } from '@wdio/globals' +import { tauri, tauriError, describeApi } from '../helpers/index.js' + +describeApi('core', () => { + it('isTauri reports true inside the app', async () => { + expect(await tauri((api) => api.core.isTauri())).toBe(true) + }) + + it('invoke round-trips a raw request through the echo command', async () => { + const echoed = await tauri((api) => + api.core.invoke('echo', { some: 'payload', n: 42 }) + ) + expect(echoed).toEqual({ some: 'payload', n: 42 }) + }) + + it('invoke rejects for a command that is not registered', async () => { + // `removeUnusedCommands` strips ungranted commands from the app entirely. + const message = await tauriError((api) => + api.core.invoke('this_command_does_not_exist') + ) + expect(message).toMatch(/not found|not allowed|denied/i) + }) + + it('command scopes gate log_operation by event', async () => { + // The run-app capability scopes `log_operation` to the `tauri-click` event. + await tauri((api) => + api.core.invoke('log_operation', { + event: 'tauri-click', + payload: 'from e2e' + }) + ) + const message = await tauriError((api) => + api.core.invoke('log_operation', { event: 'out-of-scope-event' }) + ) + expect(message).toMatch(/not allowed|denied/i) + }) + + it('Channel receives every message streamed from the backend in order', async () => { + // `spam` sends 1..=1000 over the channel. + const result = await tauri( + (api, count) => + new Promise<{ length: number; ordered: boolean; last: number }>( + (resolve, reject) => { + const received: number[] = [] + const channel = new api.core.Channel() + channel.onmessage = (value: number) => { + received.push(value) + if (received.length === count) { + let ordered = true + for (let i = 0; i < received.length; i++) { + if (received[i] !== i + 1) { + ordered = false + break + } + } + resolve({ + length: received.length, + ordered, + last: received[received.length - 1] + }) + } + } + api.core.invoke('spam', { channel }).catch(reject) + setTimeout( + () => + reject( + new Error( + `only received ${received.length} of ${count} messages` + ) + ), + 15000 + ) + } + ), + 1000 + ) + expect(result.length).toBe(1000) + expect(result.ordered).toBe(true) + expect(result.last).toBe(1000) + }) + + it('convertFileSrc builds a platform-appropriate asset URL', async () => { + const url = await tauri((api) => + api.core.convertFileSrc('/path/to/file.png') + ) + expect(url).toMatch(/(asset:\/\/localhost\/|https?:\/\/asset\.localhost\/)/) + }) +}) diff --git a/packages/api-e2e/test/specs/dpi.spec.ts b/packages/api-e2e/test/specs/dpi.spec.ts new file mode 100644 index 000000000..05ce49da9 --- /dev/null +++ b/packages/api-e2e/test/specs/dpi.spec.ts @@ -0,0 +1,65 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { expect } from '@wdio/globals' +import { tauri, describeApi } from '../helpers/index.js' + +describeApi('dpi', () => { + it('LogicalSize.toPhysical scales up by the factor', async () => { + const physical = await tauri((api) => { + const size = new api.dpi.LogicalSize(100, 50).toPhysical(2) + return { width: size.width, height: size.height } + }) + expect(physical).toEqual({ width: 200, height: 100 }) + }) + + it('PhysicalSize.toLogical scales down by the factor', async () => { + const logical = await tauri((api) => { + const size = new api.dpi.PhysicalSize(200, 100).toLogical(2) + return { width: size.width, height: size.height } + }) + expect(logical).toEqual({ width: 100, height: 50 }) + }) + + it('LogicalPosition.toPhysical and PhysicalPosition.toLogical round-trip', async () => { + const result = await tauri((api) => { + const physical = new api.dpi.LogicalPosition(10, 20).toPhysical(2) + const logical = new api.dpi.PhysicalPosition(10, 20).toLogical(2) + return { + physical: { x: physical.x, y: physical.y }, + logical: { x: logical.x, y: logical.y } + } + }) + expect(result.physical).toEqual({ x: 20, y: 40 }) + expect(result.logical).toEqual({ x: 5, y: 10 }) + }) + + it('Size and Position wrappers delegate conversions', async () => { + const result = await tauri((api) => { + const size = new api.dpi.Size( + new api.dpi.LogicalSize(100, 50) + ).toPhysical(2) + const position = new api.dpi.Position( + new api.dpi.PhysicalPosition(20, 40) + ).toLogical(2) + return { + size: { width: size.width, height: size.height }, + position: { x: position.x, y: position.y } + } + }) + expect(result.size).toEqual({ width: 200, height: 100 }) + expect(result.position).toEqual({ x: 10, y: 20 }) + }) + + it('window sizes convert consistently against the real scale factor', async () => { + const consistent = await tauri(async (api) => { + const w = api.window.getCurrentWindow() + const scale = await w.scaleFactor() + const inner = await w.innerSize() + const logical = inner.toLogical(scale) + return Math.abs(logical.width * scale - inner.width) < 1 + }) + expect(consistent).toBe(true) + }) +}) diff --git a/packages/api-e2e/test/specs/event.spec.ts b/packages/api-e2e/test/specs/event.spec.ts new file mode 100644 index 000000000..16dd8c9c5 --- /dev/null +++ b/packages/api-e2e/test/specs/event.spec.ts @@ -0,0 +1,125 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { expect } from '@wdio/globals' +import { tauri, describeApi } from '../helpers/index.js' + +describeApi('event', () => { + it('listen receives an emitted payload', async () => { + const payload = await tauri( + (api) => + new Promise<{ hello: string }>((resolve, reject) => { + api.event + .listen<{ hello: string }>('e2e://ping', (event) => + resolve(event.payload) + ) + .then((unlisten) => { + api.event.emit('e2e://ping', { hello: 'world' }).catch(reject) + setTimeout(() => { + unlisten() + reject(new Error('event was not received')) + }, 5000) + }) + .catch(reject) + }) + ) + expect(payload).toEqual({ hello: 'world' }) + }) + + it('once fires exactly once even if the event is emitted twice', async () => { + const count = await tauri( + (api) => + new Promise((resolve, reject) => { + let calls = 0 + api.event + .once('e2e://once', () => { + calls++ + }) + .then(async () => { + await api.event.emit('e2e://once') + await api.event.emit('e2e://once') + setTimeout(() => resolve(calls), 1000) + }) + .catch(reject) + }) + ) + expect(count).toBe(1) + }) + + it('unlisten stops further delivery', async () => { + const count = await tauri( + (api) => + new Promise((resolve, reject) => { + let calls = 0 + api.event + .listen('e2e://off', () => { + calls++ + }) + .then(async (unlisten) => { + await api.event.emit('e2e://off') + setTimeout(async () => { + await unlisten() + await api.event.emit('e2e://off') + setTimeout(() => resolve(calls), 500) + }, 500) + }) + .catch(reject) + }) + ) + expect(count).toBe(1) + }) + + it('emitTo delivers only to the targeted label', async () => { + const result = await tauri( + (api) => + new Promise<{ mainCount: number }>((resolve, reject) => { + let mainCount = 0 + api.event + // The listener must be scoped to the `main` label: a default + // `listen()` registers the `Any` target, a catch-all that receives + // every emit regardless of the `emitTo` label (so it would also see + // the `does-not-exist` emit). + .listen( + 'e2e://target', + () => { + mainCount++ + }, + { target: 'main' } + ) + .then(async (unlisten) => { + await api.event.emitTo('main', 'e2e://target') // delivered + await api.event.emitTo('does-not-exist', 'e2e://target') // dropped + setTimeout(async () => { + await unlisten() + resolve({ mainCount }) + }, 800) + }) + .catch(reject) + }) + ) + expect(result.mainCount).toBe(1) + }) + + it('bridges events to and from the Rust backend', async () => { + // examples/api listens for `js-event` and replies with `rust-event { data }`. + const reply = await tauri( + (api) => + new Promise<{ data: string }>((resolve, reject) => { + api.event + .listen<{ data: string }>('rust-event', (event) => + resolve(event.payload) + ) + .then((unlisten) => { + api.event.emit('js-event', 'hello from e2e').catch(reject) + setTimeout(() => { + unlisten() + reject(new Error('no rust-event reply received')) + }, 5000) + }) + .catch(reject) + }) + ) + expect(reply).toEqual({ data: 'something else' }) + }) +}) diff --git a/packages/api-e2e/test/specs/image.spec.ts b/packages/api-e2e/test/specs/image.spec.ts new file mode 100644 index 000000000..a7c394e68 --- /dev/null +++ b/packages/api-e2e/test/specs/image.spec.ts @@ -0,0 +1,41 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { expect } from '@wdio/globals' +import { tauri, describeApi } from '../helpers/index.js' + +describeApi('image', () => { + it('Image.new round-trips raw rgba pixels', async () => { + // 2x1 image: red pixel, green pixel. + const rgba = [255, 0, 0, 255, 0, 255, 0, 255] + const result = await tauri( + async (api, pixels, width, height) => { + const image = await api.image.Image.new(pixels, width, height) + const size = await image.size() + const bytes = await image.rgba() + return { + width: size.width, + height: size.height, + byteLength: bytes.length + } + }, + rgba, + 2, + 1 + ) + expect(result.width).toBe(2) + expect(result.height).toBe(1) + expect(result.byteLength).toBe(rgba.length) + }) + + it('the default window icon is a usable image', async () => { + const size = await tauri(async (api) => { + const icon = await api.app.defaultWindowIcon() + return icon ? await icon.size() : null + }) + expect(size).not.toBeNull() + expect(size!.width).toBeGreaterThan(0) + expect(size!.height).toBeGreaterThan(0) + }) +}) diff --git a/packages/api-e2e/test/specs/menu.spec.ts b/packages/api-e2e/test/specs/menu.spec.ts new file mode 100644 index 000000000..13894f7ea --- /dev/null +++ b/packages/api-e2e/test/specs/menu.spec.ts @@ -0,0 +1,95 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { expect } from '@wdio/globals' +import { tauri, describeApi } from '../helpers/index.js' + +// The menu commands are all allowed by default. These tests only build and +// inspect menu resources; they deliberately do not attach the menu to the app +// or window, to avoid disturbing the live example app. +describeApi('menu', () => { + it('Menu.new builds a menu with the given items', async () => { + const result = await tauri(async (api) => { + const item = await api.menu.MenuItem.new({ text: 'Item A' }) + const check = await api.menu.CheckMenuItem.new({ + text: 'Item B', + checked: true + }) + const separator = await api.menu.PredefinedMenuItem.new({ + item: 'Separator' + }) + const submenu = await api.menu.Submenu.new({ + text: 'More', + items: [await api.menu.MenuItem.new({ text: 'Nested' })] + }) + const menu = await api.menu.Menu.new({ + items: [item, check, separator, submenu] + }) + const items = await menu.items() + return { count: items.length } + }) + expect(result.count).toBe(4) + }) + + it('MenuItem text and enabled state can be read and updated', async () => { + const result = await tauri(async (api) => { + const item = await api.menu.MenuItem.new({ + text: 'Original', + enabled: true + }) + const before = await item.text() + await item.setText('Updated') + const after = await item.text() + const enabledBefore = await item.isEnabled() + await item.setEnabled(false) + const enabledAfter = await item.isEnabled() + return { before, after, enabledBefore, enabledAfter } + }) + expect(result.before).toBe('Original') + expect(result.after).toBe('Updated') + expect(result.enabledBefore).toBe(true) + expect(result.enabledAfter).toBe(false) + }) + + it('CheckMenuItem tracks its checked state', async () => { + const result = await tauri(async (api) => { + const item = await api.menu.CheckMenuItem.new({ + text: 'Toggle', + checked: false + }) + // On Windows the checked state lives in the native menu the item belongs + // to, so it must be attached to a menu to be readable. + await api.menu.Menu.new({ items: [item] }) + const before = await item.isChecked() + await item.setChecked(true) + const after = await item.isChecked() + return { before, after } + }) + expect(result.before).toBe(false) + expect(result.after).toBe(true) + }) + + it('append and removeAt mutate the item list', async () => { + const result = await tauri(async (api) => { + const menu = await api.menu.Menu.new({ + items: [await api.menu.MenuItem.new({ text: 'First' })] + }) + await menu.append(await api.menu.MenuItem.new({ text: 'Second' })) + const afterAppend = (await menu.items()).length + await menu.removeAt(0) + const afterRemove = (await menu.items()).length + return { afterAppend, afterRemove } + }) + expect(result.afterAppend).toBe(2) + expect(result.afterRemove).toBe(1) + }) + + it('Menu.default builds the platform default menu', async () => { + const count = await tauri(async (api) => { + const menu = await api.menu.Menu.default() + return (await menu.items()).length + }) + expect(count).toBeGreaterThanOrEqual(0) + }) +}) diff --git a/packages/api-e2e/test/specs/path.spec.ts b/packages/api-e2e/test/specs/path.spec.ts new file mode 100644 index 000000000..1ef24ecc0 --- /dev/null +++ b/packages/api-e2e/test/specs/path.spec.ts @@ -0,0 +1,57 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import path from 'node:path' +import { expect } from '@wdio/globals' +import { tauri, describeApi } from '../helpers/index.js' + +describeApi('path', () => { + it('sep and delimiter match the host platform', async () => { + const separators = await tauri((api) => ({ + sep: api.path.sep(), + delimiter: api.path.delimiter() + })) + expect(separators.sep).toBe(path.sep) + expect(separators.delimiter).toBe(path.delimiter) + }) + + it('join, dirname, basename and extname behave like the platform', async () => { + const result = await tauri(async (api) => ({ + joined: await api.path.join('a', 'b', 'c.txt'), + dir: await api.path.dirname(await api.path.join('a', 'b', 'c.txt')), + base: await api.path.basename(await api.path.join('a', 'b', 'c.txt')), + ext: await api.path.extname(await api.path.join('a', 'b', 'c.txt')) + })) + expect(result.joined).toBe(path.join('a', 'b', 'c.txt')) + expect(result.base).toBe('c.txt') + expect(result.ext).toBe('txt') + expect(result.dir.endsWith(path.join('a', 'b'))).toBe(true) + }) + + it('normalize and isAbsolute work', async () => { + const result = await tauri(async (api) => ({ + normalized: await api.path.normalize('a/b/../c'), + absoluteIsAbsolute: await api.path.isAbsolute( + await api.path.resolve('x') + ), + relativeIsAbsolute: await api.path.isAbsolute('a/b') + })) + expect(result.normalized).toContain('c') + expect(result.absoluteIsAbsolute).toBe(true) + expect(result.relativeIsAbsolute).toBe(false) + }) + + it('app directories are absolute and scoped to the identifier', async () => { + const dirs = await tauri(async (api) => ({ + appData: await api.path.appDataDir(), + appConfig: await api.path.appConfigDir(), + home: await api.path.homeDir(), + temp: await api.path.tempDir() + })) + expect(dirs.appData).toContain('com.tauri.api') + expect(dirs.appConfig.length).toBeGreaterThan(0) + expect(dirs.home.length).toBeGreaterThan(0) + expect(dirs.temp.length).toBeGreaterThan(0) + }) +}) diff --git a/packages/api-e2e/test/specs/tray.spec.ts b/packages/api-e2e/test/specs/tray.spec.ts new file mode 100644 index 000000000..93229df84 --- /dev/null +++ b/packages/api-e2e/test/specs/tray.spec.ts @@ -0,0 +1,42 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { expect } from '@wdio/globals' +import { tauri, describeApi } from '../helpers/index.js' + +// Tray commands are allowed by default, but a tray host is not always available +// in headless environments — set `E2E_SKIP=tray` there. +describeApi('tray', () => { + it('creates a tray icon, looks it up and removes it', async () => { + const created = await tauri(async (api) => { + const icon = await api.app.defaultWindowIcon() + const tray = await api.tray.TrayIcon.new({ + id: 'e2e-tray', + icon: icon ?? undefined, + tooltip: 'e2e tray' + }) + return tray.id + }) + expect(created).toBe('e2e-tray') + + const foundById = await tauri(async (api) => { + const tray = await api.tray.TrayIcon.getById('e2e-tray') + return tray !== null + }) + expect(foundById).toBe(true) + + await tauri(async (api) => { + const tray = await api.tray.TrayIcon.getById('e2e-tray') + await tray?.setVisible(true) + return null + }) + + const removed = await tauri(async (api) => { + await api.tray.TrayIcon.removeById('e2e-tray') + const tray = await api.tray.TrayIcon.getById('e2e-tray') + return tray === null + }) + expect(removed).toBe(true) + }) +}) diff --git a/packages/api-e2e/test/specs/webview.spec.ts b/packages/api-e2e/test/specs/webview.spec.ts new file mode 100644 index 000000000..27f36d7e1 --- /dev/null +++ b/packages/api-e2e/test/specs/webview.spec.ts @@ -0,0 +1,42 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { expect } from '@wdio/globals' +import { tauri, describeApi } from '../helpers/index.js' + +describeApi('webview', () => { + it('getCurrentWebview reports the main label', async () => { + expect(await tauri((api) => api.webview.getCurrentWebview().label)).toBe( + 'main' + ) + }) + + it('getAllWebviews includes the main webview', async () => { + const labels = await tauri(async (api) => + (await api.webview.getAllWebviews()).map((w) => w.label) + ) + expect(labels).toContain('main') + }) + + it('exposes a physical position and size', async () => { + const rect = await tauri(async (api) => { + const wv = api.webview.getCurrentWebview() + const pos = await wv.position() + const size = await wv.size() + return { x: pos.x, y: pos.y, width: size.width, height: size.height } + }) + expect(rect.width).toBeGreaterThan(0) + expect(rect.height).toBeGreaterThan(0) + }) + + it('setZoom adjusts and restores the zoom level', async () => { + // Requires `core:webview:allow-set-webview-zoom` in the run-app capability. + await tauri(async (api) => { + const wv = api.webview.getCurrentWebview() + await wv.setZoom(1.5) + await wv.setZoom(1) + return null + }) + }) +}) diff --git a/packages/api-e2e/test/specs/webviewWindow.spec.ts b/packages/api-e2e/test/specs/webviewWindow.spec.ts new file mode 100644 index 000000000..d2c31504a --- /dev/null +++ b/packages/api-e2e/test/specs/webviewWindow.spec.ts @@ -0,0 +1,61 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { expect } from '@wdio/globals' +import { tauri, eventually, describeApi } from '../helpers/index.js' + +describeApi('webviewWindow', () => { + it('getCurrentWebviewWindow reports the main label', async () => { + expect( + await tauri((api) => api.webviewWindow.getCurrentWebviewWindow().label) + ).toBe('main') + }) + + it('creates, finds and closes a new webview window', async () => { + // The label must match `main-*` to inherit the run-app capability. + const created = await tauri( + (api) => + new Promise((resolve, reject) => { + const w = new api.webviewWindow.WebviewWindow('main-e2e', { + width: 400, + height: 300 + }) + w.once('tauri://created', () => resolve(true)).catch(reject) + w.once('tauri://error', (event) => + reject( + new Error(`window creation failed: ${String(event.payload)}`) + ) + ).catch(reject) + setTimeout(() => reject(new Error('window creation timed out')), 8000) + }) + ) + expect(created).toBe(true) + + const found = await tauri(async (api) => { + const byLabel = + await api.webviewWindow.WebviewWindow.getByLabel('main-e2e') + const all = (await api.webviewWindow.getAllWebviewWindows()).map( + (w) => w.label + ) + return { exists: byLabel !== null, all } + }) + expect(found.exists).toBe(true) + expect(found.all).toContain('main-e2e') + + await tauri(async (api) => { + const w = await api.webviewWindow.WebviewWindow.getByLabel('main-e2e') + await w?.close() + return null + }) + + await eventually(async () => { + const labels = await tauri(async (api) => + (await api.webviewWindow.getAllWebviewWindows()).map((w) => w.label) + ) + if (labels.includes('main-e2e')) { + throw new Error('window is still present after close') + } + }) + }) +}) diff --git a/packages/api-e2e/test/specs/window.spec.ts b/packages/api-e2e/test/specs/window.spec.ts new file mode 100644 index 000000000..70acedb8b --- /dev/null +++ b/packages/api-e2e/test/specs/window.spec.ts @@ -0,0 +1,254 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import { expect } from '@wdio/globals' +import { tauri, eventually, describeApi, itWm } from '../helpers/index.js' + +describeApi('window', () => { + it('getCurrentWindow reports the main label', async () => { + expect(await tauri((api) => api.window.getCurrentWindow().label)).toBe( + 'main' + ) + }) + + it('getAllWindows includes the main window', async () => { + const labels = await tauri(async (api) => + (await api.window.getAllWindows()).map((w) => w.label) + ) + expect(labels).toContain('main') + }) + + it('title can be read and set', async () => { + const original = await tauri((api) => api.window.getCurrentWindow().title()) + await tauri((api) => api.window.getCurrentWindow().setTitle('e2e title')) + expect(await tauri((api) => api.window.getCurrentWindow().title())).toBe( + 'e2e title' + ) + // restore + await tauri( + (api, title) => api.window.getCurrentWindow().setTitle(title), + original + ) + }) + + it('reports a positive scale factor and sizes', async () => { + const metrics = await tauri(async (api) => { + const w = api.window.getCurrentWindow() + const scale = await w.scaleFactor() + const inner = await w.innerSize() + const outer = await w.outerSize() + return { + scale, + inner: { width: inner.width, height: inner.height }, + outer: { width: outer.width, height: outer.height } + } + }) + expect(metrics.scale).toBeGreaterThan(0) + expect(metrics.inner.width).toBeGreaterThan(0) + expect(metrics.inner.height).toBeGreaterThan(0) + expect(metrics.outer.width).toBeGreaterThanOrEqual(metrics.inner.width) + }) + + it('reports a theme', async () => { + const theme = await tauri((api) => api.window.getCurrentWindow().theme()) + expect(['light', 'dark']).toContain(theme) + }) + + it('monitor queries resolve to sane shapes', async () => { + const monitors = await tauri(async (api) => { + const current = await api.window.currentMonitor() + const primary = await api.window.primaryMonitor() + const available = await api.window.availableMonitors() + return { + currentHasSize: current + ? current.size.width > 0 && current.size.height > 0 + : null, + primaryHasSize: primary + ? primary.size.width > 0 && primary.size.height > 0 + : null, + availableCount: available.length + } + }) + // In a headed environment there is at least one monitor; in bare headless + // there may be none, so only assert shape when present. + if (monitors.currentHasSize !== null) { + expect(monitors.currentHasSize).toBe(true) + } + expect(monitors.availableCount).toBeGreaterThanOrEqual(0) + }) + + it('setSize resizes the window', async () => { + const scale = await tauri((api) => + api.window.getCurrentWindow().scaleFactor() + ) + const original = await tauri(async (api) => { + const size = await api.window.getCurrentWindow().innerSize() + return { width: size.width, height: size.height } + }) + + await tauri( + (api, width, height) => + api.window + .getCurrentWindow() + .setSize(new api.dpi.LogicalSize(width, height)), + 600, + 400 + ) + + await eventually(async () => { + const inner = await tauri(async (api) => { + const size = await api.window.getCurrentWindow().innerSize() + return { width: size.width, height: size.height } + }) + const tolerance = Math.ceil(scale) * 4 + if (Math.abs(inner.width - 600 * scale) > tolerance) { + throw new Error(`width ${inner.width} not near ${600 * scale}`) + } + if (Math.abs(inner.height - 400 * scale) > tolerance) { + throw new Error(`height ${inner.height} not near ${400 * scale}`) + } + }) + + // restore the original physical size + await tauri( + (api, width, height) => + api.window + .getCurrentWindow() + .setSize(new api.dpi.PhysicalSize(width, height)), + original.width, + original.height + ) + }) + + it('setResizable toggles resizability', async () => { + await tauri((api) => api.window.getCurrentWindow().setResizable(false)) + expect( + await tauri((api) => api.window.getCurrentWindow().isResizable()) + ).toBe(false) + await tauri((api) => api.window.getCurrentWindow().setResizable(true)) + expect( + await tauri((api) => api.window.getCurrentWindow().isResizable()) + ).toBe(true) + }) + + it('assorted setters resolve without throwing', async () => { + await tauri(async (api) => { + const w = api.window.getCurrentWindow() + await w.setAlwaysOnTop(true) + await w.setAlwaysOnTop(false) + await w.setShadow(true) + await w.setContentProtected(false) + await w.setCursorVisible(true) + await w.requestUserAttention(null) + return null + }) + }) + + itWm('setPosition moves the window', async () => { + const original = await tauri(async (api) => { + const pos = await api.window.getCurrentWindow().outerPosition() + return { x: pos.x, y: pos.y } + }) + + await tauri( + (api, x, y) => + api.window + .getCurrentWindow() + .setPosition(new api.dpi.PhysicalPosition(x, y)), + original.x + 40, + original.y + 40 + ) + + await eventually(async () => { + const pos = await tauri(async (api) => { + const p = await api.window.getCurrentWindow().outerPosition() + return { x: p.x, y: p.y } + }) + // Window managers can nudge the final position; allow a generous tolerance. + if ( + Math.abs(pos.x - (original.x + 40)) > 30 + || Math.abs(pos.y - (original.y + 40)) > 30 + ) { + throw new Error( + `position ${pos.x},${pos.y} not near ${original.x + 40},${original.y + 40}` + ) + } + }) + + await tauri( + (api, x, y) => + api.window + .getCurrentWindow() + .setPosition(new api.dpi.PhysicalPosition(x, y)), + original.x, + original.y + ) + }) + + itWm('minimize and unminimize toggle the minimized state', async () => { + await tauri((api) => api.window.getCurrentWindow().minimize()) + await eventually(async () => { + if ( + !(await tauri((api) => api.window.getCurrentWindow().isMinimized())) + ) { + throw new Error('window is not minimized') + } + }) + await tauri((api) => api.window.getCurrentWindow().unminimize()) + await eventually(async () => { + if (await tauri((api) => api.window.getCurrentWindow().isMinimized())) { + throw new Error('window is still minimized') + } + }) + }) + + itWm('maximize and unmaximize toggle the maximized state', async () => { + await tauri((api) => api.window.getCurrentWindow().maximize()) + await eventually(async () => { + if ( + !(await tauri((api) => api.window.getCurrentWindow().isMaximized())) + ) { + throw new Error('window is not maximized') + } + }) + await tauri((api) => api.window.getCurrentWindow().unmaximize()) + await eventually(async () => { + if (await tauri((api) => api.window.getCurrentWindow().isMaximized())) { + throw new Error('window is still maximized') + } + }) + }) + + itWm('setFullscreen toggles fullscreen', async () => { + await tauri((api) => api.window.getCurrentWindow().setFullscreen(true)) + await eventually(async () => { + if ( + !(await tauri((api) => api.window.getCurrentWindow().isFullscreen())) + ) { + throw new Error('window is not fullscreen') + } + }) + await tauri((api) => api.window.getCurrentWindow().setFullscreen(false)) + await eventually(async () => { + if (await tauri((api) => api.window.getCurrentWindow().isFullscreen())) { + throw new Error('window is still fullscreen') + } + }) + }) + + itWm('hide and show toggle visibility', async () => { + await tauri((api) => api.window.getCurrentWindow().hide()) + await eventually(async () => { + if (await tauri((api) => api.window.getCurrentWindow().isVisible())) { + throw new Error('window is still visible') + } + }) + await tauri((api) => api.window.getCurrentWindow().show()) + await eventually(async () => { + if (!(await tauri((api) => api.window.getCurrentWindow().isVisible()))) { + throw new Error('window is not visible') + } + }) + }) +}) diff --git a/packages/api-e2e/test/types/global.d.ts b/packages/api-e2e/test/types/global.d.ts new file mode 100644 index 000000000..94384750c --- /dev/null +++ b/packages/api-e2e/test/types/global.d.ts @@ -0,0 +1,17 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +// The examples/api app is built with `withGlobalTauri: true`, so the whole +// `@tauri-apps/api` surface is available on `window.__TAURI__` inside the webview. +// This mirrors that for the functions we serialize and run in the page. + +import type * as TauriApi from '@tauri-apps/api' + +declare global { + interface Window { + __TAURI__: typeof TauriApi + } +} + +export {} diff --git a/packages/api-e2e/tsconfig.json b/packages/api-e2e/tsconfig.json new file mode 100644 index 000000000..981457061 --- /dev/null +++ b/packages/api-e2e/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2023", + "module": "ESNext", + // The specs run through tsx (esbuild, pulled in by @wdio/cli), and + // @tauri-apps/api's published type definitions use extensionless relative + // imports, so bundler-style resolution is what matches the runtime and + // resolves the api types. + "moduleResolution": "Bundler", + "lib": ["ES2023", "DOM"], + "types": [ + "node", + "@wdio/globals/types", + "@wdio/mocha-framework", + "expect-webdriverio" + ], + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["wdio.conf.ts", "test/**/*.ts"] +} diff --git a/packages/api-e2e/wdio.conf.ts b/packages/api-e2e/wdio.conf.ts new file mode 100644 index 000000000..27c4254cc --- /dev/null +++ b/packages/api-e2e/wdio.conf.ts @@ -0,0 +1,296 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +import path from 'node:path' +import fs from 'node:fs' +import { spawn, spawnSync, type ChildProcess } from 'node:child_process' +import { fileURLToPath } from 'node:url' +import { waitTauriDriverReady } from '@crabnebula/tauri-driver' + +const dirname = path.dirname(fileURLToPath(import.meta.url)) +const repoRoot = path.resolve(dirname, '..', '..') +const appDir = path.join(repoRoot, 'examples', 'api') +const targetDir = process.env.CARGO_TARGET_DIR ?? path.join(repoRoot, 'target') + +// macOS has no native WebDriver for WKWebView, so the CrabNebula Webdriver +// (backed by tauri-plugin-automation + the test-runner-backend) is required there. +// It can be opted into on the other platforms via E2E_CN_WEBDRIVER for parity. +const useCrabNebulaWebdriver = + process.platform === 'darwin' || !!process.env.E2E_CN_WEBDRIVER + +// Path passed to the driver as `tauri:options.application`. +const application = + process.env.E2E_APP_PATH + ?? (process.platform === 'darwin' + ? path.join(targetDir, 'debug', 'bundle', 'macos', 'Tauri API.app') + : process.platform === 'win32' + ? path.join(targetDir, 'debug', 'api.exe') + : path.join(targetDir, 'debug', 'api')) + +let tauriDriver: ChildProcess | undefined +let killedTauriDriver = false +let testRunnerBackend: ChildProcess | undefined +let killedTestRunnerBackend = false + +export const config: WebdriverIO.Config = { + hostname: '127.0.0.1', + port: 4444, + specs: ['./test/specs/**/*.spec.ts'], + // The driver spawns a single app instance and speaks WebDriver to it, so the + // suite must run serially. + maxInstances: 1, + capabilities: [ + { + maxInstances: 1, + // `tauri:options` is understood by tauri-driver, not by the WebdriverIO types. + 'tauri:options': { application } + } as unknown as WebdriverIO.Capabilities + ], + reporters: ['spec'], + framework: 'mocha', + mochaOpts: { + ui: 'bdd', + timeout: 120000 + }, + connectionRetryCount: 0, + specFileRetries: Number(process.env.E2E_SPEC_RETRIES ?? 0), + + onPrepare: async () => { + // The example resolves `@tauri-apps/api` from `packages/api/dist`, and its + // frontend build (vite) needs it too. Fail early with a clear message. + if ( + !fs.existsSync(path.join(repoRoot, 'packages', 'api', 'dist', 'index.js')) + ) { + throw new Error( + 'packages/api/dist is missing — run `pnpm build:api` at the repo root before the e2e suite.' + ) + } + + if (!process.env.E2E_SKIP_BUILD && !process.env.E2E_APP_PATH) { + // `examples/api`'s `tauri` script is `node ../../packages/cli/tauri.js`, + // which requires the native CLI to be built (`pnpm build:cli`). + // + // The override config does two things for this (debug, test-only) build: + // - enables the example's off-by-default `automation` feature, which + // registers tauri-plugin-automation; + // - disables `removeUnusedCommands`, which the example otherwise sets. + // It strips command handlers that no static capability grants, and the + // plugin adds its `resolve` command through a *runtime* capability, so + // it would be stripped — breaking the CrabNebula Webdriver on macOS. + // Passed as an appDir-relative path to sidestep shell quoting. + const overrideConfig = path.relative( + appDir, + path.join(dirname, 'tauri.e2e.conf.json') + ) + const buildArgs = [ + 'tauri', + 'build', + '--debug', + '--config', + overrideConfig, + ...(process.platform === 'darwin' + ? ['--bundles', 'app'] // the .app bundle is needed for tauri:options + : ['--no-bundle']) + ] + const build = spawnSync('pnpm', buildArgs, { + cwd: appDir, + stdio: 'inherit', + shell: true + }) + if (build.status !== 0) { + throw new Error( + `\`pnpm ${buildArgs.join(' ')}\` failed with status ${build.status}` + ) + } + } + + if (!fs.existsSync(application)) { + throw new Error( + `app not found at ${application} — build it (unset E2E_SKIP_BUILD) or point E2E_APP_PATH at an existing build.` + ) + } + + if (useCrabNebulaWebdriver) { + if (!process.env.CN_API_KEY) { + throw new Error( + 'CN_API_KEY is required for the CrabNebula Webdriver (mandatory on macOS, or when E2E_CN_WEBDRIVER=1).' + ) + } + testRunnerBackend = spawn('pnpm', ['exec', 'test-runner-backend'], { + cwd: dirname, + stdio: 'inherit', + shell: true, + // Lead a new process group so the whole tree (sh -> pnpm -> + // test-runner-backend) can be torn down together. See killProcessTree. + detached: process.platform !== 'win32' + }) + testRunnerBackend.on('error', (error) => { + console.error('test-runner-backend error:', error) + process.exit(1) + }) + testRunnerBackend.on('exit', (code) => { + if (!killedTestRunnerBackend) { + console.error('test-runner-backend exited with code:', code) + process.exit(1) + } + }) + const { waitTestRunnerBackendReady } = + await import('@crabnebula/test-runner-backend') + await waitTestRunnerBackendReady() + process.env.REMOTE_WEBDRIVER_URL = 'http://127.0.0.1:3000' + } + }, + + // A fresh tauri-driver (and therefore a fresh app instance) per spec file, + // so each module's suite runs in isolation. + beforeSession: async () => { + const args = ['exec', 'tauri-driver'] + if (process.env.E2E_NATIVE_DRIVER) { + args.push('--native-driver', process.env.E2E_NATIVE_DRIVER) + } + // Reset before each (re)spawn so the `exit` handler below still treats an + // unexpected driver crash as fatal on retried spec files. + killedTauriDriver = false + tauriDriver = spawn('pnpm', args, { + cwd: dirname, + stdio: [null, process.stdout, process.stderr], + shell: true, + // Lead a new process group so the whole tree (sh -> pnpm -> tauri-driver + // -> native webdriver) can be torn down together. See killProcessTree. + detached: process.platform !== 'win32' + }) + tauriDriver.on('error', (error) => { + console.error('tauri-driver error:', error) + process.exit(1) + }) + tauriDriver.on('exit', (code) => { + if (!killedTauriDriver) { + console.error('tauri-driver exited with code:', code) + process.exit(1) + } + }) + await waitTauriDriverReady() + }, + + // The session is created as soon as the app's window exists, which can be + // before the webview has navigated to the app's page: WebView2 on a cold start + // (the first launches on a fresh Windows runner) still shows `about:blank` + // for a few seconds, so the first spec's scripts ran in a page without + // `window.__TAURI__`. Every spec goes through that global, so block until + // it exists. + before: async (_capabilities, _specs, browser) => { + await browser.waitUntil( + async () => { + try { + return (await browser.executeAsync( + 'var done = arguments[arguments.length - 1]; done(typeof window.__TAURI__ !== "undefined");' + )) as boolean + } catch { + // A command issued mid-navigation can fail on a stale execution + // context; that just means "not ready yet". + return false + } + }, + { + timeout: 30_000, + interval: 250, + timeoutMsg: + 'window.__TAURI__ never became available — the app did not load its page.' + } + ) + }, + + // Awaited so the driver (and its port) is fully gone before the next spec's + // beforeSession spawns a new one on the same port. + afterSession: async () => { + await closeTauriDriver() + }, + + onComplete: () => { + closeAll() + } +} + +/** + * Kills a shell-spawned child and everything it started. `child.kill()` only + * signals the `sh`/`cmd` wrapper, orphaning the real process (which keeps + * holding the WebDriver port and poisons every later spec), so we take down the + * whole process group/tree instead. + */ +function killProcessTree( + child: ChildProcess | undefined, + signal: NodeJS.Signals = 'SIGTERM' +): void { + const pid = child?.pid + if (!pid || child?.exitCode !== null) return + if (process.platform === 'win32') { + spawnSync('taskkill', ['/pid', String(pid), '/T', '/F'], { + stdio: 'ignore' + }) + } else { + try { + // Negative pid targets the whole process group (see `detached` above). + process.kill(-pid, signal) + } catch { + try { + child!.kill(signal) + } catch { + // already gone + } + } + } +} + +async function closeTauriDriver(): Promise { + killedTauriDriver = true + const driver = tauriDriver + tauriDriver = undefined + if (!driver || driver.exitCode !== null) return + const exited = new Promise((resolve) => + driver.once('exit', () => resolve()) + ) + killProcessTree(driver) + // Give it a moment to release the port, then escalate to SIGKILL. + let timer: ReturnType | undefined + await Promise.race([ + exited, + new Promise((resolve) => { + timer = setTimeout(() => { + killProcessTree(driver, 'SIGKILL') + resolve() + }, 5000) + }) + ]) + if (timer) clearTimeout(timer) +} + +function closeAll() { + killedTauriDriver = true + killProcessTree(tauriDriver) + tauriDriver = undefined + killedTestRunnerBackend = true + killProcessTree(testRunnerBackend) + testRunnerBackend = undefined +} + +function onShutdown(fn: () => void) { + const cleanup = () => { + try { + fn() + } finally { + process.exit() + } + } + for (const signal of [ + 'exit', + 'SIGINT', + 'SIGTERM', + 'SIGHUP', + 'SIGBREAK' + ] as const) { + process.on(signal, cleanup) + } +} + +onShutdown(closeAll) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f347649a8..45e9b2b38 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,7 +106,13 @@ settings: excludeLinksFromLockfile: false overrides: + brace-expansion@<1.1.16: ^1.1.16 + brace-expansion@>=2.0.0 <2.1.2: ^2.1.2 + brace-expansion@>=3.0.0 <5.0.7: ^5.0.7 + diff@>=6.0.0 <8.0.3: ^8.0.3 esbuild@>=0.27.3 <0.28.1: '>=0.28.1' + ip-address@<10.3.1: ^10.3.1 + serialize-javascript@<7.0.5: ^7.0.5 sharp@<0.35.4: ^0.35.4 undici@>=7.0.0 <7.29.0: ^7.29.0 ws@>=8.0.0 <8.20.1: '>=8.20.1' @@ -139,7 +145,7 @@ importers: version: 1.2.2 '@sveltejs/vite-plugin-svelte': specifier: ^7.2.0 - version: 7.2.0(svelte@5.56.4(@typescript-eslint/types@8.58.2))(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)) + version: 7.2.0(svelte@5.56.4(@typescript-eslint/types@8.58.2))(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0)) '@types/sortablejs': specifier: ^1.15.9 version: 1.15.9 @@ -154,10 +160,10 @@ importers: version: 5.56.4(@typescript-eslint/types@8.58.2) unocss: specifier: ^66.7.5 - version: 66.7.5(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)) + version: 66.7.5(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0)) vite: specifier: ^8.1.4 - version: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0) + version: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0) examples/file-associations: {} @@ -208,6 +214,45 @@ importers: specifier: ^8.58.2 version: 8.58.2(eslint@10.0.2(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + packages/api-e2e: + devDependencies: + '@crabnebula/tauri-driver': + specifier: ^2.0.9 + version: 2.0.9 + '@crabnebula/test-runner-backend': + specifier: ^0.2.9 + version: 0.2.9 + '@tauri-apps/api': + specifier: ../api/dist + version: link:../api/dist + '@types/node': + specifier: ^22.10.0 + version: 22.20.0 + '@wdio/cli': + specifier: ^9.31.9 + version: 9.31.9(@types/node@22.20.0)(expect-webdriverio@5.7.0)(supports-color@8.1.1) + '@wdio/globals': + specifier: ^9.31.3 + version: 9.31.3(expect-webdriverio@5.7.0)(webdriverio@9.31.9(supports-color@8.1.1)) + '@wdio/local-runner': + specifier: ^9.31.9 + version: 9.31.9(@wdio/globals@9.31.3)(supports-color@8.1.1)(webdriverio@9.31.9(supports-color@8.1.1)) + '@wdio/mocha-framework': + specifier: ^9.31.9 + version: 9.31.9(supports-color@8.1.1) + '@wdio/spec-reporter': + specifier: ^9.31.2 + version: 9.31.2 + expect-webdriverio: + specifier: ^5.0.0 + version: 5.7.0(@wdio/globals@9.31.3)(@wdio/logger@9.29.1)(webdriverio@9.31.9(supports-color@8.1.1)) + typescript: + specifier: ^6.0.3 + version: 6.0.3 + webdriverio: + specifier: ^9.31.9 + version: 9.31.9(supports-color@8.1.1) + packages/cli: devDependencies: '@napi-rs/cli': @@ -221,13 +266,21 @@ importers: version: 10.1.0 vitest: specifier: ^5.0.0 - version: 5.0.0(@types/node@24.11.0)(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)) + version: 5.0.0(@types/node@24.11.0)(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0)) packages: '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + '@cloudflare/kv-asset-handler@0.5.0': resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==} engines: {node: '>=22.0.0'} @@ -271,6 +324,66 @@ packages: cpu: [x64] os: [win32] + '@crabnebula/tauri-driver-darwin-arm64@2.0.9': + resolution: {integrity: sha512-VvO7OC6UkuEP3eU3klyl+Ka/jgWFc3yIUeCw6e8BtibQWDXSwQ/r2tzqvC0d+5psF/mWYiCqNAKMlg4v5+muvg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@crabnebula/tauri-driver-darwin-x64@2.0.9': + resolution: {integrity: sha512-AWm3CY+YjKRLxaaucYdBG9cA7sTPviBpuVjJW6rNsPHGIFlxiA3C7fOv0Eekf2L7ps6v9HRCgldjPjTLH0DvNQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@crabnebula/tauri-driver-linux-x64-gnu@2.0.9': + resolution: {integrity: sha512-+H2HQtjKQrVJ+A9C5x4LaTl/6oX1QpEBlfRJxA4WqCdbJEE2NsmLgODGSQNueav+9QV7MOgjppRMl9fiW7IIqg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@crabnebula/tauri-driver-win32-x64-msvc@2.0.9': + resolution: {integrity: sha512-/xqSl8dmGy7u9FXXjtuxAe38PJuQ4g1yT6Txgft5SwRwicAVkcEvmtdLkHJ6wUqEcg64UBEsoja8Z0EbNqTIcg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@crabnebula/tauri-driver@2.0.9': + resolution: {integrity: sha512-W+fOUkQnP0MOSu9jMykG7HSstYysTQLMnL2+b3IpenbyqPfBiBI/9uSoNC1nXjh0aYm46nPgwKC6RbiWsWa0XQ==} + engines: {node: '>= 10'} + hasBin: true + + '@crabnebula/test-runner-backend-darwin-arm64@0.2.9': + resolution: {integrity: sha512-UAlL8VA23y/fp+MigNYFwGvtE9vJ518f846c0k2vgT/bLIpt+d3UXndjZCMYbEVFTmaq00wHoRPSPbyzHEMWlQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@crabnebula/test-runner-backend-darwin-x64@0.2.9': + resolution: {integrity: sha512-RUP9L4Lk8KsT4A64U4QFVy5rj99Y6iIichPLpZgTvpRybYKZBVXjUiU31aGUIlWnd4VHsWKLM2vNl90rKZm3lA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@crabnebula/test-runner-backend-linux-x64-gnu@0.2.9': + resolution: {integrity: sha512-js/haLE9OUsa0oDHNuVps5DY7av3iWG7PpAKjr9nMnIEXiLACDmvyUL/IplHMmu1lr6S0fztoudRf4JfTR+mfA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@crabnebula/test-runner-backend-win32-x64-msvc@0.2.9': + resolution: {integrity: sha512-p4pc/GQ0bj3vVLuUyTHDnhaXO52EQNkaCUPhWXwEkG00loW93pvCBRrOWoYpJH9me/n2zMFv61meW9mQyvbByw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@crabnebula/test-runner-backend@0.2.9': + resolution: {integrity: sha512-3z6qZbJtVyA1JymQU5hFqcxG6nFD5INgqBc3OxTbYXVzMpihlRGOcHWyPK72ndHK88YmfwQWPcEFN1R/H/Lvhw==} + engines: {node: '>= 10'} + hasBin: true + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -694,10 +807,23 @@ packages: cpu: [x64] os: [win32] + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} + engines: {node: '>=18'} + '@inquirer/ansi@2.0.7': resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + '@inquirer/checkbox@4.3.2': + resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/checkbox@5.2.1': resolution: {integrity: sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -707,6 +833,15 @@ packages: '@types/node': optional: true + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/confirm@6.1.1': resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -716,6 +851,15 @@ packages: '@types/node': optional: true + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/core@11.2.1': resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -725,6 +869,15 @@ packages: '@types/node': optional: true + '@inquirer/editor@4.2.23': + resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/editor@5.2.2': resolution: {integrity: sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -734,6 +887,15 @@ packages: '@types/node': optional: true + '@inquirer/expand@4.0.23': + resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/expand@5.1.1': resolution: {integrity: sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -743,6 +905,15 @@ packages: '@types/node': optional: true + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/external-editor@3.0.3': resolution: {integrity: sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -752,10 +923,23 @@ packages: '@types/node': optional: true + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + engines: {node: '>=18'} + '@inquirer/figures@2.0.7': resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + '@inquirer/input@4.3.1': + resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/input@5.1.2': resolution: {integrity: sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -765,6 +949,15 @@ packages: '@types/node': optional: true + '@inquirer/number@3.0.23': + resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/number@4.1.1': resolution: {integrity: sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -774,6 +967,15 @@ packages: '@types/node': optional: true + '@inquirer/password@4.0.23': + resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/password@5.1.1': resolution: {integrity: sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -783,6 +985,15 @@ packages: '@types/node': optional: true + '@inquirer/prompts@7.10.1': + resolution: {integrity: sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/prompts@8.5.2': resolution: {integrity: sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -792,6 +1003,15 @@ packages: '@types/node': optional: true + '@inquirer/rawlist@4.1.11': + resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/rawlist@5.3.1': resolution: {integrity: sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -801,6 +1021,15 @@ packages: '@types/node': optional: true + '@inquirer/search@3.2.2': + resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/search@4.2.1': resolution: {integrity: sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -810,6 +1039,15 @@ packages: '@types/node': optional: true + '@inquirer/select@4.4.2': + resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/select@5.2.1': resolution: {integrity: sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -819,6 +1057,15 @@ packages: '@types/node': optional: true + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/type@4.0.7': resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -828,6 +1075,34 @@ packages: '@types/node': optional: true + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jest/diff-sequences@30.4.0': + resolution: {integrity: sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/expect-utils@30.4.1': + resolution: {integrity: sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/get-type@30.1.0': + resolution: {integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/pattern@30.4.0': + resolution: {integrity: sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/schemas@30.4.1': + resolution: {integrity: sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/types@30.4.1': + resolution: {integrity: sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1413,6 +1688,10 @@ packages: '@oxc-project/types@0.139.0': resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} @@ -1425,6 +1704,14 @@ packages: '@poppinss/exception@1.2.3': resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + '@promptbook/utils@0.69.5': + resolution: {integrity: sha512-xm5Ti/Hp3o4xHrsK9Yy3MS6KbDxYbq485hDsFvxqaNA7equHLPdo8H8faTitTeb14QCDfLW4iwCxdVYu5sn6YQ==} + + '@puppeteer/browsers@2.13.2': + resolution: {integrity: sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==} + engines: {node: '>=18'} + hasBin: true + '@quansync/fs@1.0.0': resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} @@ -1695,10 +1982,20 @@ packages: cpu: [x64] os: [win32] + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sinclair/typebox@0.34.49': + resolution: {integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==} + '@sindresorhus/is@7.2.0': resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} engines: {node: '>=18'} + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + '@speed-highlight/core@1.2.14': resolution: {integrity: sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA==} @@ -1714,6 +2011,9 @@ packages: svelte: ^5.46.4 vite: ^8.0.0-beta.7 || ^8.0.0 + '@tootallnate/quickjs-emscripten@0.23.0': + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + '@tybys/wasm-util@0.10.3': resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} @@ -1732,18 +2032,60 @@ packages: '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/mocha@10.0.10': + resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} + + '@types/node@20.19.43': + resolution: {integrity: sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==} + + '@types/node@22.20.0': + resolution: {integrity: sha512-QWlFW2wf3nTjC13/DqRnBpR4ZO36VJH/JVBkA/vcnmbTBNQIlnObqyqZE1tUR7+Ni23Lda8R1BxMfbXRpCUx5g==} + '@types/node@24.11.0': resolution: {integrity: sha512-fPxQqz4VTgPI/IQ+lj9r0h+fDR66bzoeMGHp8ASee+32OSGIkeASsoZuJixsQoVef1QJbeubcPBxKk22QVoWdw==} + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/sinonjs__fake-timers@8.1.5': + resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==} + '@types/sortablejs@1.15.9': resolution: {integrity: sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ==} + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/which@2.0.2': + resolution: {integrity: sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + '@typescript-eslint/eslint-plugin@8.58.2': resolution: {integrity: sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1883,9 +2225,98 @@ packages: vite: optional: true + '@vitest/pretty-format@3.2.7': + resolution: {integrity: sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==} + + '@vitest/pretty-format@4.1.11': + resolution: {integrity: sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==} + + '@vitest/snapshot@3.2.7': + resolution: {integrity: sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==} + + '@vitest/snapshot@4.1.11': + resolution: {integrity: sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==} + '@vitest/spy@5.0.0': resolution: {integrity: sha512-uy+luWBAPw9XfthoHi5AkfHUnuPYEESjl0p/r+meoBnU8bxg5GDQ3Ey8MjcJ6sqahkL4PFyrvfMJJBw7LbU06g==} + '@vitest/utils@4.1.11': + resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==} + + '@wdio/cli@9.31.9': + resolution: {integrity: sha512-4wFCNrXWTWrBBxY/dY2GANIb/omkV+31pXQdTtaWcSVg8pNyfBMG/S2roPjnbOjdxm12av/ZX8jQvaxnqpKR9g==} + engines: {node: '>=18.20.0'} + hasBin: true + + '@wdio/config@9.31.9': + resolution: {integrity: sha512-RrEiAJwWVuc8v1sgLFmqMhNoNqXc14UMEXNDEn+U2ihYY+n5M+86tuP9ns06N4SYhnVofjPjly7IZ2Qhadd2cQ==} + engines: {node: '>=18.20.0'} + + '@wdio/dot-reporter@9.31.2': + resolution: {integrity: sha512-SY7lYPJzCGdedPxHcGMEJlC2tjdxqqq+e8ROGaob3kmjbKH2Zn7bQIqgCk9fOsA814Zz+V628pEKJNKHL8xpyQ==} + engines: {node: '>=18.20.0'} + + '@wdio/globals@9.31.3': + resolution: {integrity: sha512-ZzmRKUlwUBahNoNxHbAzst+9dNInEjLQc7Z3c86OhDRxAf3Ivw8k2rc56UCbyYiZnkd1dOpuA91zFiTrUNNORw==} + engines: {node: '>=18.20.0'} + peerDependencies: + expect-webdriverio: ^6.0.9 + webdriverio: ^9.28.0 + + '@wdio/local-runner@9.31.9': + resolution: {integrity: sha512-9/+c/naNdBTBNZJyBb8lkmLmspKqH6oATV5ikG34nTUzItIX8wjLmhhn/uQMmOC6WvKHlRDBFGHHVgvD+fomAA==} + engines: {node: '>=18.20.0'} + + '@wdio/logger@9.29.1': + resolution: {integrity: sha512-0ZAEIo6PNyMIJPlOGkIgyOJUjcd0pC8/QHlVAAe1c91/IcjZ1X+k0yidXHaboJdN7dq1XPUacmhRdtua0U5EZg==} + engines: {node: '>=18.20.0'} + + '@wdio/mocha-framework@9.31.9': + resolution: {integrity: sha512-1kFnNNafUgNz8yg+C6EK3Ykt3K5X9+L52o3XTdYJCs2mGI/n0nCdzHr/Yh7AMGcAAvLtPtCgEnIT0nM7dmPbzg==} + engines: {node: '>=18.20.0'} + + '@wdio/protocols@9.31.5': + resolution: {integrity: sha512-e4H5exl5xCcITF0y/3zd6pf9kX4TmV8/0nnWDGt4X0KbgDi/+tGqlquZ+YS4YBEPbv95yTqVhnazEsaBiH85Tw==} + + '@wdio/repl@9.16.2': + resolution: {integrity: sha512-FLTF0VL6+o5BSTCO7yLSXocm3kUnu31zYwzdsz4n9s5YWt83sCtzGZlZpt7TaTzb3jVUfxuHNQDTb8UMkCu0lQ==} + engines: {node: '>=18.20.0'} + + '@wdio/reporter@9.31.2': + resolution: {integrity: sha512-3cKE6vCOsro/Ep9dGTIbo3FBn3WNvJ++BIn32lFd9m19pFdjuwlVgLtPXHb9jWNCJs740h5AIUcVkcscqUYhAA==} + engines: {node: '>=18.20.0'} + + '@wdio/runner@9.31.9': + resolution: {integrity: sha512-6QlU2t6wTxCm4MHSgifRzUKbBPkRdROx5WqIaYzUVrYaM7m8nZG1JQRvEauIZMWwDv4T4NQ2lKToNvQKH5bA6g==} + engines: {node: '>=18.20.0'} + peerDependencies: + expect-webdriverio: ^6.0.9 + webdriverio: ^9.28.0 + + '@wdio/spec-reporter@9.31.2': + resolution: {integrity: sha512-lNLLPUk4y1Yp5pWwBFF+tjZIy7bOv0TPTk4HDWV4LnnHnkc24abI0nN+kb2y5/JV8ZgwLCCVKUFRdRUxfKsAaQ==} + engines: {node: '>=18.20.0'} + + '@wdio/types@9.31.2': + resolution: {integrity: sha512-lQKaiQDCJJ6VC1K/cKzaAxCpwB9pL1U0VbmX2uGksMxO4EDbNuLvIxWryuUDJ7OaSYTjxILTKYFErdbT/xEikg==} + engines: {node: '>=18.20.0'} + + '@wdio/utils@9.31.9': + resolution: {integrity: sha512-k0Py9L7PxRq8d8/6+B5l4078c12/7lbDzqUVrrhH7VJDV0/EM0qVTtP1LVttLYZEPazdAn0kLSFBCLiiJmfM7Q==} + engines: {node: '>=18.20.0'} + + '@wdio/xvfb@9.31.2': + resolution: {integrity: sha512-48MqdcrvdC/Jn2YPhW6hjGLzcQqOEt1Q6KELR/TWz3vIJoZwzTngGAdT06voUnZS+PUEcd/vKSo4a6zxQ/mm7g==} + engines: {node: '>=18.20.0'} + + '@zip.js/zip.js@2.13.1': + resolution: {integrity: sha512-D+iRyi2/uBCXPDQBhz2Z+Emcj2Cd8K/FG0y0l8WFeZJAZiP46m7cCajsGW3ktSq1HWov3nogZxyQ3FBisxOQSQ==} + engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=18.0.0'} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1896,9 +2327,49 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + ajv@6.14.0: resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + 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'} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1910,20 +2381,103 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + + async-exit-hook@2.0.1: + resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==} + engines: {node: '>=0.12.0'} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} + b4a@1.8.1: + resolution: {integrity: sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==} + peerDependencies: + react-native-b4a: '*' + peerDependenciesMeta: + react-native-b4a: + optional: true + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} + bare-events@2.9.1: + resolution: {integrity: sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==} + peerDependencies: + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + + bare-fs@4.7.3: + resolution: {integrity: sha512-xRgplks8SvcKkdlv2M6Z2LZmRsmqd+x0nXXGXeMEjwdibj1HSDrlnqBRLeYdMvsgCox7Bq0e+DHwfczOfsn6IA==} + engines: {bare: '>=1.16.0'} + peerDependencies: + bare-buffer: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + + bare-os@3.9.3: + resolution: {integrity: sha512-fF4Q7QsyKVF5Rj0qvI8BgUNjqzC2JvQlpTaPLjVJVxYVUX5Zr9un+y3w1HmA4nNKdFmRBT8z/WmrjvXzXVerKQ==} + engines: {bare: '>=1.14.0'} + + bare-path@3.0.1: + resolution: {integrity: sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==} + + bare-stream@2.13.3: + resolution: {integrity: sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==} + peerDependencies: + bare-abort-controller: '*' + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true + bare-buffer: + optional: true + bare-events: + optional: true + + bare-url@2.4.5: + resolution: {integrity: sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + basic-ftp@5.3.1: + resolution: {integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==} + engines: {node: '>=10.0.0'} + before-after-hook@4.0.0: resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.18: + resolution: {integrity: sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==} + + brace-expansion@2.1.4: + resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==} + brace-expansion@5.0.9: resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} engines: {node: 20 || >=22} @@ -1932,24 +2486,68 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + 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-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + cac@7.0.0: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.2.0: + resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} + engines: {node: '>=20.18.1'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + chokidar@5.0.0: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} @@ -1959,16 +2557,49 @@ packages: peerDependencies: typanion: '*' + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -1976,10 +2607,30 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@1.1.1: resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + 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-wdio@9.31.6: + resolution: {integrity: sha512-1crqGGcJPRY4wA0Z9USae81MswbIYOVSfula/4lQYPbuimcwv3AZUsU1hJgZEfIRdRB9KepKqojOk+itWnlGlg==} + engines: {node: '>=18.20.0'} + hasBin: true + cross-env@10.1.0: resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} engines: {node: '>=20'} @@ -1989,10 +2640,27 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-shorthand-properties@1.1.2: + resolution: {integrity: sha512-C2AugXIpRGQTxaCW0N7n5jD/p5irUmCrwl03TrnMFBHDbdq44CFWR2zO7rK9xPN4Eo3pUxC4vQzQgbIpzrD1PQ==} + css-tree@3.2.1: resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-value@0.0.1: + resolution: {integrity: sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} + engines: {node: '>= 14'} + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -2002,16 +2670,39 @@ packages: supports-color: optional: true + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + decamelize@6.0.1: + resolution: {integrity: sha512-G7Cqgaelq68XHJNGlZ7lrNQyhZGsFqpwtGFexqUv4IQdjKoSYF7ipZ9UuTJZUSQXFj/XaoBLuEVIVqr8EJngEQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge-ts@8.0.2: + resolution: {integrity: sha512-uqbvqLUMrc6p0MO+WBRtTxY55hmyh94WRwI5a++PZe54X+bfVh59FSN7uWCBCW1CCVjzjnrwzfI8zidE2obMMw==} + engines: {node: '>=16.9.0'} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + defu@6.1.6: resolution: {integrity: sha512-f8mefEW4WIVg4LckePx3mALjQSPQgFlg9U8yaPdlsbdYcHQyj9n2zL2LJEA52smeYxOvmd/nB7TpMtHGMTHcug==} + degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} @@ -2022,9 +2713,81 @@ packages: devalue@5.8.1: resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} + diff@5.2.2: + resolution: {integrity: sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==} + engines: {node: '>=0.3.1'} + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} + engines: {node: '>=12'} + duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + easy-table@1.2.0: + resolution: {integrity: sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==} + + edge-paths@3.0.5: + resolution: {integrity: sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==} + engines: {node: '>=14.0.0'} + + edgedriver@6.3.1: + resolution: {integrity: sha512-wCL/Ydgt0DPkWecjhhPj2/lnDxsGeHLPKeJYKKMTNol+ULFVg4WaTvxoB19GU4tieM6LSA3vZEdZxmDC0DwIpQ==} + engines: {node: '>=20.0.0'} + hasBin: true + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + error-stack-parser-es@1.0.5: resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} @@ -2039,10 +2802,23 @@ packages: engines: {node: '>=18'} hasBin: true + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + eslint-config-prettier@10.1.8: resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} hasBin: true @@ -2082,6 +2858,11 @@ packages: resolution: {integrity: sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.7.0: resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} @@ -2112,16 +2893,66 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events-universal@1.0.1: + resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} + engines: {node: ^18.19.0 || >=20.5.0} + + exit-hook@4.0.0: + resolution: {integrity: sha512-Fqs7ChZm72y40wKjOFXBKg7nJZvQJmewP5/7LtePDdnah/+FH9Hp5sgMujSCMPXlxOAW2//1jrW9pnsY7o20vQ==} + engines: {node: '>=18'} + expect-type@1.4.0: resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} + expect-webdriverio@5.7.0: + resolution: {integrity: sha512-jLOTrJoPBC3Wtd83ryHMbRcEajMGtAnn6OWtSnoJoDLt16nHvxVdjcI4Bc0n+1KAOr8DvQtlJ55f0M48kJtEpw==} + engines: {node: '>=20'} + peerDependencies: + '@wdio/globals': ^9.0.0 + '@wdio/logger': ^9.0.0 + webdriverio: ^9.0.0 + + expect-webdriverio@6.0.10: + resolution: {integrity: sha512-VBaMl4U6orgn3uzM7n65Gd48legqi37GoP0mklR+3f7vs/cC1s4hQVmGoiqz9aBcISVF37dAynP3aoi0R0CDow==} + engines: {node: '>=20'} + peerDependencies: + '@wdio/globals': ^9.0.0 + '@wdio/logger': ^9.0.0 + webdriverio: ^9.28.0 + + expect@30.4.1: + resolution: {integrity: sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + fast-content-type-parse@3.0.0: resolution: {integrity: sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==} + fast-deep-equal@2.0.1: + resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} + 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.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -2144,6 +2975,9 @@ packages: fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -2153,10 +2987,17 @@ packages: picomatch: optional: true + 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'} + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -2165,13 +3006,28 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -2180,6 +3036,31 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + geckodriver@6.1.1: + resolution: {integrity: sha512-/AcCyc9o9o6hUbudaSJM2iOtXbxSLqQPOb4GrPvEN40cjraUeaX/j5kH3mSgwiroyMn7qzx2wM61AQ2XY8j3sA==} + engines: {node: '>=20.0.0'} + hasBin: true + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-port@7.2.0: + resolution: {integrity: sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==} + engines: {node: '>=16'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + get-uri@6.0.5: + resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} + engines: {node: '>= 14'} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2188,22 +3069,79 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + globals@17.4.0: resolution: {integrity: sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==} engines: {node: '>=18'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + gzip-size@6.0.0: resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} engines: {node: '>=10'} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + + hosted-git-info@8.1.0: + resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==} + engines: {node: ^18.17.0 || >=20.5.0} + + htmlfy@0.8.1: + resolution: {integrity: sha512-xWROBw9+MEGwxpotll0h672KCaLrKKiCYzsyN8ZgL9cQbVumFnyvsk2JqiB9ELAV1GLj1GG/jxZUjV9OZZi/yQ==} + + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + iconv-lite@0.7.2: resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} engines: {node: '>=0.10.0'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -2212,6 +3150,9 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + import-meta-resolve@4.2.0: resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} @@ -2219,6 +3160,33 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + inquirer@12.11.1: + resolution: {integrity: sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + ip-address@10.7.0: + resolution: {integrity: sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA==} + engines: {node: '>= 12'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + is-core-module@2.16.1: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} @@ -2227,6 +3195,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -2235,16 +3207,82 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + 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-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@4.0.0: + resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} + engines: {node: '>=20'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + engines: {node: '>=10'} + hasBin: true + + jest-diff@30.4.1: + resolution: {integrity: sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-matcher-utils@30.4.1: + resolution: {integrity: sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-message-util@30.4.1: + resolution: {integrity: sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-mock@30.4.1: + resolution: {integrity: sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-regex-util@30.4.0: + resolution: {integrity: sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-util@30.4.1: + resolution: {integrity: sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@4.3.2: resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} hasBin: true @@ -2252,6 +3290,10 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -2261,6 +3303,9 @@ packages: json-with-bigint@3.5.7: resolution: {integrity: sha512-7ei3MdAI5+fJPVnKlW77TKNKwQ5ppSzWvhPuSuINT/GYW9ZOC1eRKOuhV9yHG5aEsUPj9BBx5JIekkmoLHxZOw==} + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -2268,10 +3313,17 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -2346,6 +3398,13 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} + lines-and-columns@2.0.4: + resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + locate-app@2.5.0: + resolution: {integrity: sha512-xIqbzPMBYArJRmPGUZD9CzV9wOqmVtQnaAn3wrj3s6WYW0bQvPI7x+sPYUGmDTYMHefVK//zc6HEYZ1qnxIK+Q==} + locate-character@3.0.0: resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} @@ -2353,6 +3412,46 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.flattendeep@4.4.0: + resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} + + lodash.pickby@4.6.0: + resolution: {integrity: sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==} + + lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + + lodash.zip@4.2.0: + resolution: {integrity: sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + loglevel-plugin-prefix@0.8.4: + resolution: {integrity: sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==} + + loglevel@1.9.2: + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} + engines: {node: '>= 0.6.0'} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + magic-regexp@0.10.0: resolution: {integrity: sha512-Uly1Bu4lO1hwHUW0CQeSWuRtzCMNO00CmXtS8N6fyvB3B979GOEEeAkiTUDsmbYLAbvpUS/Kt5c4ibosAzVyVg==} @@ -2382,9 +3481,36 @@ packages: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} + mocha@10.8.2: + resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} + engines: {node: '>= 14.0.0'} + hasBin: true + + modern-tar@0.7.6: + resolution: {integrity: sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg==} + engines: {node: '>=18.0.0'} + mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -2392,6 +3518,10 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + mute-stream@3.0.0: resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} engines: {node: ^20.17.0 || >=22.9.0} @@ -2404,9 +3534,36 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + netmask@2.1.1: + resolution: {integrity: sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==} + engines: {node: '>= 0.4.0'} + node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + normalize-package-data@6.0.2: + resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} + engines: {node: ^16.14.0 || >=18.0.0} + + normalize-package-data@7.0.1: + resolution: {integrity: sha512-linxNAT6M0ebEYZOx2tO6vBEFsVgnPpv+AVjk0wJHfaUIbq31Jm3T6vvZaarnOeWDh8ShnwXuaAyM7WT3RzErA==} + engines: {node: ^18.17.0 || >=20.5.0} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + obug@2.1.4: resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} engines: {node: '>=12.20.0'} @@ -2414,6 +3571,9 @@ packages: ofetch@1.5.1: resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -2431,30 +3591,84 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + pac-proxy-agent@7.2.0: + resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} + engines: {node: '>= 14'} + + pac-resolver@7.0.1: + resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} + engines: {node: '>= 14'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + parse-json@7.1.1: + resolution: {integrity: sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==} + engines: {node: '>=16'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + 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==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + perfect-debounce@2.1.0: resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} @@ -2485,6 +3699,35 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@30.4.1: + resolution: {integrity: sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + pretty-ms@9.3.0: + resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} + engines: {node: '>=18'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + proxy-agent@6.5.0: + resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} + engines: {node: '>= 14'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2492,26 +3735,79 @@ packages: quansync@1.0.0: resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + query-selector-shadow-dom@1.0.1: + resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-is@19.2.7: + resolution: {integrity: sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==} + + read-pkg-up@10.1.0: + resolution: {integrity: sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==} + engines: {node: '>=16'} + + read-pkg@8.1.0: + resolution: {integrity: sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==} + engines: {node: '>=16'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + readdirp@5.0.0: resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} engines: {node: '>= 20.19.0'} + recursive-readdir@2.2.3: + resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==} + engines: {node: '>=6.0.0'} + regexp-tree@0.1.27: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + resolve@1.22.11: resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} hasBin: true + resq@1.11.0: + resolution: {integrity: sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==} + + ret@0.5.0: + resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} + engines: {node: '>=10'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rgb2hex@0.2.5: + resolution: {integrity: sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==} + rolldown@1.1.5: resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2522,9 +3818,30 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + run-async@4.0.6: + resolution: {integrity: sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==} + engines: {node: '>=0.12.0'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safaridriver@1.0.1: + resolution: {integrity: sha512-jkg4434cYgtrIF2AeY/X0Wmd2W73cK5qIEFE3hDrrQenJH/2SDJIXGvPAigfvQTcE9+H31zkiNHbUqcihEiMRA==} + engines: {node: '>=18.0.0'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex2@5.1.1: + resolution: {integrity: sha512-mOSBvHGDZMuIEZMdOz/aCEYDCv0E7nfcNsIhUF+/P+xC7Hyf3FkvymqgPbg9D1EdSGu+uKbJgy09K/RKKc7kJA==} + hasBin: true + safe-regex@2.1.1: resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} @@ -2536,10 +3853,17 @@ packages: engines: {node: '>=10'} hasBin: true + serialize-error@12.0.0: + resolution: {integrity: sha512-ZYkZLAvKTKQXWuh5XpBw7CdbSzagarX39WyZ2H07CDLC5/KfsRGlIXV8d4+tfqX1M7916mRqR1QfNHSij+c9Pw==} + engines: {node: '>=18'} + serialize-javascript@7.0.5: resolution: {integrity: sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==} engines: {node: '>=20.0.0'} + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + sharp@0.35.4: resolution: {integrity: sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==} engines: {node: '>=20.9.0'} @@ -2568,10 +3892,26 @@ packages: resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + smob@1.6.1: resolution: {integrity: sha512-KAkBqZl3c2GvNgNhcoyJae1aKldDW0LO279wF9bk1PnluRTETKBq0WyzRXxEhoQLk56yHaOY4JCBEKDuJIET5g==} engines: {node: '>=20.0.0'} + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + + socks@2.8.9: + resolution: {integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + sortablejs@1.15.7: resolution: {integrity: sha512-Kk8wLQPlS+yi1ZEf48a4+fzHa4yxjC30M/Sr2AnQu+f/MPwvvX9XjZ6OWejiz8crBsLwSq8GHqaxaET7u6ux0A==} @@ -2586,16 +3926,84 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + spacetrim@0.11.59: + resolution: {integrity: sha512-lLYsktklSRKprreOm7NXReW8YiX2VBjbgmXYEziOoGf/qsJqAEACaDvoTtUOycwjpaSh+bT8eu0KrJn7UNxiCg==} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} std-env@4.2.0: resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} + stream-buffers@3.0.3: + resolution: {integrity: sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==} + engines: {node: '>= 0.10.0'} + + streamx@2.28.0: + resolution: {integrity: sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + supports-color@10.2.2: resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} engines: {node: '>=18'} + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -2604,11 +4012,23 @@ packages: resolution: {integrity: sha512-/d0QHehmRuJW8gVz395MTkPcPozxzdjBMBE8oEYGz8O3b9KTMzzQ9ZHJQLuFKOHOPQbU6kx/X4iid/EBBzH7iw==} engines: {node: '>=18'} + tar-fs@3.1.3: + resolution: {integrity: sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ==} + + tar-stream@3.2.0: + resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} + + teex@1.0.1: + resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} + terser@5.46.0: resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} engines: {node: '>=10'} hasBin: true + text-decoder@1.2.7: + resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} + tinybench@6.1.4: resolution: {integrity: sha512-9APumHG7r4yOk4X4WlkmE71aZcv1gvin1czO3OQ1U9iJcFA5Ja/ygyb0vPOVHTthFozUYs8CLoLUlM8grb2lTQ==} engines: {node: '>=20.0.0'} @@ -2625,6 +4045,14 @@ packages: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + + tinyrainbow@3.1.1: + resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==} + engines: {node: '>=14.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -2642,6 +4070,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.23.0: + resolution: {integrity: sha512-eUdUIaCr963q2h5u3+QwvYp0+eqPvn+egeqZUm0hwERCqqx1E3kK5ehbGCvqSE5MQAULr67ww0cA3jKc3YkM1w==} + engines: {node: '>=18.0.0'} + hasBin: true + typanion@3.14.0: resolution: {integrity: sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==} @@ -2649,6 +4082,18 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + + type-fest@4.26.0: + resolution: {integrity: sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==} + engines: {node: '>=16'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + type-level-regexp@0.1.17: resolution: {integrity: sha512-wTk4DH3cxwk196uGLK/E9pE45aLfeKJacKmcEgEOA/q5dnPGNxXt0cfYdFxb57L+sEpf1oJH4Dnx/pnRcku9jg==} @@ -2673,9 +4118,16 @@ packages: unconfig@7.5.0: resolution: {integrity: sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici@6.28.1: + resolution: {integrity: sha512-zWpdTVD54H48CIybL0rWQ3ukpb9d23wM7eH5RtfdmeP70cWHNjtfo7P4vZX+5CoDcO53J4Pu5uXp7lNfjc6DRA==} + engines: {node: '>=18.17'} + undici@7.29.0: resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==} engines: {node: '>=20.18.1'} @@ -2683,6 +4135,10 @@ packages: unenv@2.0.0-rc.24: resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + universal-user-agent@7.0.3: resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} @@ -2711,6 +4167,19 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + urlpattern-polyfill@10.1.0: + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} + + userhome@1.0.1: + resolution: {integrity: sha512-5cnLm4gseXjAclKowC4IjByaGsjtAoV6PrOQOljplNB54ReUYJP8HdAFq2muHinSDAh09PPX/uXDPfdxRHvuSA==} + engines: {node: '>= 0.8.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vite@8.1.4: resolution: {integrity: sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2803,14 +4272,49 @@ packages: jsdom: optional: true + wait-port@1.1.0: + resolution: {integrity: sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==} + engines: {node: '>=10'} + hasBin: true + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + webdriver@9.31.9: + resolution: {integrity: sha512-mkRevz4ZIHCBe09FtHQnWg0G/p40bqk3Rv7aBooSthc8hpKG0880B9iga08drtPSiYN6/wC59WBh10ooLPboJA==} + engines: {node: '>=18.20.0'} + + webdriverio@9.31.9: + resolution: {integrity: sha512-C5Uxgry8Gcs4HJ2Ln/9m8QK55S4s5qNw6bjyFnWIFaZhPaoLrC0YN6wSzZ/LqfnysPdefRjgHxctFX/G6xIi0Q==} + engines: {node: '>=18.20.0'} + peerDependencies: + puppeteer-core: '>=22.x <=24.x' + peerDependenciesMeta: + puppeteer-core: + optional: true + webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + which@6.0.1: + resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} @@ -2825,6 +4329,9 @@ packages: engines: {node: '>=16'} hasBin: true + workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + wrangler@4.114.0: resolution: {integrity: sha512-M65P25t5UHA1TIJfgZXDcj+YzVobgKdRguM2QPz0xnxLFuOcuE3ErgllDht0iaho7MS4o0g/Bb4YK2+GT+bibg==} engines: {node: '>=22.0.0'} @@ -2835,6 +4342,21 @@ packages: '@cloudflare/workers-types': optional: true + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.21.0: resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} engines: {node: '>=10.0.0'} @@ -2847,10 +4369,49 @@ packages: utf-8-validate: optional: true + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@16.2.2: + resolution: {integrity: sha512-Nt9ZJjXTv5R8MHbqby/wXQ6Gi0Bb3TcYZkR1bzuL4yB2OxWPkXknz513gEF0GoA6tn00UpbPvERW8rzCuWCA6w==} + engines: {node: '>=10'} + + yargs@17.7.3: + resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} + engines: {node: '>=12'} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + youch-core@0.3.3: resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} @@ -2860,6 +4421,10 @@ packages: zimmerframe@1.1.4: resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + snapshots: '@antfu/install-pkg@1.1.0': @@ -2867,6 +4432,14 @@ snapshots: package-manager-detector: 1.6.0 tinyexec: 1.3.1 + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.29.7': {} + '@cloudflare/kv-asset-handler@0.5.0': {} '@cloudflare/unenv-preset@2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260722.1)': @@ -2890,6 +4463,44 @@ snapshots: '@cloudflare/workerd-windows-64@1.20260722.1': optional: true + '@crabnebula/tauri-driver-darwin-arm64@2.0.9': + optional: true + + '@crabnebula/tauri-driver-darwin-x64@2.0.9': + optional: true + + '@crabnebula/tauri-driver-linux-x64-gnu@2.0.9': + optional: true + + '@crabnebula/tauri-driver-win32-x64-msvc@2.0.9': + optional: true + + '@crabnebula/tauri-driver@2.0.9': + optionalDependencies: + '@crabnebula/tauri-driver-darwin-arm64': 2.0.9 + '@crabnebula/tauri-driver-darwin-x64': 2.0.9 + '@crabnebula/tauri-driver-linux-x64-gnu': 2.0.9 + '@crabnebula/tauri-driver-win32-x64-msvc': 2.0.9 + + '@crabnebula/test-runner-backend-darwin-arm64@0.2.9': + optional: true + + '@crabnebula/test-runner-backend-darwin-x64@0.2.9': + optional: true + + '@crabnebula/test-runner-backend-linux-x64-gnu@0.2.9': + optional: true + + '@crabnebula/test-runner-backend-win32-x64-msvc@0.2.9': + optional: true + + '@crabnebula/test-runner-backend@0.2.9': + optionalDependencies: + '@crabnebula/test-runner-backend-darwin-arm64': 0.2.9 + '@crabnebula/test-runner-backend-darwin-x64': 0.2.9 + '@crabnebula/test-runner-backend-linux-x64-gnu': 0.2.9 + '@crabnebula/test-runner-backend-win32-x64-msvc': 0.2.9 + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -3194,8 +4805,20 @@ snapshots: '@img/sharp-win32-x64@0.35.4': optional: true + '@inquirer/ansi@1.0.2': {} + '@inquirer/ansi@2.0.7': {} + '@inquirer/checkbox@4.3.2(@types/node@22.20.0)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@22.20.0) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/checkbox@5.2.1(@types/node@24.11.0)': dependencies: '@inquirer/ansi': 2.0.7 @@ -3205,6 +4828,13 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/confirm@5.1.21(@types/node@22.20.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/type': 3.0.10(@types/node@22.20.0) + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/confirm@6.1.1(@types/node@24.11.0)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.11.0) @@ -3212,6 +4842,19 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/core@10.3.2(@types/node@22.20.0)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@22.20.0) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/core@11.2.1(@types/node@24.11.0)': dependencies: '@inquirer/ansi': 2.0.7 @@ -3224,6 +4867,14 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/editor@4.2.23(@types/node@22.20.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/external-editor': 1.0.3(@types/node@22.20.0) + '@inquirer/type': 3.0.10(@types/node@22.20.0) + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/editor@5.2.2(@types/node@24.11.0)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.11.0) @@ -3232,6 +4883,14 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/expand@4.0.23(@types/node@22.20.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/type': 3.0.10(@types/node@22.20.0) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/expand@5.1.1(@types/node@24.11.0)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.11.0) @@ -3239,6 +4898,13 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/external-editor@1.0.3(@types/node@22.20.0)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/external-editor@3.0.3(@types/node@24.11.0)': dependencies: chardet: 2.1.1 @@ -3246,8 +4912,17 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/figures@1.0.15': {} + '@inquirer/figures@2.0.7': {} + '@inquirer/input@4.3.1(@types/node@22.20.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/type': 3.0.10(@types/node@22.20.0) + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/input@5.1.2(@types/node@24.11.0)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.11.0) @@ -3255,6 +4930,13 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/number@3.0.23(@types/node@22.20.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/type': 3.0.10(@types/node@22.20.0) + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/number@4.1.1(@types/node@24.11.0)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.11.0) @@ -3262,6 +4944,14 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/password@4.0.23(@types/node@22.20.0)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/type': 3.0.10(@types/node@22.20.0) + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/password@5.1.1(@types/node@24.11.0)': dependencies: '@inquirer/ansi': 2.0.7 @@ -3270,6 +4960,21 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/prompts@7.10.1(@types/node@22.20.0)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@22.20.0) + '@inquirer/confirm': 5.1.21(@types/node@22.20.0) + '@inquirer/editor': 4.2.23(@types/node@22.20.0) + '@inquirer/expand': 4.0.23(@types/node@22.20.0) + '@inquirer/input': 4.3.1(@types/node@22.20.0) + '@inquirer/number': 3.0.23(@types/node@22.20.0) + '@inquirer/password': 4.0.23(@types/node@22.20.0) + '@inquirer/rawlist': 4.1.11(@types/node@22.20.0) + '@inquirer/search': 3.2.2(@types/node@22.20.0) + '@inquirer/select': 4.4.2(@types/node@22.20.0) + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/prompts@8.5.2(@types/node@24.11.0)': dependencies: '@inquirer/checkbox': 5.2.1(@types/node@24.11.0) @@ -3285,6 +4990,14 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/rawlist@4.1.11(@types/node@22.20.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/type': 3.0.10(@types/node@22.20.0) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/rawlist@5.3.1(@types/node@24.11.0)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.11.0) @@ -3292,6 +5005,15 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/search@3.2.2(@types/node@22.20.0)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@22.20.0) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/search@4.2.1(@types/node@24.11.0)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.11.0) @@ -3300,6 +5022,16 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/select@4.4.2(@types/node@22.20.0)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@22.20.0) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/select@5.2.1(@types/node@24.11.0)': dependencies: '@inquirer/ansi': 2.0.7 @@ -3309,10 +5041,50 @@ snapshots: optionalDependencies: '@types/node': 24.11.0 + '@inquirer/type@3.0.10(@types/node@22.20.0)': + optionalDependencies: + '@types/node': 22.20.0 + '@inquirer/type@4.0.7(@types/node@24.11.0)': optionalDependencies: '@types/node': 24.11.0 + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jest/diff-sequences@30.4.0': {} + + '@jest/expect-utils@30.4.1': + dependencies: + '@jest/get-type': 30.1.0 + + '@jest/get-type@30.1.0': {} + + '@jest/pattern@30.4.0': + dependencies: + '@types/node': 24.11.0 + jest-regex-util: 30.4.0 + + '@jest/schemas@30.4.1': + dependencies: + '@sinclair/typebox': 0.34.49 + + '@jest/types@30.4.1': + dependencies: + '@jest/pattern': 30.4.0 + '@jest/schemas': 30.4.1 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 24.11.0 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -3770,6 +5542,9 @@ snapshots: '@oxc-project/types@0.139.0': {} + '@pkgjs/parseargs@0.11.0': + optional: true + '@polka/url@1.0.0-next.29': {} '@poppinss/colors@4.1.6': @@ -3784,6 +5559,25 @@ snapshots: '@poppinss/exception@1.2.3': {} + '@promptbook/utils@0.69.5': + dependencies: + spacetrim: 0.11.59 + + '@puppeteer/browsers@2.13.2(supports-color@8.1.1)': + dependencies: + debug: 4.4.3(supports-color@8.1.1) + extract-zip: 2.0.1(supports-color@8.1.1) + progress: 2.0.3 + proxy-agent: 6.5.0(supports-color@8.1.1) + semver: 7.8.5 + tar-fs: 3.1.3 + yargs: 17.7.3 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + - supports-color + '@quansync/fs@1.0.0': dependencies: quansync: 1.0.0 @@ -3939,22 +5733,30 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.62.4': optional: true + '@sec-ant/readable-stream@0.4.1': {} + + '@sinclair/typebox@0.34.49': {} + '@sindresorhus/is@7.2.0': {} + '@sindresorhus/merge-streams@4.0.0': {} + '@speed-highlight/core@1.2.14': {} '@sveltejs/acorn-typescript@1.0.11(acorn@8.16.0)': dependencies: acorn: 8.16.0 - '@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.4(@typescript-eslint/types@8.58.2))(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0))': + '@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.4(@typescript-eslint/types@8.58.2))(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0))': dependencies: deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.4 svelte: 5.56.4(@typescript-eslint/types@8.58.2) - vite: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0) - vitefu: 1.1.2(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)) + vite: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0) + vitefu: 1.1.2(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0)) + + '@tootallnate/quickjs-emscripten@0.23.0': {} '@tybys/wasm-util@0.10.3': dependencies: @@ -3977,16 +5779,59 @@ snapshots: '@types/estree@1.0.9': {} + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + '@types/json-schema@7.0.15': {} + '@types/mocha@10.0.10': {} + + '@types/node@20.19.43': + dependencies: + undici-types: 6.21.0 + + '@types/node@22.20.0': + dependencies: + undici-types: 6.21.0 + '@types/node@24.11.0': dependencies: undici-types: 7.16.0 + '@types/normalize-package-data@2.4.4': {} + + '@types/sinonjs__fake-timers@8.1.5': {} + '@types/sortablejs@1.15.9': {} + '@types/stack-utils@2.0.3': {} + '@types/trusted-types@2.0.7': {} + '@types/which@2.0.2': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 24.11.0 + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.35': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@types/yauzl@2.10.3': + dependencies: + '@types/node': 24.11.0 + optional: true + '@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2(eslint@10.0.2(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.0.2(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -4196,7 +6041,7 @@ snapshots: dependencies: '@unocss/core': 66.7.5 - '@unocss/vite@66.7.5(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0))': + '@unocss/vite@66.7.5(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0))': dependencies: '@jridgewell/remapping': 2.3.5 '@unocss/config': 66.7.5 @@ -4207,25 +6052,241 @@ snapshots: pathe: 2.0.3 tinyglobby: 0.2.17 unplugin-utils: 0.3.1 - vite: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0) + vite: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0) - '@vitest/mocker@5.0.0(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0))': + '@vitest/mocker@5.0.0(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0))': dependencies: '@jridgewell/trace-mapping': 0.3.31 '@vitest/spy': 5.0.0 estree-walker: 3.0.3 magic-string: 1.2.3 optionalDependencies: - vite: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0) + vite: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0) + + '@vitest/pretty-format@3.2.7': + dependencies: + tinyrainbow: 2.0.0 + + '@vitest/pretty-format@4.1.11': + dependencies: + tinyrainbow: 3.1.1 + + '@vitest/snapshot@3.2.7': + dependencies: + '@vitest/pretty-format': 3.2.7 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.11': + dependencies: + '@vitest/pretty-format': 4.1.11 + '@vitest/utils': 4.1.11 + magic-string: 0.30.21 + pathe: 2.0.3 '@vitest/spy@5.0.0': {} + '@vitest/utils@4.1.11': + dependencies: + '@vitest/pretty-format': 4.1.11 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.1 + + '@wdio/cli@9.31.9(@types/node@22.20.0)(expect-webdriverio@5.7.0)(supports-color@8.1.1)': + dependencies: + '@vitest/snapshot': 3.2.7 + '@wdio/config': 9.31.9(supports-color@8.1.1) + '@wdio/globals': 9.31.3(expect-webdriverio@5.7.0)(webdriverio@9.31.9(supports-color@8.1.1)) + '@wdio/logger': 9.29.1 + '@wdio/protocols': 9.31.5 + '@wdio/types': 9.31.2 + '@wdio/utils': 9.31.9(supports-color@8.1.1) + async-exit-hook: 2.0.1 + chalk: 5.6.2 + chokidar: 4.0.3 + create-wdio: 9.31.6(@types/node@22.20.0) + dotenv: 17.4.2 + import-meta-resolve: 4.2.0 + lodash.flattendeep: 4.4.0 + lodash.pickby: 4.6.0 + lodash.union: 4.6.0 + read-pkg-up: 10.1.0 + tsx: 4.23.0 + webdriverio: 9.31.9(supports-color@8.1.1) + yargs: 17.7.3 + transitivePeerDependencies: + - '@types/node' + - bare-abort-controller + - bare-buffer + - bufferutil + - expect-webdriverio + - puppeteer-core + - react-native-b4a + - supports-color + - utf-8-validate + + '@wdio/config@9.31.9(supports-color@8.1.1)': + dependencies: + '@wdio/logger': 9.29.1 + '@wdio/types': 9.31.2 + '@wdio/utils': 9.31.9(supports-color@8.1.1) + deepmerge-ts: 8.0.2 + glob: 10.5.0 + import-meta-resolve: 4.2.0 + jiti: 2.6.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + - supports-color + + '@wdio/dot-reporter@9.31.2': + dependencies: + '@wdio/reporter': 9.31.2 + '@wdio/types': 9.31.2 + chalk: 5.6.2 + + '@wdio/globals@9.31.3(expect-webdriverio@5.7.0)(webdriverio@9.31.9(supports-color@8.1.1))': + dependencies: + expect-webdriverio: 5.7.0(@wdio/globals@9.31.3)(@wdio/logger@9.29.1)(webdriverio@9.31.9(supports-color@8.1.1)) + webdriverio: 9.31.9(supports-color@8.1.1) + + '@wdio/globals@9.31.3(expect-webdriverio@6.0.10)(webdriverio@9.31.9(supports-color@8.1.1))': + dependencies: + expect-webdriverio: 6.0.10(@wdio/globals@9.31.3)(@wdio/logger@9.29.1)(webdriverio@9.31.9(supports-color@8.1.1)) + webdriverio: 9.31.9(supports-color@8.1.1) + + '@wdio/local-runner@9.31.9(@wdio/globals@9.31.3)(supports-color@8.1.1)(webdriverio@9.31.9(supports-color@8.1.1))': + dependencies: + '@types/node': 20.19.43 + '@wdio/logger': 9.29.1 + '@wdio/repl': 9.16.2 + '@wdio/runner': 9.31.9(expect-webdriverio@6.0.10)(supports-color@8.1.1)(webdriverio@9.31.9(supports-color@8.1.1)) + '@wdio/types': 9.31.2 + '@wdio/xvfb': 9.31.2 + exit-hook: 4.0.0 + expect-webdriverio: 6.0.10(@wdio/globals@9.31.3)(@wdio/logger@9.29.1)(webdriverio@9.31.9(supports-color@8.1.1)) + split2: 4.2.0 + stream-buffers: 3.0.3 + transitivePeerDependencies: + - '@wdio/globals' + - bare-abort-controller + - bare-buffer + - bufferutil + - react-native-b4a + - supports-color + - utf-8-validate + - webdriverio + + '@wdio/logger@9.29.1': + dependencies: + chalk: 5.6.2 + loglevel: 1.9.2 + loglevel-plugin-prefix: 0.8.4 + safe-regex2: 5.1.1 + strip-ansi: 7.2.0 + + '@wdio/mocha-framework@9.31.9(supports-color@8.1.1)': + dependencies: + '@types/mocha': 10.0.10 + '@types/node': 20.19.43 + '@wdio/logger': 9.29.1 + '@wdio/types': 9.31.2 + '@wdio/utils': 9.31.9(supports-color@8.1.1) + mocha: 10.8.2 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + - supports-color + + '@wdio/protocols@9.31.5': {} + + '@wdio/repl@9.16.2': + dependencies: + '@types/node': 20.19.43 + + '@wdio/reporter@9.31.2': + dependencies: + '@types/node': 20.19.43 + '@wdio/logger': 9.29.1 + '@wdio/types': 9.31.2 + diff: 8.0.4 + object-inspect: 1.13.4 + + '@wdio/runner@9.31.9(expect-webdriverio@6.0.10)(supports-color@8.1.1)(webdriverio@9.31.9(supports-color@8.1.1))': + dependencies: + '@types/node': 20.19.43 + '@wdio/config': 9.31.9(supports-color@8.1.1) + '@wdio/dot-reporter': 9.31.2 + '@wdio/globals': 9.31.3(expect-webdriverio@6.0.10)(webdriverio@9.31.9(supports-color@8.1.1)) + '@wdio/logger': 9.29.1 + '@wdio/types': 9.31.2 + '@wdio/utils': 9.31.9(supports-color@8.1.1) + deepmerge-ts: 8.0.2 + expect-webdriverio: 6.0.10(@wdio/globals@9.31.3)(@wdio/logger@9.29.1)(webdriverio@9.31.9(supports-color@8.1.1)) + webdriver: 9.31.9(supports-color@8.1.1) + webdriverio: 9.31.9(supports-color@8.1.1) + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - bufferutil + - react-native-b4a + - supports-color + - utf-8-validate + + '@wdio/spec-reporter@9.31.2': + dependencies: + '@wdio/reporter': 9.31.2 + '@wdio/types': 9.31.2 + chalk: 5.6.2 + easy-table: 1.2.0 + pretty-ms: 9.3.0 + + '@wdio/types@9.31.2': + dependencies: + '@types/node': 20.19.43 + + '@wdio/utils@9.31.9(supports-color@8.1.1)': + dependencies: + '@puppeteer/browsers': 2.13.2(supports-color@8.1.1) + '@wdio/logger': 9.29.1 + '@wdio/types': 9.31.2 + decamelize: 6.0.1 + deepmerge-ts: 8.0.2 + edgedriver: 6.3.1(supports-color@8.1.1) + geckodriver: 6.1.1(supports-color@8.1.1) + get-port: 7.2.0 + import-meta-resolve: 4.2.0 + locate-app: 2.5.0 + mitt: 3.0.1 + safaridriver: 1.0.1 + split2: 4.2.0 + wait-port: 1.1.0(supports-color@8.1.1) + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + - supports-color + + '@wdio/xvfb@9.31.2': + dependencies: + '@wdio/logger': 9.29.1 + + '@zip.js/zip.js@2.13.1': {} + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + acorn-jsx@5.3.2(acorn@8.16.0): dependencies: acorn: 8.16.0 acorn@8.16.0: {} + agent-base@7.1.4: {} + ajv@6.14.0: dependencies: fast-deep-equal: 3.1.3 @@ -4233,20 +6294,125 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.3: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + archiver-utils@5.0.2: + dependencies: + glob: 10.5.0 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.18.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.7.0 + readdir-glob: 1.1.3 + tar-stream: 3.2.0 + zip-stream: 6.0.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + argparse@2.0.1: {} aria-query@5.3.1: {} assertion-error@2.0.1: {} + ast-types@0.13.4: + dependencies: + tslib: 2.8.1 + + async-exit-hook@2.0.1: {} + + async@3.2.6: {} + axobject-query@4.1.0: {} + b4a@1.8.1: {} + + balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + bare-events@2.9.1: {} + + bare-fs@4.7.3: + dependencies: + bare-events: 2.9.1 + bare-path: 3.0.1 + bare-stream: 2.13.3(bare-events@2.9.1) + bare-url: 2.4.5 + fast-fifo: 1.3.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + bare-os@3.9.3: {} + + bare-path@3.0.1: + dependencies: + bare-os: 3.9.3 + + bare-stream@2.13.3(bare-events@2.9.1): + dependencies: + b4a: 1.8.1 + streamx: 2.28.0 + teex: 1.0.1 + optionalDependencies: + bare-events: 2.9.1 + transitivePeerDependencies: + - react-native-b4a + + bare-url@2.4.5: + dependencies: + bare-path: 3.0.1 + + base64-js@1.5.1: {} + + basic-ftp@5.3.1: {} + before-after-hook@4.0.0: {} + binary-extensions@2.3.0: {} + blake3-wasm@2.1.5: {} + boolbase@1.0.0: {} + + brace-expansion@1.1.18: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.1.4: + dependencies: + balanced-match: 1.0.2 + brace-expansion@5.0.9: dependencies: balanced-match: 4.0.4 @@ -4255,36 +6421,161 @@ snapshots: dependencies: fill-range: 7.1.1 + browser-stdout@1.3.1: {} + + buffer-crc32@0.2.13: {} + + buffer-crc32@1.0.0: {} + buffer-from@1.1.2: {} + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + cac@7.0.0: {} + camelcase@6.3.0: {} + chai@6.2.2: {} + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + chardet@2.1.1: {} + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.2.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + encoding-sniffer: 0.2.1 + htmlparser2: 10.1.0 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 7.29.0 + whatwg-mimetype: 4.0.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + chokidar@5.0.0: dependencies: readdirp: 5.0.0 + ci-info@4.4.0: {} + cli-width@4.1.0: {} clipanion@4.0.0-rc.4(typanion@3.14.0): dependencies: typanion: 3.14.0 + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: + optional: true + clsx@2.1.1: {} + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + colorette@2.0.20: {} + commander@14.0.3: {} + commander@2.20.3: {} + commander@9.5.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.7.0 + + concat-map@0.0.1: {} + confbox@0.1.8: {} consola@3.4.2: {} + convert-source-map@2.0.0: {} + cookie@1.1.1: {} + core-util-is@1.0.3: {} + + crc-32@1.2.2: {} + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.7.0 + + create-wdio@9.31.6(@types/node@22.20.0): + dependencies: + chalk: 5.6.2 + commander: 14.0.3 + cross-spawn: 7.0.6 + ejs: 3.1.10 + execa: 9.6.1 + import-meta-resolve: 4.2.0 + inquirer: 12.11.1(@types/node@22.20.0) + normalize-package-data: 7.0.1 + read-pkg-up: 10.1.0 + recursive-readdir: 2.2.3 + semver: 7.8.5 + type-fest: 4.41.0 + yargs: 17.7.3 + transitivePeerDependencies: + - '@types/node' + cross-env@10.1.0: dependencies: '@epic-web/invariant': 1.0.0 @@ -4296,31 +6587,148 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-shorthand-properties@1.1.2: {} + css-tree@3.2.1: dependencies: mdn-data: 2.27.1 source-map-js: 1.2.1 + css-value@0.0.1: {} + + css-what@6.2.2: {} + + data-uri-to-buffer@6.0.2: {} + debug@4.4.3(supports-color@10.2.2): dependencies: ms: 2.1.3 optionalDependencies: supports-color: 10.2.2 + debug@4.4.3(supports-color@8.1.1): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 + + decamelize@4.0.0: {} + + decamelize@6.0.1: {} + + deep-eql@5.0.2: {} + deep-is@0.1.4: {} + deepmerge-ts@8.0.2: {} + deepmerge@4.3.1: {} + defaults@1.0.4: + dependencies: + clone: 1.0.4 + optional: true + defu@6.1.6: {} + degenerator@5.0.1: + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + destr@2.0.5: {} detect-libc@2.1.2: {} devalue@5.8.1: {} + diff@5.2.2: {} + + diff@8.0.4: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dotenv@17.4.2: {} + duplexer@0.1.2: {} + eastasianwidth@0.2.0: {} + + easy-table@1.2.0: + dependencies: + ansi-regex: 5.0.1 + optionalDependencies: + wcwidth: 1.0.1 + + edge-paths@3.0.5: + dependencies: + '@types/which': 2.0.2 + which: 2.0.2 + + edgedriver@6.3.1(supports-color@8.1.1): + dependencies: + '@wdio/logger': 9.29.1 + '@zip.js/zip.js': 2.13.1 + decamelize: 6.0.1 + edge-paths: 3.0.5 + http-proxy-agent: 7.0.2(supports-color@8.1.1) + https-proxy-agent: 7.0.6(supports-color@8.1.1) + which: 6.0.1 + transitivePeerDependencies: + - supports-color + + ejs@3.1.10: + dependencies: + jake: 10.9.4 + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encoding-sniffer@0.2.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + entities@4.5.0: {} + + entities@6.0.1: {} + + entities@7.0.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + error-stack-parser-es@1.0.5: {} es-module-lexer@2.3.2: {} @@ -4356,8 +6764,20 @@ snapshots: '@esbuild/win32-ia32': 0.28.1 '@esbuild/win32-x64': 0.28.1 + escalade@3.2.0: {} + + escape-string-regexp@2.0.0: {} + escape-string-regexp@4.0.0: {} + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + eslint-config-prettier@10.1.8(eslint@10.0.2(jiti@2.6.1)(supports-color@10.2.2)): dependencies: eslint: 10.0.2(jiti@2.6.1)(supports-color@10.2.2) @@ -4422,6 +6842,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 5.0.1 + esprima@4.0.1: {} + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -4446,12 +6868,82 @@ snapshots: esutils@2.0.3: {} + event-target-shim@5.0.1: {} + + events-universal@1.0.1: + dependencies: + bare-events: 2.9.1 + transitivePeerDependencies: + - bare-abort-controller + + events@3.3.0: {} + + execa@9.6.1: + 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.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + + exit-hook@4.0.0: {} + expect-type@1.4.0: {} + expect-webdriverio@5.7.0(@wdio/globals@9.31.3)(@wdio/logger@9.29.1)(webdriverio@9.31.9(supports-color@8.1.1)): + dependencies: + '@vitest/snapshot': 4.1.11 + '@wdio/globals': 9.31.3(expect-webdriverio@5.7.0)(webdriverio@9.31.9(supports-color@8.1.1)) + '@wdio/logger': 9.29.1 + deep-eql: 5.0.2 + expect: 30.4.1 + jest-matcher-utils: 30.4.1 + webdriverio: 9.31.9(supports-color@8.1.1) + + expect-webdriverio@6.0.10(@wdio/globals@9.31.3)(@wdio/logger@9.29.1)(webdriverio@9.31.9(supports-color@8.1.1)): + dependencies: + '@vitest/snapshot': 4.1.11 + '@wdio/globals': 9.31.3(expect-webdriverio@5.7.0)(webdriverio@9.31.9(supports-color@8.1.1)) + '@wdio/logger': 9.29.1 + deep-eql: 5.0.2 + expect: 30.4.1 + jest-matcher-utils: 30.4.1 + webdriverio: 9.31.9(supports-color@8.1.1) + + expect@30.4.1: + dependencies: + '@jest/expect-utils': 30.4.1 + '@jest/get-type': 30.1.0 + jest-matcher-utils: 30.4.1 + jest-message-util: 30.4.1 + jest-mock: 30.4.1 + jest-util: 30.4.1 + + extract-zip@2.0.1(supports-color@8.1.1): + dependencies: + debug: 4.4.3(supports-color@8.1.1) + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + fast-content-type-parse@3.0.0: {} + fast-deep-equal@2.0.1: {} + fast-deep-equal@3.1.3: {} + fast-fifo@1.3.2: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4478,14 +6970,26 @@ snapshots: dependencies: reusify: 1.1.0 + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + fdir@6.5.0(picomatch@4.0.7): optionalDependencies: picomatch: 4.0.7 + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 + filelist@1.0.6: + dependencies: + minimatch: 5.1.9 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -4495,18 +6999,64 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + flat-cache@4.0.1: dependencies: flatted: 3.4.2 keyv: 4.5.4 + flat@5.0.2: {} + flatted@3.4.2: {} + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true function-bind@1.1.2: {} + geckodriver@6.1.1(supports-color@8.1.1): + dependencies: + '@wdio/logger': 9.29.1 + '@zip.js/zip.js': 2.13.1 + decamelize: 6.0.1 + http-proxy-agent: 7.0.2(supports-color@8.1.1) + https-proxy-agent: 7.0.6(supports-color@8.1.1) + modern-tar: 0.7.6 + transitivePeerDependencies: + - supports-color + + get-caller-file@2.0.5: {} + + get-port@7.2.0: {} + + get-stream@5.2.0: + dependencies: + pump: 3.0.4 + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + get-uri@6.0.5(supports-color@8.1.1): + dependencies: + basic-ftp: 5.3.1 + data-uri-to-buffer: 6.0.2 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -4515,71 +7065,257 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.9 + once: 1.4.0 + globals@17.4.0: {} + graceful-fs@4.2.11: {} + + grapheme-splitter@1.0.4: {} + gzip-size@6.0.0: dependencies: duplexer: 0.1.2 + has-flag@4.0.0: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 + he@1.2.0: {} + + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + + hosted-git-info@8.1.0: + dependencies: + lru-cache: 10.4.3 + + htmlfy@0.8.1: {} + + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + + http-proxy-agent@7.0.2(supports-color@8.1.1): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6(supports-color@8.1.1): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + human-signals@8.0.1: {} + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + iconv-lite@0.7.2: dependencies: safer-buffer: 2.1.2 + ieee754@1.2.1: {} + ignore@5.3.2: {} ignore@7.0.5: {} + immediate@3.0.6: {} + import-meta-resolve@4.2.0: {} imurmurhash@0.1.4: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + inquirer@12.11.1(@types/node@22.20.0): + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@22.20.0) + '@inquirer/prompts': 7.10.1(@types/node@22.20.0) + '@inquirer/type': 3.0.10(@types/node@22.20.0) + mute-stream: 2.0.0 + run-async: 4.0.6 + rxjs: 7.8.2 + optionalDependencies: + '@types/node': 22.20.0 + + ip-address@10.7.0: {} + + is-arrayish@0.2.1: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + is-core-module@2.16.1: dependencies: hasown: 2.0.2 is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 is-number@7.0.0: {} + is-plain-obj@2.1.0: {} + + is-plain-obj@4.1.0: {} + is-reference@3.0.3: dependencies: '@types/estree': 1.0.9 + is-stream@2.0.1: {} + + is-stream@4.0.1: {} + + is-unicode-supported@0.1.0: {} + + is-unicode-supported@2.1.0: {} + + isarray@1.0.0: {} + isexe@2.0.0: {} + isexe@4.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jake@10.9.4: + dependencies: + async: 3.2.6 + filelist: 1.0.6 + picocolors: 1.1.1 + + jest-diff@30.4.1: + dependencies: + '@jest/diff-sequences': 30.4.0 + '@jest/get-type': 30.1.0 + chalk: 4.1.2 + pretty-format: 30.4.1 + + jest-matcher-utils@30.4.1: + dependencies: + '@jest/get-type': 30.1.0 + chalk: 4.1.2 + jest-diff: 30.4.1 + pretty-format: 30.4.1 + + jest-message-util@30.4.1: + dependencies: + '@babel/code-frame': 7.29.7 + '@jest/types': 30.4.1 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-util: 30.4.1 + picomatch: 4.0.7 + pretty-format: 30.4.1 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@30.4.1: + dependencies: + '@jest/types': 30.4.1 + '@types/node': 24.11.0 + jest-util: 30.4.1 + + jest-regex-util@30.4.0: {} + + jest-util@30.4.1: + dependencies: + '@jest/types': 30.4.1 + '@types/node': 24.11.0 + chalk: 4.1.2 + ci-info: 4.4.0 + graceful-fs: 4.2.11 + picomatch: 4.0.7 + jiti@2.6.1: {} + js-tokens@4.0.0: {} + js-yaml@4.3.2: dependencies: argparse: 2.0.1 json-buffer@3.0.1: {} + json-parse-even-better-errors@3.0.2: {} + json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} json-with-bigint@3.5.7: {} + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 kleur@4.1.5: {} + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 + lie@3.3.0: + dependencies: + immediate: 3.0.6 + lightningcss-android-arm64@1.32.0: optional: true @@ -4629,12 +7365,49 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + lines-and-columns@2.0.4: {} + + locate-app@2.5.0: + dependencies: + '@promptbook/utils': 0.69.5 + type-fest: 4.26.0 + userhome: 1.0.1 + locate-character@3.0.0: {} locate-path@6.0.0: dependencies: p-locate: 5.0.0 + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + + lodash.clonedeep@4.5.0: {} + + lodash.flattendeep@4.4.0: {} + + lodash.pickby@4.6.0: {} + + lodash.union@4.6.0: {} + + lodash.zip@4.2.0: {} + + lodash@4.18.1: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + loglevel-plugin-prefix@0.8.4: {} + + loglevel@1.9.2: {} + + lru-cache@10.4.3: {} + + lru-cache@7.18.3: {} + magic-regexp@0.10.0: dependencies: estree-walker: 3.0.3 @@ -4679,6 +7452,22 @@ snapshots: dependencies: brace-expansion: 5.0.9 + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.18 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.1.4 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.1.4 + + minipass@7.1.3: {} + + mitt@3.0.1: {} + mlly@1.8.0: dependencies: acorn: 8.16.0 @@ -4686,18 +7475,72 @@ snapshots: pkg-types: 1.3.1 ufo: 1.6.3 + mocha@10.8.2: + dependencies: + ansi-colors: 4.1.3 + browser-stdout: 1.3.1 + chokidar: 3.6.0 + debug: 4.4.3(supports-color@8.1.1) + diff: 5.2.2 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 8.1.0 + he: 1.2.0 + js-yaml: 4.3.2 + log-symbols: 4.1.0 + minimatch: 5.1.9 + ms: 2.1.3 + serialize-javascript: 7.0.5 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.5.1 + yargs: 16.2.2 + yargs-parser: 20.2.9 + yargs-unparser: 2.0.0 + + modern-tar@0.7.6: {} + mrmime@2.0.1: {} ms@2.1.3: {} + mute-stream@2.0.0: {} + mute-stream@3.0.0: {} nanoid@3.3.18: {} natural-compare@1.4.0: {} + netmask@2.1.1: {} + node-fetch-native@1.6.7: {} + normalize-package-data@6.0.2: + dependencies: + hosted-git-info: 7.0.2 + semver: 7.8.5 + validate-npm-package-license: 3.0.4 + + normalize-package-data@7.0.1: + dependencies: + hosted-git-info: 8.1.0 + semver: 7.8.5 + validate-npm-package-license: 3.0.4 + + normalize-path@3.0.0: {} + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + object-inspect@1.13.4: {} + obug@2.1.4: {} ofetch@1.5.1: @@ -4706,6 +7549,10 @@ snapshots: node-fetch-native: 1.6.7 ufo: 1.6.3 + once@1.4.0: + dependencies: + wrappy: 1.0.2 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -4749,22 +7596,86 @@ snapshots: dependencies: yocto-queue: 0.1.0 + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + pac-proxy-agent@7.2.0(supports-color@8.1.1): + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + get-uri: 6.0.5(supports-color@8.1.1) + http-proxy-agent: 7.0.2(supports-color@8.1.1) + https-proxy-agent: 7.0.6(supports-color@8.1.1) + pac-resolver: 7.0.1 + socks-proxy-agent: 8.0.5(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + pac-resolver@7.0.1: + dependencies: + degenerator: 5.0.1 + netmask: 2.1.1 + + package-json-from-dist@1.0.1: {} + package-manager-detector@1.6.0: {} + pako@1.0.11: {} + + parse-json@7.1.1: + dependencies: + '@babel/code-frame': 7.29.7 + error-ex: 1.3.4 + json-parse-even-better-errors: 3.0.2 + lines-and-columns: 2.0.4 + type-fest: 3.13.1 + + parse-ms@4.0.0: {} + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.3.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + path-exists@4.0.0: {} + path-exists@5.0.0: {} + path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + path-to-regexp@6.3.0: {} pathe@2.0.3: {} + pend@1.2.0: {} + perfect-debounce@2.1.0: {} picocolors@1.1.1: {} @@ -4789,24 +7700,122 @@ snapshots: prettier@3.8.1: {} + pretty-format@30.4.1: + dependencies: + '@jest/schemas': 30.4.1 + ansi-styles: 5.2.0 + react-is-18: react-is@18.3.1 + react-is-19: react-is@19.2.7 + + pretty-ms@9.3.0: + dependencies: + parse-ms: 4.0.0 + + process-nextick-args@2.0.1: {} + + process@0.11.10: {} + + progress@2.0.3: {} + + proxy-agent@6.5.0(supports-color@8.1.1): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + http-proxy-agent: 7.0.2(supports-color@8.1.1) + https-proxy-agent: 7.0.6(supports-color@8.1.1) + lru-cache: 7.18.3 + pac-proxy-agent: 7.2.0(supports-color@8.1.1) + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.5(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + proxy-from-env@1.1.0: {} + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + punycode@2.3.1: {} quansync@1.0.0: {} + query-selector-shadow-dom@1.0.1: {} + queue-microtask@1.2.3: {} + react-is@18.3.1: {} + + react-is@19.2.7: {} + + read-pkg-up@10.1.0: + dependencies: + find-up: 6.3.0 + read-pkg: 8.1.0 + type-fest: 4.41.0 + + read-pkg@8.1.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 6.0.2 + parse-json: 7.1.1 + type-fest: 4.41.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.9 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + + readdirp@4.1.2: {} + readdirp@5.0.0: {} + recursive-readdir@2.2.3: + dependencies: + minimatch: 3.1.5 + regexp-tree@0.1.27: {} + require-directory@2.1.1: {} + resolve@1.22.11: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + resq@1.11.0: + dependencies: + fast-deep-equal: 2.0.1 + + ret@0.5.0: {} + reusify@1.1.0: {} + rgb2hex@0.2.5: {} + rolldown@1.1.5: dependencies: '@oxc-project/types': 0.139.0 @@ -4860,10 +7869,26 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.62.4 fsevents: 2.3.3 + run-async@4.0.6: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safaridriver@1.0.1: {} + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-regex2@5.1.1: + dependencies: + ret: 0.5.0 + safe-regex@2.1.1: dependencies: regexp-tree: 0.1.27 @@ -4872,8 +7897,14 @@ snapshots: semver@7.8.5: {} + serialize-error@12.0.0: + dependencies: + type-fest: 4.41.0 + serialize-javascript@7.0.5: {} + setimmediate@1.0.5: {} + sharp@0.35.4(@types/node@24.11.0): dependencies: '@img/colour': 1.1.0 @@ -4923,8 +7954,25 @@ snapshots: mrmime: 2.0.1 totalist: 3.0.1 + slash@3.0.0: {} + + smart-buffer@4.2.0: {} + smob@1.6.1: {} + socks-proxy-agent@8.0.5(supports-color@8.1.1): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@8.1.1) + socks: 2.8.9 + transitivePeerDependencies: + - supports-color + + socks@2.8.9: + dependencies: + ip-address: 10.7.0 + smart-buffer: 4.2.0 + sortablejs@1.15.7: {} source-map-js@1.2.1: {} @@ -4936,12 +7984,85 @@ snapshots: source-map@0.6.1: {} + spacetrim@0.11.59: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.23 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 + + spdx-license-ids@3.0.23: {} + + split2@4.2.0: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + stackback@0.0.2: {} std-env@4.2.0: {} + stream-buffers@3.0.3: {} + + streamx@2.28.0: + dependencies: + events-universal: 1.0.1 + fast-fifo: 1.3.2 + text-decoder: 1.2.7 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-final-newline@4.0.0: {} + + strip-json-comments@3.1.1: {} + supports-color@10.2.2: {} + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} svelte@5.56.4(@typescript-eslint/types@8.58.2): @@ -4965,6 +8086,36 @@ snapshots: transitivePeerDependencies: - '@typescript-eslint/types' + tar-fs@3.1.3: + dependencies: + pump: 3.0.4 + tar-stream: 3.2.0 + optionalDependencies: + bare-fs: 4.7.3 + bare-path: 3.0.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + tar-stream@3.2.0: + dependencies: + b4a: 1.8.1 + bare-fs: 4.7.3 + fast-fifo: 1.3.2 + streamx: 2.28.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + teex@1.0.1: + dependencies: + streamx: 2.28.0 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + terser@5.46.0: dependencies: '@jridgewell/source-map': 0.3.11 @@ -4972,6 +8123,12 @@ snapshots: commander: 2.20.3 source-map-support: 0.5.21 + text-decoder@1.2.7: + dependencies: + b4a: 1.8.1 + transitivePeerDependencies: + - react-native-b4a + tinybench@6.1.4: {} tinyexec@1.3.0: {} @@ -4983,6 +8140,10 @@ snapshots: fdir: 6.5.0(picomatch@4.0.7) picomatch: 4.0.7 + tinyrainbow@2.0.0: {} + + tinyrainbow@3.1.1: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -4995,12 +8156,24 @@ snapshots: tslib@2.8.1: {} + tsx@4.23.0: + dependencies: + esbuild: 0.28.1 + optionalDependencies: + fsevents: 2.3.3 + typanion@3.14.0: {} type-check@0.4.0: dependencies: prelude-ls: 1.2.1 + type-fest@3.13.1: {} + + type-fest@4.26.0: {} + + type-fest@4.41.0: {} + type-level-regexp@0.1.17: {} typescript-eslint@8.58.2(eslint@10.0.2(jiti@2.6.1)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3): @@ -5031,17 +8204,23 @@ snapshots: quansync: 1.0.0 unconfig-core: 7.5.0 + undici-types@6.21.0: {} + undici-types@7.16.0: {} + undici@6.28.1: {} + undici@7.29.0: {} unenv@2.0.0-rc.24: dependencies: pathe: 2.0.3 + unicorn-magic@0.3.0: {} + universal-user-agent@7.0.3: {} - unocss@66.7.5(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)): + unocss@66.7.5(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0)): dependencies: '@unocss/cli': 66.7.5 '@unocss/core': 66.7.5 @@ -5059,7 +8238,7 @@ snapshots: '@unocss/transformer-compile-class': 66.7.5 '@unocss/transformer-directives': 66.7.5 '@unocss/transformer-variant-group': 66.7.5 - '@unocss/vite': 66.7.5(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)) + '@unocss/vite': 66.7.5(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0)) transitivePeerDependencies: - vite @@ -5079,7 +8258,18 @@ snapshots: dependencies: punycode: 2.3.1 - vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0): + urlpattern-polyfill@10.1.0: {} + + userhome@1.0.1: {} + + util-deprecate@1.0.2: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.7 @@ -5092,15 +8282,16 @@ snapshots: fsevents: 2.3.3 jiti: 2.6.1 terser: 5.46.0 + tsx: 4.23.0 - vitefu@1.1.2(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)): + vitefu@1.1.2(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0)): optionalDependencies: - vite: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0) + vite: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0) - vitest@5.0.0(@types/node@24.11.0)(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)): + vitest@5.0.0(@types/node@24.11.0)(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0)): dependencies: '@types/chai': 5.2.3 - '@vitest/mocker': 5.0.0(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)) + '@vitest/mocker': 5.0.0(vite@8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0)) chai: 6.2.2 es-module-lexer: 2.3.2 expect-type: 1.4.0 @@ -5111,19 +8302,98 @@ snapshots: tinybench: 6.1.4 tinyexec: 1.3.0 tinyglobby: 0.2.17 - vite: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0) + vite: 8.1.4(@types/node@24.11.0)(esbuild@0.28.1)(jiti@2.6.1)(terser@5.46.0)(tsx@4.23.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.11.0 transitivePeerDependencies: - msw + wait-port@1.1.0(supports-color@8.1.1): + dependencies: + chalk: 4.1.2 + commander: 9.5.0 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + optional: true + + webdriver@9.31.9(supports-color@8.1.1): + dependencies: + '@types/node': 20.19.43 + '@types/ws': 8.18.1 + '@wdio/config': 9.31.9(supports-color@8.1.1) + '@wdio/logger': 9.29.1 + '@wdio/protocols': 9.31.5 + '@wdio/types': 9.31.2 + '@wdio/utils': 9.31.9(supports-color@8.1.1) + deepmerge-ts: 8.0.2 + https-proxy-agent: 7.0.6(supports-color@8.1.1) + undici: 6.28.1 + ws: 8.21.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - bufferutil + - react-native-b4a + - supports-color + - utf-8-validate + + webdriverio@9.31.9(supports-color@8.1.1): + dependencies: + '@types/node': 20.19.43 + '@types/sinonjs__fake-timers': 8.1.5 + '@wdio/config': 9.31.9(supports-color@8.1.1) + '@wdio/logger': 9.29.1 + '@wdio/protocols': 9.31.5 + '@wdio/repl': 9.16.2 + '@wdio/types': 9.31.2 + '@wdio/utils': 9.31.9(supports-color@8.1.1) + archiver: 7.0.1 + aria-query: 5.3.1 + cheerio: 1.2.0 + css-shorthand-properties: 1.1.2 + css-value: 0.0.1 + grapheme-splitter: 1.0.4 + htmlfy: 0.8.1 + is-plain-obj: 4.1.0 + jszip: 3.10.1 + lodash.clonedeep: 4.5.0 + lodash.zip: 4.2.0 + query-selector-shadow-dom: 1.0.1 + resq: 1.11.0 + rgb2hex: 0.2.5 + serialize-error: 12.0.0 + urlpattern-polyfill: 10.1.0 + webdriver: 9.31.9(supports-color@8.1.1) + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - bufferutil + - react-native-b4a + - supports-color + - utf-8-validate + webpack-virtual-modules@0.6.2: {} + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + which@2.0.2: dependencies: isexe: 2.0.0 + which@6.0.1: + dependencies: + isexe: 4.0.0 + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 @@ -5139,6 +8409,8 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20260722.1 '@cloudflare/workerd-windows-64': 1.20260722.1 + workerpool@6.5.1: {} + wrangler@4.114.0(@types/node@24.11.0): dependencies: '@cloudflare/kv-asset-handler': 0.5.0 @@ -5156,10 +8428,74 @@ snapshots: - bufferutil - utf-8-validate + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} + ws@8.21.0: {} + y18n@5.0.8: {} + + yargs-parser@20.2.9: {} + + yargs-parser@21.1.1: {} + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@16.2.2: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yargs@17.7.3: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + yocto-queue@0.1.0: {} + yocto-queue@1.2.2: {} + + yoctocolors-cjs@2.1.3: {} + + yoctocolors@2.1.2: {} + youch-core@0.3.3: dependencies: '@poppinss/exception': 1.2.3 @@ -5174,3 +8510,9 @@ snapshots: youch-core: 0.3.3 zimmerframe@1.1.4: {} + + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.7.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 73606420d..4032eb6ec 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,6 @@ packages: - packages/api + - packages/api-e2e - packages/cli - crates/tauri-schema-worker - examples/api @@ -7,12 +8,37 @@ packages: - examples/file-associations allowBuilds: + # transitive deps of @wdio/utils; their postinstall downloads browser drivers + # the Tauri suite never uses (it drives the app via tauri-driver) + edgedriver: false esbuild: true + geckodriver: false sharp: true workerd: true +minimumReleaseAgeExclude: + - serialize-javascript@7.0.5 + - brace-expansion@1.1.16 || 2.1.2 || 5.0.7 + - js-yaml@4.3.0 + - sharp@0.35.0 + - fast-xml-parser@5.10.1 + overrides: + brace-expansion@<1.1.16: ^1.1.16 + brace-expansion@>=2.0.0 <2.1.2: ^2.1.2 + brace-expansion@>=3.0.0 <5.0.7: ^5.0.7 + diff@>=6.0.0 <8.0.3: ^8.0.3 esbuild@>=0.27.3 <0.28.1: '>=0.28.1' + ip-address@<10.3.1: ^10.3.1 + serialize-javascript@<7.0.5: ^7.0.5 sharp@<0.35.4: ^0.35.4 undici@>=7.0.0 <7.29.0: ^7.29.0 ws@>=8.0.0 <8.20.1: '>=8.20.1' + +auditConfig: + ignoreGhsas: + # extract-zip symlink path traversal; no patched release exists (latest is + # still 2.0.1). Reached via @wdio/utils > @puppeteer/browsers, which only + # unpacks the browser drivers we never download (see allowBuilds above) + - GHSA-jmr9-qjv8-65gv + - GHSA-7pqw-9j4j-h8q3