diff --git a/.github/actions/setup-web/action.yml b/.github/actions/setup-web/action.yml index 24af948732..673155bcf7 100644 --- a/.github/actions/setup-web/action.yml +++ b/.github/actions/setup-web/action.yml @@ -6,7 +6,6 @@ runs: - name: Setup Vite+ uses: voidzero-dev/setup-vp@20553a7a7429c429a74894104a2835d7fed28a72 # v1.3.0 with: - working-directory: web node-version-file: .nvmrc cache: true run-install: true diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml index 7bce056970..cd967b76cf 100644 --- a/.github/workflows/api-tests.yml +++ b/.github/workflows/api-tests.yml @@ -35,7 +35,7 @@ jobs: persist-credentials: false - name: Setup UV and Python - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: enable-cache: true python-version: ${{ matrix.python-version }} @@ -84,7 +84,7 @@ jobs: persist-credentials: false - name: Setup UV and Python - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: enable-cache: true python-version: ${{ matrix.python-version }} @@ -156,7 +156,7 @@ jobs: persist-credentials: false - name: Setup UV and Python - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: enable-cache: true python-version: "3.12" @@ -203,7 +203,7 @@ jobs: - name: Report coverage if: ${{ env.CODECOV_TOKEN != '' }} - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: files: ./coverage.xml disable_search: true diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index d8a53c9594..9648c34274 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -39,6 +39,10 @@ jobs: with: files: | web/** + package.json + pnpm-lock.yaml + pnpm-workspace.yaml + .nvmrc - name: Check api inputs if: github.event_name != 'merge_group' id: api-changes @@ -52,7 +56,7 @@ jobs: python-version: "3.11" - if: github.event_name != 'merge_group' - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 - name: Generate Docker Compose if: github.event_name != 'merge_group' && steps.docker-compose-changes.outputs.any_changed == 'true' diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 1ae8d44482..a23edc70e5 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -24,27 +24,39 @@ env: jobs: build: - runs-on: ${{ matrix.platform == 'linux/arm64' && 'arm64_runner' || 'ubuntu-latest' }} + runs-on: ${{ matrix.runs_on }} if: github.repository == 'langgenius/dify' strategy: matrix: include: - service_name: "build-api-amd64" image_name_env: "DIFY_API_IMAGE_NAME" - context: "api" + artifact_context: "api" + build_context: "{{defaultContext}}:api" + file: "Dockerfile" platform: linux/amd64 + runs_on: ubuntu-latest - service_name: "build-api-arm64" image_name_env: "DIFY_API_IMAGE_NAME" - context: "api" + artifact_context: "api" + build_context: "{{defaultContext}}:api" + file: "Dockerfile" platform: linux/arm64 + runs_on: ubuntu-24.04-arm - service_name: "build-web-amd64" image_name_env: "DIFY_WEB_IMAGE_NAME" - context: "web" + artifact_context: "web" + build_context: "{{defaultContext}}" + file: "web/Dockerfile" platform: linux/amd64 + runs_on: ubuntu-latest - service_name: "build-web-arm64" image_name_env: "DIFY_WEB_IMAGE_NAME" - context: "web" + artifact_context: "web" + build_context: "{{defaultContext}}" + file: "web/Dockerfile" platform: linux/arm64 + runs_on: ubuntu-24.04-arm steps: - name: Prepare @@ -58,9 +70,6 @@ jobs: username: ${{ env.DOCKERHUB_USER }} password: ${{ env.DOCKERHUB_TOKEN }} - - name: Set up QEMU - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 - - name: Set up Docker Buildx uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 @@ -74,7 +83,8 @@ jobs: id: build uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: - context: "{{defaultContext}}:${{ matrix.context }}" + context: ${{ matrix.build_context }} + file: ${{ matrix.file }} platforms: ${{ matrix.platform }} build-args: COMMIT_SHA=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} labels: ${{ steps.meta.outputs.labels }} @@ -93,7 +103,7 @@ jobs: - name: Upload digest uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: - name: digests-${{ matrix.context }}-${{ env.PLATFORM_PAIR }} + name: digests-${{ matrix.artifact_context }}-${{ env.PLATFORM_PAIR }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 diff --git a/.github/workflows/db-migration-test.yml b/.github/workflows/db-migration-test.yml index ffb9734e48..5991abe3ba 100644 --- a/.github/workflows/db-migration-test.yml +++ b/.github/workflows/db-migration-test.yml @@ -19,7 +19,7 @@ jobs: persist-credentials: false - name: Setup UV and Python - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: enable-cache: true python-version: "3.12" @@ -69,7 +69,7 @@ jobs: persist-credentials: false - name: Setup UV and Python - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: enable-cache: true python-version: "3.12" diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 340b380dc9..cbeb1a3bb1 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -6,7 +6,12 @@ on: - "main" paths: - api/Dockerfile + - web/docker/** - web/Dockerfile + - package.json + - pnpm-lock.yaml + - pnpm-workspace.yaml + - .nvmrc concurrency: group: docker-build-${{ github.head_ref || github.run_id }} @@ -14,26 +19,31 @@ concurrency: jobs: build-docker: - runs-on: ubuntu-latest + runs-on: ${{ matrix.runs_on }} strategy: matrix: include: - service_name: "api-amd64" platform: linux/amd64 - context: "api" + runs_on: ubuntu-latest + context: "{{defaultContext}}:api" + file: "Dockerfile" - service_name: "api-arm64" platform: linux/arm64 - context: "api" + runs_on: ubuntu-24.04-arm + context: "{{defaultContext}}:api" + file: "Dockerfile" - service_name: "web-amd64" platform: linux/amd64 - context: "web" + runs_on: ubuntu-latest + context: "{{defaultContext}}" + file: "web/Dockerfile" - service_name: "web-arm64" platform: linux/arm64 - context: "web" + runs_on: ubuntu-24.04-arm + context: "{{defaultContext}}" + file: "web/Dockerfile" steps: - - name: Set up QEMU - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 - - name: Set up Docker Buildx uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 @@ -41,8 +51,8 @@ jobs: uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: push: false - context: "{{defaultContext}}:${{ matrix.context }}" - file: "${{ matrix.file }}" + context: ${{ matrix.context }} + file: ${{ matrix.file }} platforms: ${{ matrix.platform }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml index 2d96dae4da..104368d192 100644 --- a/.github/workflows/main-ci.yml +++ b/.github/workflows/main-ci.yml @@ -65,6 +65,10 @@ jobs: - 'docker/volumes/sandbox/conf/**' web: - 'web/**' + - 'package.json' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - '.nvmrc' - '.github/workflows/web-tests.yml' - '.github/actions/setup-web/**' e2e: @@ -73,6 +77,10 @@ jobs: - 'api/uv.lock' - 'e2e/**' - 'web/**' + - 'package.json' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - '.nvmrc' - 'docker/docker-compose.middleware.yaml' - 'docker/middleware.env.example' - '.github/workflows/web-e2e.yml' diff --git a/.github/workflows/pyrefly-diff.yml b/.github/workflows/pyrefly-diff.yml index a00f469bbe..8623d35b04 100644 --- a/.github/workflows/pyrefly-diff.yml +++ b/.github/workflows/pyrefly-diff.yml @@ -22,7 +22,7 @@ jobs: fetch-depth: 0 - name: Setup Python & UV - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: enable-cache: true @@ -50,6 +50,17 @@ jobs: run: | diff -u /tmp/pyrefly_base.txt /tmp/pyrefly_pr.txt > pyrefly_diff.txt || true + - name: Check if line counts match + id: line_count_check + run: | + base_lines=$(wc -l < /tmp/pyrefly_base.txt) + pr_lines=$(wc -l < /tmp/pyrefly_pr.txt) + if [ "$base_lines" -eq "$pr_lines" ]; then + echo "same=true" >> $GITHUB_OUTPUT + else + echo "same=false" >> $GITHUB_OUTPUT + fi + - name: Save PR number run: | echo ${{ github.event.pull_request.number }} > pr_number.txt @@ -63,7 +74,7 @@ jobs: pr_number.txt - name: Comment PR with pyrefly diff - if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && steps.line_count_check.outputs.same == 'false' }} uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 7b269ccf4e..9bc4ceaa93 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -33,7 +33,7 @@ jobs: - name: Setup UV and Python if: steps.changed-files.outputs.any_changed == 'true' - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: enable-cache: false python-version: "3.12" @@ -77,6 +77,10 @@ jobs: with: files: | web/** + package.json + pnpm-lock.yaml + pnpm-workspace.yaml + .nvmrc .github/workflows/style.yml .github/actions/setup-web/** @@ -90,9 +94,9 @@ jobs: uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: web/.eslintcache - key: ${{ runner.os }}-web-eslint-${{ hashFiles('web/package.json', 'web/pnpm-lock.yaml', 'web/eslint.config.mjs', 'web/eslint.constants.mjs', 'web/plugins/eslint/**') }}-${{ github.sha }} + key: ${{ runner.os }}-web-eslint-${{ hashFiles('web/package.json', 'pnpm-lock.yaml', 'web/eslint.config.mjs', 'web/eslint.constants.mjs', 'web/plugins/eslint/**') }}-${{ github.sha }} restore-keys: | - ${{ runner.os }}-web-eslint-${{ hashFiles('web/package.json', 'web/pnpm-lock.yaml', 'web/eslint.config.mjs', 'web/eslint.constants.mjs', 'web/plugins/eslint/**') }}- + ${{ runner.os }}-web-eslint-${{ hashFiles('web/package.json', 'pnpm-lock.yaml', 'web/eslint.config.mjs', 'web/eslint.constants.mjs', 'web/plugins/eslint/**') }}- - name: Web style check if: steps.changed-files.outputs.any_changed == 'true' diff --git a/.github/workflows/tool-test-sdks.yaml b/.github/workflows/tool-test-sdks.yaml index 3fc351c0c2..536a52b560 100644 --- a/.github/workflows/tool-test-sdks.yaml +++ b/.github/workflows/tool-test-sdks.yaml @@ -6,6 +6,9 @@ on: - main paths: - sdks/** + - package.json + - pnpm-lock.yaml + - pnpm-workspace.yaml concurrency: group: sdk-tests-${{ github.head_ref || github.run_id }} diff --git a/.github/workflows/translate-i18n-claude.yml b/.github/workflows/translate-i18n-claude.yml index aaf51aa606..f3fbfe60e2 100644 --- a/.github/workflows/translate-i18n-claude.yml +++ b/.github/workflows/translate-i18n-claude.yml @@ -1,10 +1,10 @@ name: Translate i18n Files with Claude Code +# Note: claude-code-action doesn't support push events directly. +# Push events are bridged by trigger-i18n-sync.yml via repository_dispatch. on: - push: - branches: [main] - paths: - - 'web/i18n/en-US/*.json' + repository_dispatch: + types: [i18n-sync] workflow_dispatch: inputs: files: @@ -30,7 +30,7 @@ permissions: concurrency: group: translate-i18n-${{ github.event_name }}-${{ github.ref }} - cancel-in-progress: ${{ github.event_name == 'push' }} + cancel-in-progress: false jobs: translate: @@ -67,19 +67,20 @@ jobs: } " web/i18n-config/languages.ts | sed 's/[[:space:]]*$//') - if [ "${{ github.event_name }}" = "push" ]; then - BASE_SHA="${{ github.event.before }}" - if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then - BASE_SHA=$(git rev-parse HEAD~1 2>/dev/null || true) - fi - HEAD_SHA="${{ github.sha }}" - if [ -n "$BASE_SHA" ]; then - CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" -- 'web/i18n/en-US/*.json' 2>/dev/null | sed -n 's@^.*/@@p' | sed 's/\.json$//' | tr '\n' ' ' | sed 's/[[:space:]]*$//') - else - CHANGED_FILES=$(find web/i18n/en-US -maxdepth 1 -type f -name '*.json' -print | sed -n 's@^.*/@@p' | sed 's/\.json$//' | sort | tr '\n' ' ' | sed 's/[[:space:]]*$//') - fi + if [ "${{ github.event_name }}" = "repository_dispatch" ]; then + BASE_SHA="${{ github.event.client_payload.base_sha }}" + HEAD_SHA="${{ github.event.client_payload.head_sha }}" + CHANGED_FILES="${{ github.event.client_payload.changed_files }}" TARGET_LANGS="$DEFAULT_TARGET_LANGS" - SYNC_MODE="incremental" + SYNC_MODE="${{ github.event.client_payload.sync_mode || 'incremental' }}" + + if [ -n "${{ github.event.client_payload.diff_base64 }}" ]; then + printf '%s' '${{ github.event.client_payload.diff_base64 }}' | base64 -d > /tmp/i18n-diff.txt + DIFF_AVAILABLE="true" + else + : > /tmp/i18n-diff.txt + DIFF_AVAILABLE="false" + fi else BASE_SHA="" HEAD_SHA=$(git rev-parse HEAD) @@ -104,6 +105,18 @@ jobs: else CHANGED_FILES="" fi + + if [ "$SYNC_MODE" = "incremental" ] && [ -n "$BASE_SHA" ]; then + git diff "$BASE_SHA" "$HEAD_SHA" -- 'web/i18n/en-US/*.json' > /tmp/i18n-diff.txt 2>/dev/null || : > /tmp/i18n-diff.txt + else + : > /tmp/i18n-diff.txt + fi + + if [ -s /tmp/i18n-diff.txt ]; then + DIFF_AVAILABLE="true" + else + DIFF_AVAILABLE="false" + fi fi FILE_ARGS="" @@ -123,6 +136,7 @@ jobs: echo "CHANGED_FILES=$CHANGED_FILES" echo "TARGET_LANGS=$TARGET_LANGS" echo "SYNC_MODE=$SYNC_MODE" + echo "DIFF_AVAILABLE=$DIFF_AVAILABLE" echo "FILE_ARGS=$FILE_ARGS" echo "LANG_ARGS=$LANG_ARGS" } >> "$GITHUB_OUTPUT" @@ -156,6 +170,7 @@ jobs: - Head SHA: `${{ steps.context.outputs.HEAD_SHA }}` - Scoped file args: `${{ steps.context.outputs.FILE_ARGS }}` - Scoped language args: `${{ steps.context.outputs.LANG_ARGS }}` + - Full English diff available: `${{ steps.context.outputs.DIFF_AVAILABLE }}` Tool rules: - Use Read for repository files. @@ -173,6 +188,9 @@ jobs: - Do not touch unrelated i18n files. - Do not modify `${{ github.workspace }}/web/i18n/en-US/`. 3. Detect English changes per file. + - Treat the current English JSON files under `${{ github.workspace }}/web/i18n/en-US/` plus the scoped `i18n:check` result as the primary source of truth. + - Use `/tmp/i18n-diff.txt` only as supporting context to understand what changed between `Base SHA` and `Head SHA`. + - Never rely on diff alone when deciding final keys or values. - Read the current English JSON file for each file in scope. - If sync mode is `incremental` and `Base SHA` is not empty, run: `git -C ${{ github.workspace }} show :web/i18n/en-US/.json` @@ -182,7 +200,7 @@ jobs: - ADD: key only in current - UPDATE: key exists in both and the English value changed - DELETE: key only in previous - - Do not rely on a truncated diff file. + - If `/tmp/i18n-diff.txt` is available, read it before translating so wording changes are grounded in the full English patch, but resolve any ambiguity by trusting the actual English files and scoped checks. 4. Run a scoped pre-check before editing: - `pnpm --dir ${{ github.workspace }}/web run i18n:check ${{ steps.context.outputs.FILE_ARGS }} ${{ steps.context.outputs.LANG_ARGS }}` - Use this command as the source of truth for missing and extra keys inside the current scope. diff --git a/.github/workflows/trigger-i18n-sync.yml b/.github/workflows/trigger-i18n-sync.yml new file mode 100644 index 0000000000..ee44fbb0c0 --- /dev/null +++ b/.github/workflows/trigger-i18n-sync.yml @@ -0,0 +1,81 @@ +name: Trigger i18n Sync on Push + +on: + push: + branches: [main] + paths: + - 'web/i18n/en-US/*.json' + +permissions: + contents: write + +concurrency: + group: trigger-i18n-sync-${{ github.ref }} + cancel-in-progress: true + +jobs: + trigger: + if: github.repository == 'langgenius/dify' + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - name: Detect changed files and generate full diff + id: detect + shell: bash + run: | + BASE_SHA="${{ github.event.before }}" + if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then + BASE_SHA=$(git rev-parse HEAD~1 2>/dev/null || true) + fi + HEAD_SHA="${{ github.sha }}" + + if [ -n "$BASE_SHA" ]; then + CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" -- 'web/i18n/en-US/*.json' 2>/dev/null | sed -n 's@^.*/@@p' | sed 's/\.json$//' | tr '\n' ' ' | sed 's/[[:space:]]*$//') + git diff "$BASE_SHA" "$HEAD_SHA" -- 'web/i18n/en-US/*.json' > /tmp/i18n-diff.txt 2>/dev/null || : > /tmp/i18n-diff.txt + else + CHANGED_FILES=$(find web/i18n/en-US -maxdepth 1 -type f -name '*.json' -print | sed -n 's@^.*/@@p' | sed 's/\.json$//' | sort | tr '\n' ' ' | sed 's/[[:space:]]*$//') + : > /tmp/i18n-diff.txt + fi + + if [ -n "$CHANGED_FILES" ]; then + echo "has_changes=true" >> "$GITHUB_OUTPUT" + else + echo "has_changes=false" >> "$GITHUB_OUTPUT" + fi + + echo "base_sha=$BASE_SHA" >> "$GITHUB_OUTPUT" + echo "head_sha=$HEAD_SHA" >> "$GITHUB_OUTPUT" + echo "changed_files=$CHANGED_FILES" >> "$GITHUB_OUTPUT" + + - name: Trigger i18n sync workflow + if: steps.detect.outputs.has_changes == 'true' + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + BASE_SHA: ${{ steps.detect.outputs.base_sha }} + HEAD_SHA: ${{ steps.detect.outputs.head_sha }} + CHANGED_FILES: ${{ steps.detect.outputs.changed_files }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs') + + const diffBase64 = fs.readFileSync('/tmp/i18n-diff.txt').toString('base64') + + await github.rest.repos.createDispatchEvent({ + owner: context.repo.owner, + repo: context.repo.repo, + event_type: 'i18n-sync', + client_payload: { + changed_files: process.env.CHANGED_FILES, + diff_base64: diffBase64, + sync_mode: 'incremental', + base_sha: process.env.BASE_SHA, + head_sha: process.env.HEAD_SHA, + }, + }) diff --git a/.github/workflows/vdb-tests-full.yml b/.github/workflows/vdb-tests-full.yml new file mode 100644 index 0000000000..01d25902f6 --- /dev/null +++ b/.github/workflows/vdb-tests-full.yml @@ -0,0 +1,95 @@ +name: Run Full VDB Tests + +on: + schedule: + - cron: '0 3 * * 1' + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: vdb-tests-full-${{ github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + test: + name: Full VDB Tests + if: github.repository == 'langgenius/dify' + runs-on: ubuntu-latest + strategy: + matrix: + python-version: + - "3.12" + + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Free Disk Space + uses: endersonmenezes/free-disk-space@7901478139cff6e9d44df5972fd8ab8fcade4db1 # v3.2.2 + with: + remove_dotnet: true + remove_haskell: true + remove_tool_cache: true + + - name: Setup UV and Python + uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + with: + enable-cache: true + python-version: ${{ matrix.python-version }} + cache-dependency-glob: api/uv.lock + + - name: Check UV lockfile + run: uv lock --project api --check + + - name: Install dependencies + run: uv sync --project api --dev + + - name: Set up dotenvs + run: | + cp docker/.env.example docker/.env + cp docker/middleware.env.example docker/middleware.env + + - name: Expose Service Ports + run: sh .github/workflows/expose_service_ports.sh + +# - name: Set up Vector Store (TiDB) +# uses: hoverkraft-tech/compose-action@v2.0.2 +# with: +# compose-file: docker/tidb/docker-compose.yaml +# services: | +# tidb +# tiflash + + - name: Set up Full Vector Store Matrix + uses: hoverkraft-tech/compose-action@4894d2492015c1774ee5a13a95b1072093087ec3 # v2.5.0 + with: + compose-file: | + docker/docker-compose.yaml + services: | + weaviate + qdrant + couchbase-server + etcd + minio + milvus-standalone + pgvecto-rs + pgvector + chroma + elasticsearch + oceanbase + + - name: setup test config + run: | + echo $(pwd) + ls -lah . + cp api/tests/integration_tests/.env.example api/tests/integration_tests/.env + +# - name: Check VDB Ready (TiDB) +# run: uv run --project api python api/tests/integration_tests/vdb/tidb_vector/check_tiflash_ready.py + + - name: Test Vector Stores + run: uv run --project api bash dev/pytest/pytest_vdb.sh diff --git a/.github/workflows/vdb-tests.yml b/.github/workflows/vdb-tests.yml index 7c4cd0ba8c..47ec70f603 100644 --- a/.github/workflows/vdb-tests.yml +++ b/.github/workflows/vdb-tests.yml @@ -1,15 +1,18 @@ -name: Run VDB Tests +name: Run VDB Smoke Tests on: workflow_call: +permissions: + contents: read + concurrency: group: vdb-tests-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: test: - name: VDB Tests + name: VDB Smoke Tests runs-on: ubuntu-latest strategy: matrix: @@ -30,7 +33,7 @@ jobs: remove_tool_cache: true - name: Setup UV and Python - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: enable-cache: true python-version: ${{ matrix.python-version }} @@ -58,23 +61,18 @@ jobs: # tidb # tiflash - - name: Set up Vector Stores (Weaviate, Qdrant, PGVector, Milvus, PgVecto-RS, Chroma, MyScale, ElasticSearch, Couchbase, OceanBase) + - name: Set up Vector Stores for Smoke Coverage uses: hoverkraft-tech/compose-action@4894d2492015c1774ee5a13a95b1072093087ec3 # v2.5.0 with: compose-file: | docker/docker-compose.yaml services: | + db_postgres + redis weaviate qdrant - couchbase-server - etcd - minio - milvus-standalone - pgvecto-rs pgvector chroma - elasticsearch - oceanbase - name: setup test config run: | @@ -86,4 +84,9 @@ jobs: # run: uv run --project api python api/tests/integration_tests/vdb/tidb_vector/check_tiflash_ready.py - name: Test Vector Stores - run: uv run --project api bash dev/pytest/pytest_vdb.sh + run: | + uv run --project api pytest --timeout "${PYTEST_TIMEOUT:-180}" \ + api/tests/integration_tests/vdb/chroma \ + api/tests/integration_tests/vdb/pgvector \ + api/tests/integration_tests/vdb/qdrant \ + api/tests/integration_tests/vdb/weaviate diff --git a/.github/workflows/web-e2e.yml b/.github/workflows/web-e2e.yml index 8035d1ef8e..eb752619be 100644 --- a/.github/workflows/web-e2e.yml +++ b/.github/workflows/web-e2e.yml @@ -27,12 +27,8 @@ jobs: - name: Setup web dependencies uses: ./.github/actions/setup-web - - name: Install E2E package dependencies - working-directory: ./e2e - run: vp install --frozen-lockfile - - name: Setup UV and Python - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0 with: enable-cache: true python-version: "3.12" diff --git a/.github/workflows/web-tests.yml b/.github/workflows/web-tests.yml index 8110a16355..3c36335e79 100644 --- a/.github/workflows/web-tests.yml +++ b/.github/workflows/web-tests.yml @@ -83,40 +83,9 @@ jobs: - name: Report coverage if: ${{ env.CODECOV_TOKEN != '' }} - uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: directory: web/coverage flags: web env: CODECOV_TOKEN: ${{ env.CODECOV_TOKEN }} - - web-build: - name: Web Build - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./web - - steps: - - name: Checkout code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: Check changed files - id: changed-files - uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5 - with: - files: | - web/** - .github/workflows/web-tests.yml - .github/actions/setup-web/** - - - name: Setup web environment - if: steps.changed-files.outputs.any_changed == 'true' - uses: ./.github/actions/setup-web - - - name: Web build check - if: steps.changed-files.outputs.any_changed == 'true' - working-directory: ./web - run: vp run build diff --git a/.gitignore b/.gitignore index aaca9f2b0a..d7698fe3fd 100644 --- a/.gitignore +++ b/.gitignore @@ -212,6 +212,7 @@ api/.vscode # pnpm /.pnpm-store +/node_modules # plugin migrate plugins.jsonl @@ -239,4 +240,4 @@ scripts/stress-test/reports/ *.local.md # Code Agent Folder -.qoder/* \ No newline at end of file +.qoder/* diff --git a/web/.nvmrc b/.nvmrc similarity index 100% rename from web/.nvmrc rename to .nvmrc diff --git a/Makefile b/Makefile index c377b7c671..d8c9df5208 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,8 @@ prepare-docker: # Step 2: Prepare web environment prepare-web: @echo "🌐 Setting up web environment..." - @cp -n web/.env.example web/.env 2>/dev/null || echo "Web .env already exists" - @cd web && pnpm install + @cp -n web/.env.example web/.env.local 2>/dev/null || echo "Web .env.local already exists" + @pnpm install @echo "✅ Web environment prepared (not started)" # Step 3: Prepare API environment @@ -93,7 +93,7 @@ test: # Build Docker images build-web: @echo "Building web Docker image: $(WEB_IMAGE):$(VERSION)..." - docker build -t $(WEB_IMAGE):$(VERSION) ./web + docker build -f web/Dockerfile -t $(WEB_IMAGE):$(VERSION) . @echo "Web Docker image built successfully: $(WEB_IMAGE):$(VERSION)" build-api: diff --git a/api/README.md b/api/README.md index b647367046..00562f3f78 100644 --- a/api/README.md +++ b/api/README.md @@ -40,6 +40,8 @@ The scripts resolve paths relative to their location, so you can run them from a ./dev/start-web ``` + `./dev/setup` and `./dev/start-web` install JavaScript dependencies through the repository root workspace, so you do not need a separate `cd web && pnpm install` step. + 1. Set up your application by visiting `http://localhost:3000`. 1. Start the worker service (async and scheduler tasks, runs from `api`). diff --git a/api/controllers/console/datasets/rag_pipeline/datasource_auth.py b/api/controllers/console/datasets/rag_pipeline/datasource_auth.py index 1976a6bc8a..bdf83b991e 100644 --- a/api/controllers/console/datasets/rag_pipeline/datasource_auth.py +++ b/api/controllers/console/datasets/rag_pipeline/datasource_auth.py @@ -120,7 +120,8 @@ class DatasourceOAuthCallback(Resource): if context is None: raise Forbidden("Invalid context_id") - user_id, tenant_id = context.get("user_id"), context.get("tenant_id") + user_id: str = context["user_id"] + tenant_id: str = context["tenant_id"] datasource_provider_id = DatasourceProviderID(provider_id) plugin_id = datasource_provider_id.plugin_id datasource_provider_service = DatasourceProviderService() @@ -141,7 +142,7 @@ class DatasourceOAuthCallback(Resource): system_credentials=oauth_client_params, request=request, ) - credential_id = context.get("credential_id") + credential_id: str | None = context.get("credential_id") if credential_id: datasource_provider_service.reauthorize_datasource_oauth_provider( tenant_id=tenant_id, @@ -150,7 +151,7 @@ class DatasourceOAuthCallback(Resource): name=oauth_response.metadata.get("name") or None, expire_at=oauth_response.expires_at, credentials=dict(oauth_response.credentials), - credential_id=context.get("credential_id"), + credential_id=credential_id, ) else: datasource_provider_service.add_datasource_oauth_provider( diff --git a/api/controllers/console/workspace/models.py b/api/controllers/console/workspace/models.py index 2ec1a9435a..9182dbb510 100644 --- a/api/controllers/console/workspace/models.py +++ b/api/controllers/console/workspace/models.py @@ -287,12 +287,10 @@ class ModelProviderModelCredentialApi(Resource): provider=provider, ) else: - # Normalize model_type to the origin value stored in DB (e.g., "text-generation" for LLM) - normalized_model_type = args.model_type.to_origin_model_type() available_credentials = model_provider_service.get_provider_model_available_credentials( tenant_id=tenant_id, provider=provider, - model_type=normalized_model_type, + model_type=args.model_type, model=args.model, ) diff --git a/api/controllers/console/workspace/tool_providers.py b/api/controllers/console/workspace/tool_providers.py index 02eb0adc94..80216915cd 100644 --- a/api/controllers/console/workspace/tool_providers.py +++ b/api/controllers/console/workspace/tool_providers.py @@ -832,7 +832,8 @@ class ToolOAuthCallback(Resource): tool_provider = ToolProviderID(provider) plugin_id = tool_provider.plugin_id provider_name = tool_provider.provider_name - user_id, tenant_id = context.get("user_id"), context.get("tenant_id") + user_id: str = context["user_id"] + tenant_id: str = context["tenant_id"] oauth_handler = OAuthHandler() oauth_client_params = BuiltinToolManageService.get_oauth_client(tenant_id, provider) diff --git a/api/controllers/console/workspace/trigger_providers.py b/api/controllers/console/workspace/trigger_providers.py index 265b6ecd9a..76d64cb97c 100644 --- a/api/controllers/console/workspace/trigger_providers.py +++ b/api/controllers/console/workspace/trigger_providers.py @@ -499,9 +499,9 @@ class TriggerOAuthCallbackApi(Resource): provider_id = TriggerProviderID(provider) plugin_id = provider_id.plugin_id provider_name = provider_id.provider_name - user_id = context.get("user_id") - tenant_id = context.get("tenant_id") - subscription_builder_id = context.get("subscription_builder_id") + user_id: str = context["user_id"] + tenant_id: str = context["tenant_id"] + subscription_builder_id: str = context["subscription_builder_id"] # Get OAuth client configuration oauth_client_params = TriggerProviderService.get_oauth_client( diff --git a/api/controllers/mcp/mcp.py b/api/controllers/mcp/mcp.py index 3d00f77e79..58ec76243b 100644 --- a/api/controllers/mcp/mcp.py +++ b/api/controllers/mcp/mcp.py @@ -174,6 +174,7 @@ class MCPAppApi(Resource): required=variable.get("required", False), max_length=variable.get("max_length"), options=variable.get("options") or [], + json_schema=variable.get("json_schema"), ) def _parse_mcp_request(self, args: dict) -> mcp_types.ClientRequest | mcp_types.ClientNotification: diff --git a/api/controllers/service_api/dataset/segment.py b/api/controllers/service_api/dataset/segment.py index b4cc9874b6..5b16da81e0 100644 --- a/api/controllers/service_api/dataset/segment.py +++ b/api/controllers/service_api/dataset/segment.py @@ -29,6 +29,31 @@ from services.entities.knowledge_entities.knowledge_entities import SegmentUpdat from services.errors.chunk import ChildChunkDeleteIndexError, ChildChunkIndexingError from services.errors.chunk import ChildChunkDeleteIndexError as ChildChunkDeleteIndexServiceError from services.errors.chunk import ChildChunkIndexingError as ChildChunkIndexingServiceError +from services.summary_index_service import SummaryIndexService + + +def _marshal_segment_with_summary(segment, dataset_id: str) -> dict: + """Marshal a single segment and enrich it with summary content.""" + segment_dict = dict(marshal(segment, segment_fields)) # type: ignore[arg-type] + summary = SummaryIndexService.get_segment_summary(segment_id=segment.id, dataset_id=dataset_id) + segment_dict["summary"] = summary.summary_content if summary else None + return segment_dict + + +def _marshal_segments_with_summary(segments, dataset_id: str) -> list[dict]: + """Marshal multiple segments and enrich them with summary content (batch query).""" + segment_ids = [segment.id for segment in segments] + summaries: dict = {} + if segment_ids: + summary_records = SummaryIndexService.get_segments_summaries(segment_ids=segment_ids, dataset_id=dataset_id) + summaries = {chunk_id: record.summary_content for chunk_id, record in summary_records.items()} + + result = [] + for segment in segments: + segment_dict = dict(marshal(segment, segment_fields)) # type: ignore[arg-type] + segment_dict["summary"] = summaries.get(segment.id) + result.append(segment_dict) + return result class SegmentCreatePayload(BaseModel): @@ -132,7 +157,7 @@ class SegmentApi(DatasetApiResource): for args_item in payload.segments: SegmentService.segment_create_args_validate(args_item, document) segments = SegmentService.multi_create_segment(payload.segments, document, dataset) - return {"data": marshal(segments, segment_fields), "doc_form": document.doc_form}, 200 + return {"data": _marshal_segments_with_summary(segments, dataset_id), "doc_form": document.doc_form}, 200 else: return {"error": "Segments is required"}, 400 @@ -196,7 +221,7 @@ class SegmentApi(DatasetApiResource): ) response = { - "data": marshal(segments, segment_fields), + "data": _marshal_segments_with_summary(segments, dataset_id), "doc_form": document.doc_form, "total": total, "has_more": len(segments) == limit, @@ -296,7 +321,7 @@ class DatasetSegmentApi(DatasetApiResource): payload = SegmentUpdatePayload.model_validate(service_api_ns.payload or {}) updated_segment = SegmentService.update_segment(payload.segment, segment, document, dataset) - return {"data": marshal(updated_segment, segment_fields), "doc_form": document.doc_form}, 200 + return {"data": _marshal_segment_with_summary(updated_segment, dataset_id), "doc_form": document.doc_form}, 200 @service_api_ns.doc("get_segment") @service_api_ns.doc(description="Get a specific segment by ID") @@ -326,7 +351,7 @@ class DatasetSegmentApi(DatasetApiResource): if not segment: raise NotFound("Segment not found.") - return {"data": marshal(segment, segment_fields), "doc_form": document.doc_form}, 200 + return {"data": _marshal_segment_with_summary(segment, dataset_id), "doc_form": document.doc_form}, 200 @service_api_ns.route( diff --git a/api/core/app/llm/quota.py b/api/core/app/llm/quota.py index 63d2235358..182f1b767d 100644 --- a/api/core/app/llm/quota.py +++ b/api/core/app/llm/quota.py @@ -81,7 +81,7 @@ def deduct_llm_quota(*, tenant_id: str, model_instance: ModelInstance, usage: LL # TODO: Use provider name with prefix after the data migration. Provider.provider_name == ModelProviderID(model_instance.provider).provider_name, Provider.provider_type == ProviderType.SYSTEM.value, - Provider.quota_type == system_configuration.current_quota_type.value, + Provider.quota_type == system_configuration.current_quota_type, Provider.quota_limit > Provider.quota_used, ) .values( diff --git a/api/core/app/workflow/layers/observability.py b/api/core/app/workflow/layers/observability.py index 8565c3076c..c4ed54a140 100644 --- a/api/core/app/workflow/layers/observability.py +++ b/api/core/app/workflow/layers/observability.py @@ -8,6 +8,7 @@ associates with the node span. """ import logging +from contextvars import Token from dataclasses import dataclass from typing import cast, final @@ -35,7 +36,7 @@ logger = logging.getLogger(__name__) @dataclass(slots=True) class _NodeSpanContext: span: "Span" - token: object + token: Token[context_api.Context] @final diff --git a/api/core/entities/provider_configuration.py b/api/core/entities/provider_configuration.py index 8b48aa2660..782897aea9 100644 --- a/api/core/entities/provider_configuration.py +++ b/api/core/entities/provider_configuration.py @@ -403,7 +403,7 @@ class ProviderConfiguration(BaseModel): ProviderModelCredential.tenant_id == self.tenant_id, ProviderModelCredential.provider_name.in_(self._get_provider_names()), ProviderModelCredential.model_name == model, - ProviderModelCredential.model_type == model_type.to_origin_model_type(), + ProviderModelCredential.model_type == model_type, ), ) @@ -753,7 +753,7 @@ class ProviderConfiguration(BaseModel): ProviderModel.tenant_id == self.tenant_id, ProviderModel.provider_name.in_(provider_names), ProviderModel.model_name == model, - ProviderModel.model_type == model_type.to_origin_model_type(), + ProviderModel.model_type == model_type, ) return session.execute(stmt).scalar_one_or_none() @@ -778,7 +778,7 @@ class ProviderConfiguration(BaseModel): ProviderModelCredential.tenant_id == self.tenant_id, ProviderModelCredential.provider_name.in_(self._get_provider_names()), ProviderModelCredential.model_name == model, - ProviderModelCredential.model_type == model_type.to_origin_model_type(), + ProviderModelCredential.model_type == model_type, ) credential_record = session.execute(stmt).scalar_one_or_none() @@ -825,7 +825,7 @@ class ProviderConfiguration(BaseModel): ProviderModelCredential.tenant_id == self.tenant_id, ProviderModelCredential.provider_name.in_(self._get_provider_names()), ProviderModelCredential.model_name == model, - ProviderModelCredential.model_type == model_type.to_origin_model_type(), + ProviderModelCredential.model_type == model_type, ProviderModelCredential.credential_name == credential_name, ) if exclude_id: @@ -901,7 +901,7 @@ class ProviderConfiguration(BaseModel): ProviderModelCredential.tenant_id == self.tenant_id, ProviderModelCredential.provider_name.in_(self._get_provider_names()), ProviderModelCredential.model_name == model, - ProviderModelCredential.model_type == model_type.to_origin_model_type(), + ProviderModelCredential.model_type == model_type, ) credential_record = s.execute(stmt).scalar_one_or_none() original_credentials = ( @@ -970,7 +970,7 @@ class ProviderConfiguration(BaseModel): tenant_id=self.tenant_id, provider_name=self.provider.provider, model_name=model, - model_type=model_type.to_origin_model_type(), + model_type=model_type, encrypted_config=json.dumps(credentials), credential_name=credential_name, ) @@ -983,7 +983,7 @@ class ProviderConfiguration(BaseModel): tenant_id=self.tenant_id, provider_name=self.provider.provider, model_name=model, - model_type=model_type.to_origin_model_type(), + model_type=model_type, credential_id=credential.id, is_valid=True, ) @@ -1038,7 +1038,7 @@ class ProviderConfiguration(BaseModel): ProviderModelCredential.tenant_id == self.tenant_id, ProviderModelCredential.provider_name.in_(self._get_provider_names()), ProviderModelCredential.model_name == model, - ProviderModelCredential.model_type == model_type.to_origin_model_type(), + ProviderModelCredential.model_type == model_type, ) credential_record = session.execute(stmt).scalar_one_or_none() if not credential_record: @@ -1083,7 +1083,7 @@ class ProviderConfiguration(BaseModel): ProviderModelCredential.tenant_id == self.tenant_id, ProviderModelCredential.provider_name.in_(self._get_provider_names()), ProviderModelCredential.model_name == model, - ProviderModelCredential.model_type == model_type.to_origin_model_type(), + ProviderModelCredential.model_type == model_type, ) credential_record = session.execute(stmt).scalar_one_or_none() if not credential_record: @@ -1116,7 +1116,7 @@ class ProviderConfiguration(BaseModel): ProviderModelCredential.tenant_id == self.tenant_id, ProviderModelCredential.provider_name.in_(self._get_provider_names()), ProviderModelCredential.model_name == model, - ProviderModelCredential.model_type == model_type.to_origin_model_type(), + ProviderModelCredential.model_type == model_type, ) available_credentials_count = session.execute(count_stmt).scalar() or 0 session.delete(credential_record) @@ -1156,7 +1156,7 @@ class ProviderConfiguration(BaseModel): ProviderModelCredential.tenant_id == self.tenant_id, ProviderModelCredential.provider_name.in_(self._get_provider_names()), ProviderModelCredential.model_name == model, - ProviderModelCredential.model_type == model_type.to_origin_model_type(), + ProviderModelCredential.model_type == model_type, ) credential_record = session.execute(stmt).scalar_one_or_none() if not credential_record: @@ -1171,7 +1171,7 @@ class ProviderConfiguration(BaseModel): tenant_id=self.tenant_id, provider_name=self.provider.provider, model_name=model, - model_type=model_type.to_origin_model_type(), + model_type=model_type, is_valid=True, credential_id=credential_id, ) @@ -1207,7 +1207,7 @@ class ProviderConfiguration(BaseModel): ProviderModelCredential.tenant_id == self.tenant_id, ProviderModelCredential.provider_name.in_(self._get_provider_names()), ProviderModelCredential.model_name == model, - ProviderModelCredential.model_type == model_type.to_origin_model_type(), + ProviderModelCredential.model_type == model_type, ) credential_record = session.execute(stmt).scalar_one_or_none() if not credential_record: @@ -1263,7 +1263,7 @@ class ProviderConfiguration(BaseModel): stmt = select(ProviderModelSetting).where( ProviderModelSetting.tenant_id == self.tenant_id, ProviderModelSetting.provider_name.in_(self._get_provider_names()), - ProviderModelSetting.model_type == model_type.to_origin_model_type(), + ProviderModelSetting.model_type == model_type, ProviderModelSetting.model_name == model, ) return session.execute(stmt).scalars().first() @@ -1286,7 +1286,7 @@ class ProviderConfiguration(BaseModel): model_setting = ProviderModelSetting( tenant_id=self.tenant_id, provider_name=self.provider.provider, - model_type=model_type.to_origin_model_type(), + model_type=model_type, model_name=model, enabled=True, ) @@ -1312,7 +1312,7 @@ class ProviderConfiguration(BaseModel): model_setting = ProviderModelSetting( tenant_id=self.tenant_id, provider_name=self.provider.provider, - model_type=model_type.to_origin_model_type(), + model_type=model_type, model_name=model, enabled=False, ) @@ -1348,7 +1348,7 @@ class ProviderConfiguration(BaseModel): stmt = select(func.count(LoadBalancingModelConfig.id)).where( LoadBalancingModelConfig.tenant_id == self.tenant_id, LoadBalancingModelConfig.provider_name.in_(provider_names), - LoadBalancingModelConfig.model_type == model_type.to_origin_model_type(), + LoadBalancingModelConfig.model_type == model_type, LoadBalancingModelConfig.model_name == model, ) load_balancing_config_count = session.execute(stmt).scalar() or 0 @@ -1364,7 +1364,7 @@ class ProviderConfiguration(BaseModel): model_setting = ProviderModelSetting( tenant_id=self.tenant_id, provider_name=self.provider.provider, - model_type=model_type.to_origin_model_type(), + model_type=model_type, model_name=model, load_balancing_enabled=True, ) @@ -1391,7 +1391,7 @@ class ProviderConfiguration(BaseModel): model_setting = ProviderModelSetting( tenant_id=self.tenant_id, provider_name=self.provider.provider, - model_type=model_type.to_origin_model_type(), + model_type=model_type, model_name=model, load_balancing_enabled=False, ) diff --git a/api/core/mcp/server/streamable_http.py b/api/core/mcp/server/streamable_http.py index 27000c947c..278add8cc9 100644 --- a/api/core/mcp/server/streamable_http.py +++ b/api/core/mcp/server/streamable_http.py @@ -260,4 +260,12 @@ def convert_input_form_to_parameters( parameters[item.variable]["enum"] = item.options elif item.type == VariableEntityType.NUMBER: parameters[item.variable]["type"] = "number" + elif item.type == VariableEntityType.CHECKBOX: + parameters[item.variable]["type"] = "boolean" + elif item.type == VariableEntityType.JSON_OBJECT: + parameters[item.variable]["type"] = "object" + if item.json_schema: + for key in ("properties", "required", "additionalProperties"): + if key in item.json_schema: + parameters[item.variable][key] = item.json_schema[key] return parameters, required diff --git a/api/core/ops/aliyun_trace/data_exporter/traceclient.py b/api/core/ops/aliyun_trace/data_exporter/traceclient.py index 0e00e90520..67d5163b0f 100644 --- a/api/core/ops/aliyun_trace/data_exporter/traceclient.py +++ b/api/core/ops/aliyun_trace/data_exporter/traceclient.py @@ -16,7 +16,13 @@ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExport from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import ReadableSpan from opentelemetry.sdk.util.instrumentation import InstrumentationScope -from opentelemetry.semconv.resource import ResourceAttributes +from opentelemetry.semconv._incubating.attributes.deployment_attributes import ( # type: ignore[import-untyped] + DEPLOYMENT_ENVIRONMENT, +) +from opentelemetry.semconv._incubating.attributes.host_attributes import ( # type: ignore[import-untyped] + HOST_NAME, +) +from opentelemetry.semconv.attributes import service_attributes from opentelemetry.trace import Link, SpanContext, TraceFlags from configs import dify_config @@ -45,10 +51,10 @@ class TraceClient: self.endpoint = endpoint self.resource = Resource( attributes={ - ResourceAttributes.SERVICE_NAME: service_name, - ResourceAttributes.SERVICE_VERSION: f"dify-{dify_config.project.version}-{dify_config.COMMIT_SHA}", - ResourceAttributes.DEPLOYMENT_ENVIRONMENT: f"{dify_config.DEPLOY_ENV}-{dify_config.EDITION}", - ResourceAttributes.HOST_NAME: socket.gethostname(), + service_attributes.SERVICE_NAME: service_name, + service_attributes.SERVICE_VERSION: f"dify-{dify_config.project.version}-{dify_config.COMMIT_SHA}", + DEPLOYMENT_ENVIRONMENT: f"{dify_config.DEPLOY_ENV}-{dify_config.EDITION}", + HOST_NAME: socket.gethostname(), ACS_ARMS_SERVICE_FEATURE: "genai_app", } ) diff --git a/api/core/ops/arize_phoenix_trace/arize_phoenix_trace.py b/api/core/ops/arize_phoenix_trace/arize_phoenix_trace.py index 39d97e2882..902f58e6b7 100644 --- a/api/core/ops/arize_phoenix_trace/arize_phoenix_trace.py +++ b/api/core/ops/arize_phoenix_trace/arize_phoenix_trace.py @@ -19,7 +19,7 @@ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExport from opentelemetry.sdk import trace as trace_sdk from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace.export import SimpleSpanProcessor -from opentelemetry.semconv.trace import SpanAttributes as OTELSpanAttributes +from opentelemetry.semconv.attributes import exception_attributes from opentelemetry.trace import Span, Status, StatusCode, set_span_in_context, use_span from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator from opentelemetry.util.types import AttributeValue @@ -134,10 +134,10 @@ def set_span_status(current_span: Span, error: Exception | str | None = None): if not exception_message: exception_message = repr(error) attributes: dict[str, AttributeValue] = { - OTELSpanAttributes.EXCEPTION_TYPE: exception_type, - OTELSpanAttributes.EXCEPTION_MESSAGE: exception_message, - OTELSpanAttributes.EXCEPTION_ESCAPED: False, - OTELSpanAttributes.EXCEPTION_STACKTRACE: error_string, + exception_attributes.EXCEPTION_TYPE: exception_type, + exception_attributes.EXCEPTION_MESSAGE: exception_message, + exception_attributes.EXCEPTION_ESCAPED: False, + exception_attributes.EXCEPTION_STACKTRACE: error_string, } current_span.add_event(name="exception", attributes=attributes) else: diff --git a/api/core/ops/langfuse_trace/langfuse_trace.py b/api/core/ops/langfuse_trace/langfuse_trace.py index 3644b6b4c2..9be2ce1bdf 100644 --- a/api/core/ops/langfuse_trace/langfuse_trace.py +++ b/api/core/ops/langfuse_trace/langfuse_trace.py @@ -1,9 +1,19 @@ import logging import os -from datetime import datetime, timedelta +import uuid +from datetime import UTC, datetime, timedelta from graphon.enums import BuiltinNodeTypes from langfuse import Langfuse +from langfuse.api import ( + CreateGenerationBody, + CreateSpanBody, + IngestionEvent_GenerationCreate, + IngestionEvent_SpanCreate, + IngestionEvent_TraceCreate, + TraceBody, +) +from langfuse.api.commons.types.usage import Usage from sqlalchemy.orm import sessionmaker from core.ops.base_trace_instance import BaseTraceInstance @@ -396,18 +406,61 @@ class LangFuseDataTrace(BaseTraceInstance): ) self.add_span(langfuse_span_data=name_generation_span_data) + def _make_event_id(self) -> str: + return str(uuid.uuid4()) + + def _now_iso(self) -> str: + return datetime.now(UTC).isoformat() + def add_trace(self, langfuse_trace_data: LangfuseTrace | None = None): - format_trace_data = filter_none_values(langfuse_trace_data.model_dump()) if langfuse_trace_data else {} + data = filter_none_values(langfuse_trace_data.model_dump()) if langfuse_trace_data else {} try: - self.langfuse_client.trace(**format_trace_data) + body = TraceBody( + id=data.get("id"), + name=data.get("name"), + user_id=data.get("user_id"), + input=data.get("input"), + output=data.get("output"), + metadata=data.get("metadata"), + session_id=data.get("session_id"), + version=data.get("version"), + release=data.get("release"), + tags=data.get("tags"), + public=data.get("public"), + ) + event = IngestionEvent_TraceCreate( + body=body, + id=self._make_event_id(), + timestamp=self._now_iso(), + ) + self.langfuse_client.api.ingestion.batch(batch=[event]) logger.debug("LangFuse Trace created successfully") except Exception as e: raise ValueError(f"LangFuse Failed to create trace: {str(e)}") def add_span(self, langfuse_span_data: LangfuseSpan | None = None): - format_span_data = filter_none_values(langfuse_span_data.model_dump()) if langfuse_span_data else {} + data = filter_none_values(langfuse_span_data.model_dump()) if langfuse_span_data else {} try: - self.langfuse_client.span(**format_span_data) + body = CreateSpanBody( + id=data.get("id"), + trace_id=data.get("trace_id"), + name=data.get("name"), + start_time=data.get("start_time"), + end_time=data.get("end_time"), + input=data.get("input"), + output=data.get("output"), + metadata=data.get("metadata"), + level=data.get("level"), + status_message=data.get("status_message"), + parent_observation_id=data.get("parent_observation_id"), + version=data.get("version"), + ) + event = IngestionEvent_SpanCreate( + body=body, + id=self._make_event_id(), + timestamp=self._now_iso(), + ) + self.langfuse_client.api.ingestion.batch(batch=[event]) logger.debug("LangFuse Span created successfully") except Exception as e: raise ValueError(f"LangFuse Failed to create span: {str(e)}") @@ -418,11 +471,45 @@ class LangFuseDataTrace(BaseTraceInstance): span.end(**format_span_data) def add_generation(self, langfuse_generation_data: LangfuseGeneration | None = None): - format_generation_data = ( - filter_none_values(langfuse_generation_data.model_dump()) if langfuse_generation_data else {} - ) + data = filter_none_values(langfuse_generation_data.model_dump()) if langfuse_generation_data else {} try: - self.langfuse_client.generation(**format_generation_data) + usage_data = data.pop("usage", None) + usage = None + if usage_data: + usage = Usage( + input=usage_data.get("input", 0) or 0, + output=usage_data.get("output", 0) or 0, + total=usage_data.get("total", 0) or 0, + unit=usage_data.get("unit"), + input_cost=usage_data.get("inputCost"), + output_cost=usage_data.get("outputCost"), + total_cost=usage_data.get("totalCost"), + ) + + body = CreateGenerationBody( + id=data.get("id"), + trace_id=data.get("trace_id"), + name=data.get("name"), + start_time=data.get("start_time"), + end_time=data.get("end_time"), + model=data.get("model"), + model_parameters=data.get("model_parameters"), + input=data.get("input"), + output=data.get("output"), + usage=usage, + metadata=data.get("metadata"), + level=data.get("level"), + status_message=data.get("status_message"), + parent_observation_id=data.get("parent_observation_id"), + version=data.get("version"), + completion_start_time=data.get("completion_start_time"), + ) + event = IngestionEvent_GenerationCreate( + body=body, + id=self._make_event_id(), + timestamp=self._now_iso(), + ) + self.langfuse_client.api.ingestion.batch(batch=[event]) logger.debug("LangFuse Generation created successfully") except Exception as e: raise ValueError(f"LangFuse Failed to create generation: {str(e)}") @@ -443,7 +530,7 @@ class LangFuseDataTrace(BaseTraceInstance): def get_project_key(self): try: - projects = self.langfuse_client.client.projects.get() + projects = self.langfuse_client.api.projects.get() return projects.data[0].id except Exception as e: logger.debug("LangFuse get project key failed: %s", str(e)) diff --git a/api/core/ops/tencent_trace/client.py b/api/core/ops/tencent_trace/client.py index c39093bf4c..be06ab4a36 100644 --- a/api/core/ops/tencent_trace/client.py +++ b/api/core/ops/tencent_trace/client.py @@ -26,7 +26,13 @@ from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExport from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor -from opentelemetry.semconv.resource import ResourceAttributes +from opentelemetry.semconv._incubating.attributes.deployment_attributes import ( # type: ignore[import-untyped] + DEPLOYMENT_ENVIRONMENT, +) +from opentelemetry.semconv._incubating.attributes.host_attributes import ( # type: ignore[import-untyped] + HOST_NAME, +) +from opentelemetry.semconv.attributes import service_attributes from opentelemetry.trace import SpanKind from opentelemetry.util.types import AttributeValue @@ -73,13 +79,13 @@ class TencentTraceClient: self.resource = Resource( attributes={ - ResourceAttributes.SERVICE_NAME: service_name, - ResourceAttributes.SERVICE_VERSION: f"dify-{dify_config.project.version}-{dify_config.COMMIT_SHA}", - ResourceAttributes.DEPLOYMENT_ENVIRONMENT: f"{dify_config.DEPLOY_ENV}-{dify_config.EDITION}", - ResourceAttributes.HOST_NAME: socket.gethostname(), - ResourceAttributes.TELEMETRY_SDK_LANGUAGE: "python", - ResourceAttributes.TELEMETRY_SDK_NAME: "opentelemetry", - ResourceAttributes.TELEMETRY_SDK_VERSION: _get_opentelemetry_sdk_version(), + service_attributes.SERVICE_NAME: service_name, + service_attributes.SERVICE_VERSION: f"dify-{dify_config.project.version}-{dify_config.COMMIT_SHA}", + DEPLOYMENT_ENVIRONMENT: f"{dify_config.DEPLOY_ENV}-{dify_config.EDITION}", + HOST_NAME: socket.gethostname(), + "telemetry.sdk.language": "python", + "telemetry.sdk.name": "opentelemetry", + "telemetry.sdk.version": _get_opentelemetry_sdk_version(), } ) # Prepare gRPC endpoint/metadata diff --git a/api/core/provider_manager.py b/api/core/provider_manager.py index 30933239f6..5d536e0e32 100644 --- a/api/core/provider_manager.py +++ b/api/core/provider_manager.py @@ -306,7 +306,7 @@ class ProviderManager: """ stmt = select(TenantDefaultModel).where( TenantDefaultModel.tenant_id == tenant_id, - TenantDefaultModel.model_type == model_type.to_origin_model_type(), + TenantDefaultModel.model_type == model_type, ) default_model = db.session.scalar(stmt) @@ -324,7 +324,7 @@ class ProviderManager: default_model = TenantDefaultModel( tenant_id=tenant_id, - model_type=model_type.to_origin_model_type(), + model_type=model_type, provider_name=available_model.provider.provider, model_name=available_model.model, ) @@ -391,7 +391,7 @@ class ProviderManager: raise ValueError(f"Model {model} does not exist.") stmt = select(TenantDefaultModel).where( TenantDefaultModel.tenant_id == tenant_id, - TenantDefaultModel.model_type == model_type.to_origin_model_type(), + TenantDefaultModel.model_type == model_type, ) default_model = db.session.scalar(stmt) @@ -405,7 +405,7 @@ class ProviderManager: # create default model default_model = TenantDefaultModel( tenant_id=tenant_id, - model_type=model_type.to_origin_model_type(), + model_type=model_type, provider_name=provider, model_name=model, ) @@ -626,9 +626,8 @@ class ProviderManager: if provider_record.provider_type != ProviderType.SYSTEM: continue - provider_quota_to_provider_record_dict[ProviderQuotaType.value_of(provider_record.quota_type)] = ( - provider_record - ) + if provider_record.quota_type is not None: + provider_quota_to_provider_record_dict[provider_record.quota_type] = provider_record for quota in configuration.quotas: if quota.quota_type in (ProviderQuotaType.TRIAL, ProviderQuotaType.PAID): @@ -641,7 +640,7 @@ class ProviderManager: # TODO: Use provider name with prefix after the data migration. provider_name=ModelProviderID(provider_name).provider_name, provider_type=ProviderType.SYSTEM, - quota_type=quota.quota_type, + quota_type=quota.quota_type, # type: ignore[arg-type] quota_limit=0, # type: ignore quota_used=0, is_valid=True, @@ -823,7 +822,7 @@ class ProviderManager: custom_model_configurations.append( CustomModelConfiguration( model=provider_model_record.model_name, - model_type=ModelType.value_of(provider_model_record.model_type), + model_type=provider_model_record.model_type, credentials=provider_model_credentials, current_credential_id=provider_model_record.credential_id, current_credential_name=provider_model_record.credential_name, @@ -921,9 +920,8 @@ class ProviderManager: if provider_record.provider_type != ProviderType.SYSTEM: continue - quota_type_to_provider_records_dict[ProviderQuotaType.value_of(provider_record.quota_type)] = ( - provider_record - ) + if provider_record.quota_type is not None: + quota_type_to_provider_records_dict[provider_record.quota_type] = provider_record # type: ignore[index] quota_configurations = [] if dify_config.EDITION == "CLOUD": @@ -1203,7 +1201,7 @@ class ProviderManager: model_settings.append( ModelSettings( model=provider_model_setting.model_name, - model_type=ModelType.value_of(provider_model_setting.model_type), + model_type=provider_model_setting.model_type, enabled=provider_model_setting.enabled, load_balancing_enabled=provider_model_setting.load_balancing_enabled, load_balancing_configs=load_balancing_configs if len(load_balancing_configs) > 1 else [], diff --git a/api/core/rag/datasource/keyword/jieba/jieba.py b/api/core/rag/datasource/keyword/jieba/jieba.py index b07dc108be..b8d5db7a43 100644 --- a/api/core/rag/datasource/keyword/jieba/jieba.py +++ b/api/core/rag/datasource/keyword/jieba/jieba.py @@ -97,13 +97,13 @@ class Jieba(BaseKeyword): documents = [] - segment_query_stmt = db.session.query(DocumentSegment).where( + segment_query_stmt = select(DocumentSegment).where( DocumentSegment.dataset_id == self.dataset.id, DocumentSegment.index_node_id.in_(sorted_chunk_indices) ) if document_ids_filter: segment_query_stmt = segment_query_stmt.where(DocumentSegment.document_id.in_(document_ids_filter)) - segments = db.session.execute(segment_query_stmt).scalars().all() + segments = db.session.scalars(segment_query_stmt).all() segment_map = {segment.index_node_id: segment for segment in segments} for chunk_index in sorted_chunk_indices: segment = segment_map.get(chunk_index) diff --git a/api/core/rag/datasource/retrieval_service.py b/api/core/rag/datasource/retrieval_service.py index cc6ec12c75..203a8588d6 100644 --- a/api/core/rag/datasource/retrieval_service.py +++ b/api/core/rag/datasource/retrieval_service.py @@ -432,10 +432,11 @@ class RetrievalService: # Batch query dataset documents dataset_documents = { doc.id: doc - for doc in db.session.query(DatasetDocument) - .where(DatasetDocument.id.in_(document_ids)) - .options(load_only(DatasetDocument.id, DatasetDocument.doc_form, DatasetDocument.dataset_id)) - .all() + for doc in db.session.scalars( + select(DatasetDocument) + .where(DatasetDocument.id.in_(document_ids)) + .options(load_only(DatasetDocument.id, DatasetDocument.doc_form, DatasetDocument.dataset_id)) + ).all() } valid_dataset_documents = {} diff --git a/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_on_qdrant_vector.py b/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_on_qdrant_vector.py index 3c1d5e015f..69c81d521c 100644 --- a/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_on_qdrant_vector.py +++ b/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_on_qdrant_vector.py @@ -426,11 +426,10 @@ class TidbOnQdrantVectorFactory(AbstractVectorFactory): TIDB_ON_QDRANT_API_KEY = f"{tidb_auth_binding.account}:{tidb_auth_binding.password}" else: - idle_tidb_auth_binding = ( - db.session.query(TidbAuthBinding) + idle_tidb_auth_binding = db.session.scalar( + select(TidbAuthBinding) .where(TidbAuthBinding.active == False, TidbAuthBinding.status == "ACTIVE") .limit(1) - .one_or_none() ) if idle_tidb_auth_binding: idle_tidb_auth_binding.active = True diff --git a/api/core/rag/datasource/vdb/vector_factory.py b/api/core/rag/datasource/vdb/vector_factory.py index 5a8d3a2f3f..26531eab88 100644 --- a/api/core/rag/datasource/vdb/vector_factory.py +++ b/api/core/rag/datasource/vdb/vector_factory.py @@ -277,7 +277,7 @@ class Vector: return self._vector_processor.search_by_vector(query_vector, **kwargs) def search_by_file(self, file_id: str, **kwargs: Any) -> list[Document]: - upload_file: UploadFile | None = db.session.query(UploadFile).where(UploadFile.id == file_id).first() + upload_file: UploadFile | None = db.session.get(UploadFile, file_id) if not upload_file: return [] diff --git a/api/core/rag/docstore/dataset_docstore.py b/api/core/rag/docstore/dataset_docstore.py index e5b794f80d..40f45953af 100644 --- a/api/core/rag/docstore/dataset_docstore.py +++ b/api/core/rag/docstore/dataset_docstore.py @@ -4,7 +4,7 @@ from collections.abc import Sequence from typing import Any from graphon.model_runtime.entities.model_entities import ModelType -from sqlalchemy import func, select +from sqlalchemy import delete, func, select from core.model_manager import ModelManager from core.rag.index_processor.constant.index_type import IndexTechniqueType @@ -63,10 +63,8 @@ class DatasetDocumentStore: return output def add_documents(self, docs: Sequence[Document], allow_update: bool = True, save_child: bool = False): - max_position = ( - db.session.query(func.max(DocumentSegment.position)) - .where(DocumentSegment.document_id == self._document_id) - .scalar() + max_position = db.session.scalar( + select(func.max(DocumentSegment.position)).where(DocumentSegment.document_id == self._document_id) ) if max_position is None: @@ -155,12 +153,14 @@ class DatasetDocumentStore: ) if save_child and doc.children: # delete the existing child chunks - db.session.query(ChildChunk).where( - ChildChunk.tenant_id == self._dataset.tenant_id, - ChildChunk.dataset_id == self._dataset.id, - ChildChunk.document_id == self._document_id, - ChildChunk.segment_id == segment_document.id, - ).delete() + db.session.execute( + delete(ChildChunk).where( + ChildChunk.tenant_id == self._dataset.tenant_id, + ChildChunk.dataset_id == self._dataset.id, + ChildChunk.document_id == self._document_id, + ChildChunk.segment_id == segment_document.id, + ) + ) # add new child chunks for position, child in enumerate(doc.children, start=1): child_segment = ChildChunk( diff --git a/api/core/rag/embedding/cached_embedding.py b/api/core/rag/embedding/cached_embedding.py index 3bdad00712..8d1c0da392 100644 --- a/api/core/rag/embedding/cached_embedding.py +++ b/api/core/rag/embedding/cached_embedding.py @@ -6,6 +6,7 @@ from typing import Any, cast import numpy as np from graphon.model_runtime.entities.model_entities import ModelPropertyKey from graphon.model_runtime.model_providers.__base.text_embedding_model import TextEmbeddingModel +from sqlalchemy import select from sqlalchemy.exc import IntegrityError from configs import dify_config @@ -31,14 +32,14 @@ class CacheEmbedding(Embeddings): embedding_queue_indices = [] for i, text in enumerate(texts): hash = helper.generate_text_hash(text) - embedding = ( - db.session.query(Embedding) - .filter_by( - model_name=self._model_instance.model_name, - hash=hash, - provider_name=self._model_instance.provider, + embedding = db.session.scalar( + select(Embedding) + .where( + Embedding.model_name == self._model_instance.model_name, + Embedding.hash == hash, + Embedding.provider_name == self._model_instance.provider, ) - .first() + .limit(1) ) if embedding: text_embeddings[i] = embedding.get_embedding() @@ -112,14 +113,14 @@ class CacheEmbedding(Embeddings): embedding_queue_indices = [] for i, multimodel_document in enumerate(multimodel_documents): file_id = multimodel_document["file_id"] - embedding = ( - db.session.query(Embedding) - .filter_by( - model_name=self._model_instance.model_name, - hash=file_id, - provider_name=self._model_instance.provider, + embedding = db.session.scalar( + select(Embedding) + .where( + Embedding.model_name == self._model_instance.model_name, + Embedding.hash == file_id, + Embedding.provider_name == self._model_instance.provider, ) - .first() + .limit(1) ) if embedding: multimodel_embeddings[i] = embedding.get_embedding() diff --git a/api/core/rag/extractor/notion_extractor.py b/api/core/rag/extractor/notion_extractor.py index 372af8fd94..aa36160711 100644 --- a/api/core/rag/extractor/notion_extractor.py +++ b/api/core/rag/extractor/notion_extractor.py @@ -4,6 +4,7 @@ import operator from typing import Any, cast import httpx +from sqlalchemy import update from configs import dify_config from core.rag.extractor.extractor_base import BaseExtractor @@ -346,9 +347,11 @@ class NotionExtractor(BaseExtractor): if data_source_info: data_source_info["last_edited_time"] = last_edited_time - db.session.query(DocumentModel).filter_by(id=document_model.id).update( - {DocumentModel.data_source_info: json.dumps(data_source_info)} - ) # type: ignore + db.session.execute( + update(DocumentModel) + .where(DocumentModel.id == document_model.id) + .values(data_source_info=json.dumps(data_source_info)) + ) db.session.commit() def get_notion_last_edited_time(self) -> str: diff --git a/api/core/rag/index_processor/index_processor_base.py b/api/core/rag/index_processor/index_processor_base.py index a435dfc46a..7d504fdb35 100644 --- a/api/core/rag/index_processor/index_processor_base.py +++ b/api/core/rag/index_processor/index_processor_base.py @@ -11,6 +11,7 @@ from typing import TYPE_CHECKING, Any, NotRequired, Optional from urllib.parse import unquote, urlparse import httpx +from sqlalchemy import select from typing_extensions import TypedDict from configs import dify_config @@ -200,7 +201,7 @@ class BaseIndexProcessor(ABC): # Get unique IDs for database query unique_upload_file_ids = list(set(upload_file_id_list)) - upload_files = db.session.query(UploadFile).where(UploadFile.id.in_(unique_upload_file_ids)).all() + upload_files = db.session.scalars(select(UploadFile).where(UploadFile.id.in_(unique_upload_file_ids))).all() # Create a mapping from ID to UploadFile for quick lookup upload_file_map = {upload_file.id: upload_file for upload_file in upload_files} @@ -312,7 +313,7 @@ class BaseIndexProcessor(ABC): """ from services.file_service import FileService - tool_file = db.session.query(ToolFile).where(ToolFile.id == tool_file_id).first() + tool_file = db.session.get(ToolFile, tool_file_id) if not tool_file: return None blob = storage.load_once(tool_file.file_key) diff --git a/api/core/rag/index_processor/processor/paragraph_index_processor.py b/api/core/rag/index_processor/processor/paragraph_index_processor.py index 5c10ffbf2d..22ab492cbf 100644 --- a/api/core/rag/index_processor/processor/paragraph_index_processor.py +++ b/api/core/rag/index_processor/processor/paragraph_index_processor.py @@ -18,6 +18,7 @@ from graphon.model_runtime.entities.message_entities import ( UserPromptMessage, ) from graphon.model_runtime.entities.model_entities import ModelFeature, ModelType +from sqlalchemy import select from core.app.file_access import DatabaseFileAccessController from core.app.llm import deduct_llm_quota @@ -145,14 +146,12 @@ class ParagraphIndexProcessor(BaseIndexProcessor): if delete_summaries: if node_ids: # Find segments by index_node_id - segments = ( - db.session.query(DocumentSegment) - .filter( + segments = db.session.scalars( + select(DocumentSegment).where( DocumentSegment.dataset_id == dataset.id, DocumentSegment.index_node_id.in_(node_ids), ) - .all() - ) + ).all() segment_ids = [segment.id for segment in segments] if segment_ids: SummaryIndexService.delete_summaries_for_segments(dataset, segment_ids) @@ -537,11 +536,9 @@ class ParagraphIndexProcessor(BaseIndexProcessor): # Get unique IDs for database query unique_upload_file_ids = list(set(upload_file_id_list)) - upload_files = ( - db.session.query(UploadFile) - .where(UploadFile.id.in_(unique_upload_file_ids), UploadFile.tenant_id == tenant_id) - .all() - ) + upload_files = db.session.scalars( + select(UploadFile).where(UploadFile.id.in_(unique_upload_file_ids), UploadFile.tenant_id == tenant_id) + ).all() # Create File objects from UploadFile records file_objects = [] diff --git a/api/core/rag/index_processor/processor/parent_child_index_processor.py b/api/core/rag/index_processor/processor/parent_child_index_processor.py index 70504e6e50..1c5e02e9c8 100644 --- a/api/core/rag/index_processor/processor/parent_child_index_processor.py +++ b/api/core/rag/index_processor/processor/parent_child_index_processor.py @@ -6,6 +6,8 @@ import uuid from collections.abc import Mapping from typing import Any +from sqlalchemy import delete, select + from configs import dify_config from core.db.session_factory import session_factory from core.entities.knowledge_entities import PreviewDetail @@ -177,17 +179,16 @@ class ParentChildIndexProcessor(BaseIndexProcessor): child_node_ids = precomputed_child_node_ids else: # Fallback to original query (may fail if segments are already deleted) - child_node_ids = ( - db.session.query(ChildChunk.index_node_id) + rows = db.session.execute( + select(ChildChunk.index_node_id) .join(DocumentSegment, ChildChunk.segment_id == DocumentSegment.id) .where( DocumentSegment.dataset_id == dataset.id, DocumentSegment.index_node_id.in_(node_ids), ChildChunk.dataset_id == dataset.id, ) - .all() - ) - child_node_ids = [child_node_id[0] for child_node_id in child_node_ids if child_node_id[0]] + ).all() + child_node_ids = [row[0] for row in rows if row[0]] # Delete from vector index if child_node_ids: @@ -195,18 +196,22 @@ class ParentChildIndexProcessor(BaseIndexProcessor): # Delete from database if delete_child_chunks and child_node_ids: - db.session.query(ChildChunk).where( - ChildChunk.dataset_id == dataset.id, ChildChunk.index_node_id.in_(child_node_ids) - ).delete(synchronize_session=False) + db.session.execute( + delete(ChildChunk).where( + ChildChunk.dataset_id == dataset.id, ChildChunk.index_node_id.in_(child_node_ids) + ) + ) db.session.commit() else: vector.delete() if delete_child_chunks: # Use existing compound index: (tenant_id, dataset_id, ...) - db.session.query(ChildChunk).where( - ChildChunk.tenant_id == dataset.tenant_id, ChildChunk.dataset_id == dataset.id - ).delete(synchronize_session=False) + db.session.execute( + delete(ChildChunk).where( + ChildChunk.tenant_id == dataset.tenant_id, ChildChunk.dataset_id == dataset.id + ) + ) db.session.commit() def retrieve( diff --git a/api/core/rag/rerank/rerank_model.py b/api/core/rag/rerank/rerank_model.py index 211a9f5c5c..8283be19f9 100644 --- a/api/core/rag/rerank/rerank_model.py +++ b/api/core/rag/rerank/rerank_model.py @@ -134,9 +134,7 @@ class RerankModelRunner(BaseRerankRunner): ): if document.metadata.get("doc_type") == DocType.IMAGE: # Query file info within db.session context to ensure thread-safe access - upload_file = ( - db.session.query(UploadFile).where(UploadFile.id == document.metadata["doc_id"]).first() - ) + upload_file = db.session.get(UploadFile, document.metadata["doc_id"]) if upload_file: blob = storage.load_once(upload_file.key) document_file_base64 = base64.b64encode(blob).decode() @@ -169,7 +167,7 @@ class RerankModelRunner(BaseRerankRunner): return rerank_result, unique_documents elif query_type == QueryType.IMAGE_QUERY: # Query file info within db.session context to ensure thread-safe access - upload_file = db.session.query(UploadFile).where(UploadFile.id == query).first() + upload_file = db.session.get(UploadFile, query) if upload_file: blob = storage.load_once(upload_file.key) file_query = base64.b64encode(blob).decode() diff --git a/api/core/rag/retrieval/dataset_retrieval.py b/api/core/rag/retrieval/dataset_retrieval.py index 1abea6639e..593e1f1420 100644 --- a/api/core/rag/retrieval/dataset_retrieval.py +++ b/api/core/rag/retrieval/dataset_retrieval.py @@ -1340,7 +1340,7 @@ class DatasetRetrieval: metadata_filtering_conditions: MetadataFilteringCondition | None, inputs: dict, ) -> tuple[dict[str, list[str]] | None, MetadataCondition | None]: - document_query = db.session.query(DatasetDocument).where( + document_query = select(DatasetDocument).where( DatasetDocument.dataset_id.in_(dataset_ids), DatasetDocument.indexing_status == "completed", DatasetDocument.enabled == True, @@ -1411,7 +1411,7 @@ class DatasetRetrieval: document_query = document_query.where(and_(*filters)) else: document_query = document_query.where(or_(*filters)) - documents = document_query.all() + documents = db.session.scalars(document_query).all() # group by dataset_id metadata_filter_document_ids = defaultdict(list) if documents else None # type: ignore for document in documents: diff --git a/api/enterprise/telemetry/exporter.py b/api/enterprise/telemetry/exporter.py index b2f860764f..80959514f2 100644 --- a/api/enterprise/telemetry/exporter.py +++ b/api/enterprise/telemetry/exporter.py @@ -27,7 +27,10 @@ from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.sdk.trace.sampling import ParentBasedTraceIdRatio -from opentelemetry.semconv.resource import ResourceAttributes +from opentelemetry.semconv._incubating.attributes.host_attributes import ( # type: ignore[import-untyped] + HOST_NAME, +) +from opentelemetry.semconv.attributes import service_attributes from opentelemetry.trace import SpanContext, TraceFlags from opentelemetry.util.types import Attributes, AttributeValue @@ -114,8 +117,8 @@ class EnterpriseExporter: resource = Resource( attributes={ - ResourceAttributes.SERVICE_NAME: service_name, - ResourceAttributes.HOST_NAME: socket.gethostname(), + service_attributes.SERVICE_NAME: service_name, + HOST_NAME: socket.gethostname(), } ) sampler = ParentBasedTraceIdRatio(sampling_rate) diff --git a/api/events/event_handlers/update_provider_when_message_created.py b/api/events/event_handlers/update_provider_when_message_created.py index 1ddcc8f792..f68cdaadde 100644 --- a/api/events/event_handlers/update_provider_when_message_created.py +++ b/api/events/event_handlers/update_provider_when_message_created.py @@ -157,7 +157,7 @@ def handle(sender: Message, **kwargs): tenant_id=tenant_id, provider_name=ModelProviderID(model_config.provider).provider_name, provider_type=ProviderType.SYSTEM.value, - quota_type=provider_configuration.system_configuration.current_quota_type.value, + quota_type=provider_configuration.system_configuration.current_quota_type, ), values=_ProviderUpdateValues(quota_used=Provider.quota_used + used_quota, last_used=current_time), additional_filters=_ProviderUpdateAdditionalFilters( diff --git a/api/extensions/ext_sentry.py b/api/extensions/ext_sentry.py index 651f8ed898..5cc58f27c4 100644 --- a/api/extensions/ext_sentry.py +++ b/api/extensions/ext_sentry.py @@ -6,15 +6,24 @@ def init_app(app: DifyApp): if dify_config.SENTRY_DSN: import sentry_sdk from graphon.model_runtime.errors.invoke import InvokeRateLimitError - from langfuse import parse_error from sentry_sdk.integrations.celery import CeleryIntegration from sentry_sdk.integrations.flask import FlaskIntegration from werkzeug.exceptions import HTTPException + try: + from langfuse._utils import parse_error + + _langfuse_error_response = parse_error.defaultErrorResponse + except (ImportError, AttributeError): + _langfuse_error_response = ( + "Unexpected error occurred. Please check your request" + " and contact support: https://langfuse.com/support." + ) + def before_send(event, hint): if "exc_info" in hint: _, exc_value, _ = hint["exc_info"] - if parse_error.defaultErrorResponse in str(exc_value): + if _langfuse_error_response in str(exc_value): return None return event @@ -27,7 +36,7 @@ def init_app(app: DifyApp): ValueError, FileNotFoundError, InvokeRateLimitError, - parse_error.defaultErrorResponse, + _langfuse_error_response, ], traces_sample_rate=dify_config.SENTRY_TRACES_SAMPLE_RATE, profiles_sample_rate=dify_config.SENTRY_PROFILES_SAMPLE_RATE, diff --git a/api/extensions/otel/instrumentation.py b/api/extensions/otel/instrumentation.py index b73ba8df8c..0a70f6ebe9 100644 --- a/api/extensions/otel/instrumentation.py +++ b/api/extensions/otel/instrumentation.py @@ -1,5 +1,7 @@ import contextlib import logging +from collections.abc import Callable +from typing import Protocol, cast import flask from opentelemetry.instrumentation.celery import CeleryInstrumentor @@ -21,6 +23,38 @@ from extensions.otel.runtime import is_celery_worker logger = logging.getLogger(__name__) +class SupportsInstrument(Protocol): + def instrument(self, **kwargs: object) -> None: ... + + +class SupportsFlaskInstrumentor(Protocol): + def instrument_app( + self, app: DifyApp, response_hook: Callable[[Span, str, list], None] | None = None, **kwargs: object + ) -> None: ... + + +# Some OpenTelemetry instrumentor constructors are typed loosely enough that +# pyrefly infers `NoneType`. Narrow the instances to just the methods we use +# while leaving runtime behavior unchanged. +def _new_celery_instrumentor() -> SupportsInstrument: + return cast( + SupportsInstrument, + CeleryInstrumentor(tracer_provider=get_tracer_provider(), meter_provider=get_meter_provider()), + ) + + +def _new_httpx_instrumentor() -> SupportsInstrument: + return cast(SupportsInstrument, HTTPXClientInstrumentor()) + + +def _new_redis_instrumentor() -> SupportsInstrument: + return cast(SupportsInstrument, RedisInstrumentor()) + + +def _new_sqlalchemy_instrumentor() -> SupportsInstrument: + return cast(SupportsInstrument, SQLAlchemyInstrumentor()) + + class ExceptionLoggingHandler(logging.Handler): """ Handler that records exceptions to the current OpenTelemetry span. @@ -97,7 +131,7 @@ def init_flask_instrumentor(app: DifyApp) -> None: from opentelemetry.instrumentation.flask import FlaskInstrumentor - instrumentor = FlaskInstrumentor() + instrumentor = cast(SupportsFlaskInstrumentor, FlaskInstrumentor()) if dify_config.DEBUG: logger.info("Initializing Flask instrumentor") instrumentor.instrument_app(app, response_hook=response_hook) @@ -106,21 +140,21 @@ def init_flask_instrumentor(app: DifyApp) -> None: def init_sqlalchemy_instrumentor(app: DifyApp) -> None: with app.app_context(): engines = list(app.extensions["sqlalchemy"].engines.values()) - SQLAlchemyInstrumentor().instrument(enable_commenter=True, engines=engines) + _new_sqlalchemy_instrumentor().instrument(enable_commenter=True, engines=engines) def init_redis_instrumentor() -> None: - RedisInstrumentor().instrument() + _new_redis_instrumentor().instrument() def init_httpx_instrumentor() -> None: - HTTPXClientInstrumentor().instrument() + _new_httpx_instrumentor().instrument() def init_instruments(app: DifyApp) -> None: if not is_celery_worker(): init_flask_instrumentor(app) - CeleryInstrumentor(tracer_provider=get_tracer_provider(), meter_provider=get_meter_provider()).instrument() + _new_celery_instrumentor().instrument() instrument_exception_logging() init_sqlalchemy_instrumentor(app) diff --git a/api/models/provider.py b/api/models/provider.py index afeee20b1e..8270961b31 100644 --- a/api/models/provider.py +++ b/api/models/provider.py @@ -6,6 +6,7 @@ from functools import cached_property from uuid import uuid4 import sqlalchemy as sa +from graphon.model_runtime.entities.model_entities import ModelType from sqlalchemy import DateTime, String, func, select, text from sqlalchemy.orm import Mapped, mapped_column @@ -13,7 +14,7 @@ from libs.uuid_utils import uuidv7 from .base import TypeBase from .engine import db -from .enums import CredentialSourceType, PaymentStatus +from .enums import CredentialSourceType, PaymentStatus, ProviderQuotaType from .types import EnumText, LongText, StringUUID @@ -29,24 +30,6 @@ class ProviderType(StrEnum): raise ValueError(f"No matching enum found for value '{value}'") -class ProviderQuotaType(StrEnum): - PAID = auto() - """hosted paid quota""" - - FREE = auto() - """third-party free quota""" - - TRIAL = auto() - """hosted trial quota""" - - @staticmethod - def value_of(value: str) -> ProviderQuotaType: - for member in ProviderQuotaType: - if member.value == value: - return member - raise ValueError(f"No matching enum found for value '{value}'") - - class Provider(TypeBase): """ Provider model representing the API providers and their configurations. @@ -77,7 +60,9 @@ class Provider(TypeBase): last_used: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, init=False) credential_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) - quota_type: Mapped[str | None] = mapped_column(String(40), nullable=True, server_default=text("''"), default="") + quota_type: Mapped[ProviderQuotaType | None] = mapped_column( + EnumText(ProviderQuotaType, length=40), nullable=True, server_default=text("''"), default=None + ) quota_limit: Mapped[int | None] = mapped_column(sa.BigInteger, nullable=True, default=None) quota_used: Mapped[int | None] = mapped_column(sa.BigInteger, nullable=True, default=0) @@ -147,7 +132,7 @@ class ProviderModel(TypeBase): tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) provider_name: Mapped[str] = mapped_column(String(255), nullable=False) model_name: Mapped[str] = mapped_column(String(255), nullable=False) - model_type: Mapped[str] = mapped_column(String(40), nullable=False) + model_type: Mapped[ModelType] = mapped_column(EnumText(ModelType, length=40), nullable=False) credential_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) is_valid: Mapped[bool] = mapped_column(sa.Boolean, nullable=False, server_default=text("false"), default=False) created_at: Mapped[datetime] = mapped_column( @@ -189,7 +174,7 @@ class TenantDefaultModel(TypeBase): tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) provider_name: Mapped[str] = mapped_column(String(255), nullable=False) model_name: Mapped[str] = mapped_column(String(255), nullable=False) - model_type: Mapped[str] = mapped_column(String(40), nullable=False) + model_type: Mapped[ModelType] = mapped_column(EnumText(ModelType, length=40), nullable=False) created_at: Mapped[datetime] = mapped_column( DateTime, nullable=False, server_default=func.current_timestamp(), init=False ) @@ -269,7 +254,7 @@ class ProviderModelSetting(TypeBase): tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) provider_name: Mapped[str] = mapped_column(String(255), nullable=False) model_name: Mapped[str] = mapped_column(String(255), nullable=False) - model_type: Mapped[str] = mapped_column(String(40), nullable=False) + model_type: Mapped[ModelType] = mapped_column(EnumText(ModelType, length=40), nullable=False) enabled: Mapped[bool] = mapped_column(sa.Boolean, nullable=False, server_default=text("true"), default=True) load_balancing_enabled: Mapped[bool] = mapped_column( sa.Boolean, nullable=False, server_default=text("false"), default=False @@ -299,7 +284,7 @@ class LoadBalancingModelConfig(TypeBase): tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) provider_name: Mapped[str] = mapped_column(String(255), nullable=False) model_name: Mapped[str] = mapped_column(String(255), nullable=False) - model_type: Mapped[str] = mapped_column(String(40), nullable=False) + model_type: Mapped[ModelType] = mapped_column(EnumText(ModelType, length=40), nullable=False) name: Mapped[str] = mapped_column(String(255), nullable=False) encrypted_config: Mapped[str | None] = mapped_column(LongText, nullable=True, default=None) credential_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True, default=None) @@ -364,7 +349,7 @@ class ProviderModelCredential(TypeBase): tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) provider_name: Mapped[str] = mapped_column(String(255), nullable=False) model_name: Mapped[str] = mapped_column(String(255), nullable=False) - model_type: Mapped[str] = mapped_column(String(40), nullable=False) + model_type: Mapped[ModelType] = mapped_column(EnumText(ModelType, length=40), nullable=False) credential_name: Mapped[str] = mapped_column(String(255), nullable=False) encrypted_config: Mapped[str] = mapped_column(LongText, nullable=False) created_at: Mapped[datetime] = mapped_column( diff --git a/api/models/types.py b/api/models/types.py index f8369dab9e..98084563be 100644 --- a/api/models/types.py +++ b/api/models/types.py @@ -144,8 +144,8 @@ class EnumText(TypeDecorator[_E | None], Generic[_E]): return dialect.type_descriptor(VARCHAR(self._length)) def process_result_value(self, value: str | None, dialect: Dialect) -> _E | None: - if value is None: - return value + if value is None or value == "": + return None # Type annotation guarantees value is str at this point return self._enum_class(value) diff --git a/api/pyproject.toml b/api/pyproject.toml index f737d0699f..a09b474bf5 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -33,7 +33,7 @@ dependencies = [ "httpx[socks]~=0.28.0", "jieba==0.42.1", "json-repair>=0.55.1", - "langfuse~=2.51.3", + "langfuse>=3.0.0,<5.0.0", "langsmith~=0.7.16", "markdown~=3.10.2", "mlflow-skinny>=3.0.0", @@ -41,23 +41,23 @@ dependencies = [ "openpyxl~=3.1.5", "opik~=1.10.37", "litellm==1.82.6", # Pinned to avoid madoka dependency issue - "opentelemetry-api==1.28.0", - "opentelemetry-distro==0.49b0", - "opentelemetry-exporter-otlp==1.28.0", - "opentelemetry-exporter-otlp-proto-common==1.28.0", - "opentelemetry-exporter-otlp-proto-grpc==1.28.0", - "opentelemetry-exporter-otlp-proto-http==1.28.0", - "opentelemetry-instrumentation==0.49b0", - "opentelemetry-instrumentation-celery==0.49b0", - "opentelemetry-instrumentation-flask==0.49b0", - "opentelemetry-instrumentation-httpx==0.49b0", - "opentelemetry-instrumentation-redis==0.49b0", - "opentelemetry-instrumentation-sqlalchemy==0.49b0", + "opentelemetry-api==1.40.0", + "opentelemetry-distro==0.61b0", + "opentelemetry-exporter-otlp==1.40.0", + "opentelemetry-exporter-otlp-proto-common==1.40.0", + "opentelemetry-exporter-otlp-proto-grpc==1.40.0", + "opentelemetry-exporter-otlp-proto-http==1.40.0", + "opentelemetry-instrumentation==0.61b0", + "opentelemetry-instrumentation-celery==0.61b0", + "opentelemetry-instrumentation-flask==0.61b0", + "opentelemetry-instrumentation-httpx==0.61b0", + "opentelemetry-instrumentation-redis==0.61b0", + "opentelemetry-instrumentation-sqlalchemy==0.61b0", "opentelemetry-propagator-b3==1.40.0", - "opentelemetry-proto==1.28.0", - "opentelemetry-sdk==1.28.0", - "opentelemetry-semantic-conventions==0.49b0", - "opentelemetry-util-http==0.49b0", + "opentelemetry-proto==1.40.0", + "opentelemetry-sdk==1.40.0", + "opentelemetry-semantic-conventions==0.61b0", + "opentelemetry-util-http==0.61b0", "pandas[excel,output-formatting,performance]~=3.0.1", "psycogreen~=1.0.2", "psycopg2-binary~=2.9.6", diff --git a/api/services/account_service.py b/api/services/account_service.py index bd520f54cf..cc8ef08857 100644 --- a/api/services/account_service.py +++ b/api/services/account_service.py @@ -7,9 +7,19 @@ from datetime import UTC, datetime, timedelta from hashlib import sha256 from typing import Any, cast -from pydantic import BaseModel +from pydantic import BaseModel, TypeAdapter from sqlalchemy import func, select from sqlalchemy.orm import Session +from typing_extensions import TypedDict + + +class InvitationData(TypedDict): + account_id: str + email: str + workspace_id: str + + +_invitation_adapter: TypeAdapter[InvitationData] = TypeAdapter(InvitationData) from werkzeug.exceptions import Unauthorized from configs import dify_config @@ -1571,7 +1581,7 @@ class RegisterService: @classmethod def get_invitation_by_token( cls, token: str, workspace_id: str | None = None, email: str | None = None - ) -> dict[str, str] | None: + ) -> InvitationData | None: if workspace_id is not None and email is not None: email_hash = sha256(email.encode()).hexdigest() cache_key = f"member_invite_token:{workspace_id}, {email_hash}:{token}" @@ -1590,7 +1600,7 @@ class RegisterService: if not data: return None - invitation: dict = json.loads(data) + invitation = _invitation_adapter.validate_json(data) return invitation @classmethod diff --git a/api/services/message_service.py b/api/services/message_service.py index e5389ef659..a04f9cbe01 100644 --- a/api/services/message_service.py +++ b/api/services/message_service.py @@ -1,8 +1,8 @@ -import json from collections.abc import Sequence from typing import Union from graphon.model_runtime.entities.model_entities import ModelType +from pydantic import TypeAdapter from sqlalchemy.orm import sessionmaker from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfigManager @@ -17,7 +17,7 @@ from extensions.ext_database import db from libs.infinite_scroll_pagination import InfiniteScrollPagination from models import Account from models.enums import FeedbackFromSource, FeedbackRating -from models.model import App, AppMode, AppModelConfig, EndUser, Message, MessageFeedback +from models.model import App, AppMode, AppModelConfig, AppModelConfigDict, EndUser, Message, MessageFeedback from repositories.execution_extra_content_repository import ExecutionExtraContentRepository from repositories.sqlalchemy_execution_extra_content_repository import ( SQLAlchemyExecutionExtraContentRepository, @@ -31,6 +31,8 @@ from services.errors.message import ( ) from services.workflow_service import WorkflowService +_app_model_config_adapter: TypeAdapter[AppModelConfigDict] = TypeAdapter(AppModelConfigDict) + def _create_execution_extra_content_repository() -> ExecutionExtraContentRepository: session_maker = sessionmaker(bind=db.engine, expire_on_commit=False) @@ -286,7 +288,9 @@ class MessageService: .first() ) else: - conversation_override_model_configs = json.loads(conversation.override_model_configs) + conversation_override_model_configs = _app_model_config_adapter.validate_json( + conversation.override_model_configs + ) app_model_config = AppModelConfig( app_id=app_model.id, ) diff --git a/api/services/model_load_balancing_service.py b/api/services/model_load_balancing_service.py index 91cca5cb6d..752d3002d9 100644 --- a/api/services/model_load_balancing_service.py +++ b/api/services/model_load_balancing_service.py @@ -1,7 +1,6 @@ import json import logging -from json import JSONDecodeError -from typing import Union +from typing import Any, Union from graphon.model_runtime.entities.model_entities import ModelType from graphon.model_runtime.entities.provider_entities import ( @@ -116,7 +115,7 @@ class ModelLoadBalancingService: .where( LoadBalancingModelConfig.tenant_id == tenant_id, LoadBalancingModelConfig.provider_name == provider_configuration.provider.provider, - LoadBalancingModelConfig.model_type == model_type_enum.to_origin_model_type(), + LoadBalancingModelConfig.model_type == model_type_enum, LoadBalancingModelConfig.model_name == model, or_( LoadBalancingModelConfig.credential_source_type == credential_source_type, @@ -168,10 +167,10 @@ class ModelLoadBalancingService: try: if load_balancing_config.encrypted_config: - credentials: dict[str, object] = json.loads(load_balancing_config.encrypted_config) + credentials: dict[str, Any] = json.loads(load_balancing_config.encrypted_config) else: credentials = {} - except JSONDecodeError: + except (json.JSONDecodeError, ValueError): credentials = {} # Get provider credential secret variables @@ -241,7 +240,7 @@ class ModelLoadBalancingService: .where( LoadBalancingModelConfig.tenant_id == tenant_id, LoadBalancingModelConfig.provider_name == provider_configuration.provider.provider, - LoadBalancingModelConfig.model_type == model_type_enum.to_origin_model_type(), + LoadBalancingModelConfig.model_type == model_type_enum, LoadBalancingModelConfig.model_name == model, LoadBalancingModelConfig.id == config_id, ) @@ -256,7 +255,7 @@ class ModelLoadBalancingService: credentials = json.loads(load_balancing_model_config.encrypted_config) else: credentials = {} - except JSONDecodeError: + except (json.JSONDecodeError, ValueError): credentials = {} # Get credential form schemas from model credential schema or provider credential schema @@ -289,7 +288,7 @@ class ModelLoadBalancingService: inherit_config = LoadBalancingModelConfig( tenant_id=tenant_id, provider_name=provider, - model_type=model_type.to_origin_model_type(), + model_type=model_type, model_name=model, name="__inherit__", ) @@ -329,7 +328,7 @@ class ModelLoadBalancingService: select(LoadBalancingModelConfig).where( LoadBalancingModelConfig.tenant_id == tenant_id, LoadBalancingModelConfig.provider_name == provider_configuration.provider.provider, - LoadBalancingModelConfig.model_type == model_type_enum.to_origin_model_type(), + LoadBalancingModelConfig.model_type == model_type_enum, LoadBalancingModelConfig.model_name == model, ) ).all() @@ -369,7 +368,7 @@ class ModelLoadBalancingService: tenant_id=tenant_id, provider_name=provider_configuration.provider.provider, model_name=model, - model_type=model_type_enum.to_origin_model_type(), + model_type=model_type_enum, ) .first() ) @@ -433,7 +432,7 @@ class ModelLoadBalancingService: load_balancing_model_config = LoadBalancingModelConfig( tenant_id=tenant_id, provider_name=provider_configuration.provider.provider, - model_type=model_type_enum.to_origin_model_type(), + model_type=model_type_enum, model_name=model, name=credential_record.credential_name, encrypted_config=credential_record.encrypted_config, @@ -461,7 +460,7 @@ class ModelLoadBalancingService: load_balancing_model_config = LoadBalancingModelConfig( tenant_id=tenant_id, provider_name=provider_configuration.provider.provider, - model_type=model_type_enum.to_origin_model_type(), + model_type=model_type_enum, model_name=model, name=name, encrypted_config=json.dumps(credentials), @@ -516,7 +515,7 @@ class ModelLoadBalancingService: .where( LoadBalancingModelConfig.tenant_id == tenant_id, LoadBalancingModelConfig.provider_name == provider, - LoadBalancingModelConfig.model_type == model_type_enum.to_origin_model_type(), + LoadBalancingModelConfig.model_type == model_type_enum, LoadBalancingModelConfig.model_name == model, LoadBalancingModelConfig.id == config_id, ) @@ -575,7 +574,7 @@ class ModelLoadBalancingService: original_credentials = json.loads(load_balancing_model_config.encrypted_config) else: original_credentials = {} - except JSONDecodeError: + except (json.JSONDecodeError, ValueError): original_credentials = {} # encrypt credentials diff --git a/api/services/plugin/plugin_migration.py b/api/services/plugin/plugin_migration.py index df5fa3e233..1562d4e696 100644 --- a/api/services/plugin/plugin_migration.py +++ b/api/services/plugin/plugin_migration.py @@ -12,7 +12,9 @@ import click import sqlalchemy as sa import tqdm from flask import Flask, current_app +from pydantic import TypeAdapter from sqlalchemy.orm import Session +from typing_extensions import TypedDict from core.agent.entities import AgentToolEntity from core.helper import marketplace @@ -33,6 +35,14 @@ logger = logging.getLogger(__name__) excluded_providers = ["time", "audio", "code", "webscraper"] +class _TenantPluginRecord(TypedDict): + tenant_id: str + plugins: list[str] + + +_tenant_plugin_adapter: TypeAdapter[_TenantPluginRecord] = TypeAdapter(_TenantPluginRecord) + + class PluginMigration: @classmethod def extract_plugins(cls, filepath: str, workers: int): @@ -308,9 +318,8 @@ class PluginMigration: logger.info("Extracting unique plugins from %s", extracted_plugins) with open(extracted_plugins) as f: for line in f: - data = json.loads(line) - new_plugin_ids = data.get("plugins", []) - for plugin_id in new_plugin_ids: + data = _tenant_plugin_adapter.validate_json(line) + for plugin_id in data["plugins"]: if plugin_id not in plugin_ids: plugin_ids.append(plugin_id) @@ -381,21 +390,23 @@ class PluginMigration: Read line by line, and install plugins for each tenant. """ for line in f: - data = json.loads(line) - tenant_id = data.get("tenant_id") - plugin_ids = data.get("plugins", []) - current_not_installed = { - "tenant_id": tenant_id, - "plugin_not_exist": [], - } + data = _tenant_plugin_adapter.validate_json(line) + tenant_id = data["tenant_id"] + plugin_ids = data["plugins"] + plugin_not_exist: list[str] = [] # get plugin unique identifier for plugin_id in plugin_ids: unique_identifier = plugins.get(plugin_id) if unique_identifier: - current_not_installed["plugin_not_exist"].append(plugin_id) + plugin_not_exist.append(plugin_id) - if current_not_installed["plugin_not_exist"]: - not_installed.append(current_not_installed) + if plugin_not_exist: + not_installed.append( + { + "tenant_id": tenant_id, + "plugin_not_exist": plugin_not_exist, + } + ) thread_pool.submit(install, tenant_id, plugin_ids) diff --git a/api/services/retention/workflow_run/restore_archived_workflow_run.py b/api/services/retention/workflow_run/restore_archived_workflow_run.py index 64dad7ba52..c8362738ee 100644 --- a/api/services/retention/workflow_run/restore_archived_workflow_run.py +++ b/api/services/retention/workflow_run/restore_archived_workflow_run.py @@ -6,7 +6,6 @@ back to the database. """ import io -import json import logging import time import zipfile @@ -17,8 +16,23 @@ from datetime import datetime from typing import Any, cast import click +from pydantic import TypeAdapter from sqlalchemy.dialects.postgresql import insert as pg_insert from sqlalchemy.engine import CursorResult +from typing_extensions import TypedDict + + +class _TableInfo(TypedDict, total=False): + row_count: int + + +class ArchiveManifest(TypedDict, total=False): + tables: dict[str, _TableInfo] + schema_version: str + + +_manifest_adapter: TypeAdapter[ArchiveManifest] = TypeAdapter(ArchiveManifest) + from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker from extensions.ext_database import db @@ -239,12 +253,12 @@ class WorkflowRunRestore: return self.workflow_run_repo @staticmethod - def _load_manifest_from_zip(archive: zipfile.ZipFile) -> dict[str, Any]: + def _load_manifest_from_zip(archive: zipfile.ZipFile) -> ArchiveManifest: try: data = archive.read("manifest.json") except KeyError as e: raise ValueError("manifest.json missing from archive bundle") from e - return json.loads(data.decode("utf-8")) + return _manifest_adapter.validate_json(data) def _restore_table_records( self, @@ -332,7 +346,7 @@ class WorkflowRunRestore: return result - def _get_schema_version(self, manifest: dict[str, Any]) -> str: + def _get_schema_version(self, manifest: ArchiveManifest) -> str: schema_version = manifest.get("schema_version") if not schema_version: logger.warning("Manifest missing schema_version; defaulting to 1.0") diff --git a/api/services/tools/tools_transform_service.py b/api/services/tools/tools_transform_service.py index b276146066..7cd61e3162 100644 --- a/api/services/tools/tools_transform_service.py +++ b/api/services/tools/tools_transform_service.py @@ -3,7 +3,7 @@ import logging from collections.abc import Mapping from typing import Any, Union -from pydantic import ValidationError +from pydantic import TypeAdapter, ValidationError from yarl import URL from configs import dify_config @@ -31,6 +31,8 @@ from services.plugin.plugin_service import PluginService logger = logging.getLogger(__name__) +_mcp_tools_adapter: TypeAdapter[list[MCPTool]] = TypeAdapter(list[MCPTool]) + class ToolTransformService: _MCP_SCHEMA_TYPE_RESOLUTION_MAX_DEPTH = 10 @@ -53,7 +55,7 @@ class ToolTransformService: if isinstance(icon, str): return json.loads(icon) return icon - except Exception: + except (json.JSONDecodeError, ValueError): return {"background": "#252525", "content": "\ud83d\ude01"} elif provider_type == ToolProviderType.MCP: return icon @@ -247,8 +249,8 @@ class ToolTransformService: response = provider_entity.to_api_response(user_name=user_name, include_sensitive=include_sensitive) try: - mcp_tools = [MCPTool(**tool) for tool in json.loads(db_provider.tools)] - except (ValidationError, json.JSONDecodeError): + mcp_tools = _mcp_tools_adapter.validate_json(db_provider.tools) + except (ValidationError, ValueError): mcp_tools = [] # Add additional fields specific to the transform response["id"] = db_provider.server_identifier if not for_list else db_provider.id diff --git a/api/services/trigger/trigger_subscription_builder_service.py b/api/services/trigger/trigger_subscription_builder_service.py index 37f852da3e..889717df72 100644 --- a/api/services/trigger/trigger_subscription_builder_service.py +++ b/api/services/trigger/trigger_subscription_builder_service.py @@ -1,4 +1,3 @@ -import json import logging import uuid from collections.abc import Mapping @@ -7,6 +6,7 @@ from datetime import datetime from typing import Any from flask import Request, Response +from pydantic import TypeAdapter from core.plugin.entities.plugin_daemon import CredentialType from core.plugin.entities.request import TriggerDispatchResponse @@ -29,6 +29,8 @@ from services.trigger.trigger_provider_service import TriggerProviderService logger = logging.getLogger(__name__) +_request_logs_adapter: TypeAdapter[list[RequestLog]] = TypeAdapter(list[RequestLog]) + class TriggerSubscriptionBuilderService: """Service for managing trigger providers and credentials""" @@ -398,7 +400,7 @@ class TriggerSubscriptionBuilderService: cache_key = cls.encode_cache_key(endpoint_id) subscription_cache = redis_client.get(cache_key) if subscription_cache: - return SubscriptionBuilder.model_validate(json.loads(subscription_cache)) + return SubscriptionBuilder.model_validate_json(subscription_cache) return None @@ -423,12 +425,16 @@ class TriggerSubscriptionBuilderService: ) key = f"trigger:subscription:builder:logs:{endpoint_id}" - logs = json.loads(redis_client.get(key) or "[]") - logs.append(log.model_dump(mode="json")) + logs = _request_logs_adapter.validate_json(redis_client.get(key) or b"[]") + logs.append(log) # Keep last N logs logs = logs[-cls.__VALIDATION_REQUEST_CACHE_COUNT__ :] - redis_client.setex(key, cls.__VALIDATION_REQUEST_CACHE_EXPIRE_SECONDS__, json.dumps(logs, default=str)) + redis_client.setex( + key, + cls.__VALIDATION_REQUEST_CACHE_EXPIRE_SECONDS__, + _request_logs_adapter.dump_json(logs), + ) @classmethod def list_logs(cls, endpoint_id: str) -> list[RequestLog]: @@ -437,7 +443,7 @@ class TriggerSubscriptionBuilderService: logs_json = redis_client.get(key) if not logs_json: return [] - return [RequestLog.model_validate(log) for log in json.loads(logs_json)] + return _request_logs_adapter.validate_json(logs_json) @classmethod def process_builder_validation_endpoint(cls, endpoint_id: str, request: Request) -> Response | None: diff --git a/api/services/workflow_service.py b/api/services/workflow_service.py index b555676704..3b3ee6dd92 100644 --- a/api/services/workflow_service.py +++ b/api/services/workflow_service.py @@ -1118,7 +1118,7 @@ class WorkflowService: continue try: payload = json.loads(recipient.recipient_payload) - except Exception: + except (json.JSONDecodeError, ValueError): logger.exception("Failed to parse human input recipient payload for delivery test.") continue email = payload.get("email") diff --git a/api/tests/integration_tests/services/plugin/__init__.py b/api/tests/integration_tests/services/plugin/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/integration_tests/services/plugin/test_plugin_lifecycle.py b/api/tests/integration_tests/services/plugin/test_plugin_lifecycle.py new file mode 100644 index 0000000000..951a5ab4b4 --- /dev/null +++ b/api/tests/integration_tests/services/plugin/test_plugin_lifecycle.py @@ -0,0 +1,182 @@ +import pytest +from sqlalchemy import delete + +from core.db.session_factory import session_factory +from models import Tenant +from models.account import TenantPluginAutoUpgradeStrategy, TenantPluginPermission +from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService +from services.plugin.plugin_permission_service import PluginPermissionService + + +@pytest.fixture +def tenant(flask_req_ctx): + with session_factory.create_session() as session: + t = Tenant(name="plugin_it_tenant") + session.add(t) + session.commit() + tenant_id = t.id + + yield tenant_id + + with session_factory.create_session() as session: + session.execute(delete(TenantPluginPermission).where(TenantPluginPermission.tenant_id == tenant_id)) + session.execute( + delete(TenantPluginAutoUpgradeStrategy).where(TenantPluginAutoUpgradeStrategy.tenant_id == tenant_id) + ) + session.execute(delete(Tenant).where(Tenant.id == tenant_id)) + session.commit() + + +class TestPluginPermissionLifecycle: + def test_get_returns_none_for_new_tenant(self, tenant): + assert PluginPermissionService.get_permission(tenant) is None + + def test_change_creates_row(self, tenant): + result = PluginPermissionService.change_permission( + tenant, + TenantPluginPermission.InstallPermission.ADMINS, + TenantPluginPermission.DebugPermission.EVERYONE, + ) + assert result is True + + perm = PluginPermissionService.get_permission(tenant) + assert perm is not None + assert perm.install_permission == TenantPluginPermission.InstallPermission.ADMINS + assert perm.debug_permission == TenantPluginPermission.DebugPermission.EVERYONE + + def test_change_updates_existing_row(self, tenant): + PluginPermissionService.change_permission( + tenant, + TenantPluginPermission.InstallPermission.ADMINS, + TenantPluginPermission.DebugPermission.NOBODY, + ) + PluginPermissionService.change_permission( + tenant, + TenantPluginPermission.InstallPermission.EVERYONE, + TenantPluginPermission.DebugPermission.ADMINS, + ) + perm = PluginPermissionService.get_permission(tenant) + assert perm is not None + assert perm.install_permission == TenantPluginPermission.InstallPermission.EVERYONE + assert perm.debug_permission == TenantPluginPermission.DebugPermission.ADMINS + + with session_factory.create_session() as session: + count = session.query(TenantPluginPermission).where(TenantPluginPermission.tenant_id == tenant).count() + assert count == 1 + + +class TestPluginAutoUpgradeLifecycle: + def test_get_returns_none_for_new_tenant(self, tenant): + assert PluginAutoUpgradeService.get_strategy(tenant) is None + + def test_change_creates_row(self, tenant): + result = PluginAutoUpgradeService.change_strategy( + tenant, + strategy_setting=TenantPluginAutoUpgradeStrategy.StrategySetting.LATEST, + upgrade_time_of_day=3, + upgrade_mode=TenantPluginAutoUpgradeStrategy.UpgradeMode.ALL, + exclude_plugins=[], + include_plugins=[], + ) + assert result is True + + strategy = PluginAutoUpgradeService.get_strategy(tenant) + assert strategy is not None + assert strategy.strategy_setting == TenantPluginAutoUpgradeStrategy.StrategySetting.LATEST + assert strategy.upgrade_time_of_day == 3 + + def test_change_updates_existing_row(self, tenant): + PluginAutoUpgradeService.change_strategy( + tenant, + strategy_setting=TenantPluginAutoUpgradeStrategy.StrategySetting.FIX_ONLY, + upgrade_time_of_day=0, + upgrade_mode=TenantPluginAutoUpgradeStrategy.UpgradeMode.ALL, + exclude_plugins=[], + include_plugins=[], + ) + PluginAutoUpgradeService.change_strategy( + tenant, + strategy_setting=TenantPluginAutoUpgradeStrategy.StrategySetting.LATEST, + upgrade_time_of_day=12, + upgrade_mode=TenantPluginAutoUpgradeStrategy.UpgradeMode.PARTIAL, + exclude_plugins=[], + include_plugins=["plugin-a"], + ) + + strategy = PluginAutoUpgradeService.get_strategy(tenant) + assert strategy is not None + assert strategy.strategy_setting == TenantPluginAutoUpgradeStrategy.StrategySetting.LATEST + assert strategy.upgrade_time_of_day == 12 + assert strategy.upgrade_mode == TenantPluginAutoUpgradeStrategy.UpgradeMode.PARTIAL + assert strategy.include_plugins == ["plugin-a"] + + def test_exclude_plugin_creates_strategy_when_none_exists(self, tenant): + PluginAutoUpgradeService.exclude_plugin(tenant, "my-plugin") + + strategy = PluginAutoUpgradeService.get_strategy(tenant) + assert strategy is not None + assert strategy.upgrade_mode == TenantPluginAutoUpgradeStrategy.UpgradeMode.EXCLUDE + assert "my-plugin" in strategy.exclude_plugins + + def test_exclude_plugin_appends_in_exclude_mode(self, tenant): + PluginAutoUpgradeService.change_strategy( + tenant, + strategy_setting=TenantPluginAutoUpgradeStrategy.StrategySetting.FIX_ONLY, + upgrade_time_of_day=0, + upgrade_mode=TenantPluginAutoUpgradeStrategy.UpgradeMode.EXCLUDE, + exclude_plugins=["existing"], + include_plugins=[], + ) + PluginAutoUpgradeService.exclude_plugin(tenant, "new-plugin") + + strategy = PluginAutoUpgradeService.get_strategy(tenant) + assert strategy is not None + assert "existing" in strategy.exclude_plugins + assert "new-plugin" in strategy.exclude_plugins + + def test_exclude_plugin_dedup_in_exclude_mode(self, tenant): + PluginAutoUpgradeService.change_strategy( + tenant, + strategy_setting=TenantPluginAutoUpgradeStrategy.StrategySetting.FIX_ONLY, + upgrade_time_of_day=0, + upgrade_mode=TenantPluginAutoUpgradeStrategy.UpgradeMode.EXCLUDE, + exclude_plugins=["same-plugin"], + include_plugins=[], + ) + PluginAutoUpgradeService.exclude_plugin(tenant, "same-plugin") + + strategy = PluginAutoUpgradeService.get_strategy(tenant) + assert strategy is not None + assert strategy.exclude_plugins.count("same-plugin") == 1 + + def test_exclude_from_partial_mode_removes_from_include(self, tenant): + PluginAutoUpgradeService.change_strategy( + tenant, + strategy_setting=TenantPluginAutoUpgradeStrategy.StrategySetting.FIX_ONLY, + upgrade_time_of_day=0, + upgrade_mode=TenantPluginAutoUpgradeStrategy.UpgradeMode.PARTIAL, + exclude_plugins=[], + include_plugins=["p1", "p2"], + ) + PluginAutoUpgradeService.exclude_plugin(tenant, "p1") + + strategy = PluginAutoUpgradeService.get_strategy(tenant) + assert strategy is not None + assert "p1" not in strategy.include_plugins + assert "p2" in strategy.include_plugins + + def test_exclude_from_all_mode_switches_to_exclude(self, tenant): + PluginAutoUpgradeService.change_strategy( + tenant, + strategy_setting=TenantPluginAutoUpgradeStrategy.StrategySetting.LATEST, + upgrade_time_of_day=0, + upgrade_mode=TenantPluginAutoUpgradeStrategy.UpgradeMode.ALL, + exclude_plugins=[], + include_plugins=[], + ) + PluginAutoUpgradeService.exclude_plugin(tenant, "excluded-plugin") + + strategy = PluginAutoUpgradeService.get_strategy(tenant) + assert strategy is not None + assert strategy.upgrade_mode == TenantPluginAutoUpgradeStrategy.UpgradeMode.EXCLUDE + assert "excluded-plugin" in strategy.exclude_plugins diff --git a/api/tests/integration_tests/services/retention/__init__.py b/api/tests/integration_tests/services/retention/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/integration_tests/services/retention/test_messages_clean_service.py b/api/tests/integration_tests/services/retention/test_messages_clean_service.py new file mode 100644 index 0000000000..348bb0af4a --- /dev/null +++ b/api/tests/integration_tests/services/retention/test_messages_clean_service.py @@ -0,0 +1,348 @@ +import datetime +import math +import uuid + +import pytest +from sqlalchemy import delete + +from core.db.session_factory import session_factory +from models import Tenant +from models.enums import FeedbackFromSource, FeedbackRating +from models.model import ( + App, + Conversation, + Message, + MessageAnnotation, + MessageFeedback, +) +from services.retention.conversation.messages_clean_policy import BillingDisabledPolicy +from services.retention.conversation.messages_clean_service import MessagesCleanService + +_NOW = datetime.datetime(2026, 1, 15, 12, 0, 0, tzinfo=datetime.UTC) +_OLD = _NOW - datetime.timedelta(days=60) +_VERY_OLD = _NOW - datetime.timedelta(days=90) +_RECENT = _NOW - datetime.timedelta(days=5) + +_WINDOW_START = _VERY_OLD - datetime.timedelta(hours=1) +_WINDOW_END = _RECENT + datetime.timedelta(hours=1) + +_DEFAULT_BATCH_SIZE = 100 +_PAGINATION_MESSAGE_COUNT = 25 +_PAGINATION_BATCH_SIZE = 8 + + +@pytest.fixture +def tenant_and_app(flask_req_ctx): + """Creates a Tenant, App and Conversation for the test and cleans up after.""" + with session_factory.create_session() as session: + tenant = Tenant(name="retention_it_tenant") + session.add(tenant) + session.flush() + + app = App( + tenant_id=tenant.id, + name="Retention IT App", + mode="chat", + enable_site=True, + enable_api=True, + ) + session.add(app) + session.flush() + + conv = Conversation( + app_id=app.id, + mode="chat", + name="test_conv", + status="normal", + from_source="console", + _inputs={}, + ) + session.add(conv) + session.commit() + + tenant_id = tenant.id + app_id = app.id + conv_id = conv.id + + yield {"tenant_id": tenant_id, "app_id": app_id, "conversation_id": conv_id} + + with session_factory.create_session() as session: + session.execute(delete(Conversation).where(Conversation.id == conv_id)) + session.execute(delete(App).where(App.id == app_id)) + session.execute(delete(Tenant).where(Tenant.id == tenant_id)) + session.commit() + + +def _make_message(app_id: str, conversation_id: str, created_at: datetime.datetime) -> Message: + return Message( + app_id=app_id, + conversation_id=conversation_id, + query="test", + message=[{"text": "hello"}], + answer="world", + message_tokens=1, + message_unit_price=0, + answer_tokens=1, + answer_unit_price=0, + from_source="console", + currency="USD", + _inputs={}, + created_at=created_at, + ) + + +class TestMessagesCleanServiceIntegration: + @pytest.fixture + def seed_messages(self, tenant_and_app): + """Seeds one message at each of _VERY_OLD, _OLD, and _RECENT. + Yields a semantic mapping keyed by age label. + """ + data = tenant_and_app + app_id = data["app_id"] + conv_id = data["conversation_id"] + # Ordered tuple of (label, timestamp) for deterministic seeding + timestamps = [ + ("very_old", _VERY_OLD), + ("old", _OLD), + ("recent", _RECENT), + ] + msg_ids: dict[str, str] = {} + + with session_factory.create_session() as session: + for label, ts in timestamps: + msg = _make_message(app_id, conv_id, ts) + session.add(msg) + session.flush() + msg_ids[label] = msg.id + session.commit() + + yield {"msg_ids": msg_ids, **data} + + with session_factory.create_session() as session: + session.execute( + delete(Message) + .where(Message.id.in_(list(msg_ids.values()))) + .execution_options(synchronize_session=False) + ) + session.commit() + + @pytest.fixture + def paginated_seed_messages(self, tenant_and_app): + """Seeds multiple messages separated by 1-second increments starting at _OLD.""" + data = tenant_and_app + app_id = data["app_id"] + conv_id = data["conversation_id"] + msg_ids: list[str] = [] + + with session_factory.create_session() as session: + for i in range(_PAGINATION_MESSAGE_COUNT): + ts = _OLD + datetime.timedelta(seconds=i) + msg = _make_message(app_id, conv_id, ts) + session.add(msg) + session.flush() + msg_ids.append(msg.id) + session.commit() + + yield {"msg_ids": msg_ids, **data} + + with session_factory.create_session() as session: + session.execute(delete(Message).where(Message.id.in_(msg_ids)).execution_options(synchronize_session=False)) + session.commit() + + @pytest.fixture + def cascade_test_data(self, tenant_and_app): + """Seeds one Message with an associated Feedback and Annotation.""" + data = tenant_and_app + app_id = data["app_id"] + conv_id = data["conversation_id"] + + with session_factory.create_session() as session: + msg = _make_message(app_id, conv_id, _OLD) + session.add(msg) + session.flush() + + feedback = MessageFeedback( + app_id=app_id, + conversation_id=conv_id, + message_id=msg.id, + rating=FeedbackRating.LIKE, + from_source=FeedbackFromSource.USER, + ) + annotation = MessageAnnotation( + app_id=app_id, + conversation_id=conv_id, + message_id=msg.id, + question="q", + content="a", + account_id=str(uuid.uuid4()), + ) + session.add_all([feedback, annotation]) + session.commit() + + msg_id = msg.id + fb_id = feedback.id + ann_id = annotation.id + + yield {"msg_id": msg_id, "fb_id": fb_id, "ann_id": ann_id, **data} + + with session_factory.create_session() as session: + session.execute(delete(MessageAnnotation).where(MessageAnnotation.id == ann_id)) + session.execute(delete(MessageFeedback).where(MessageFeedback.id == fb_id)) + session.execute(delete(Message).where(Message.id == msg_id)) + session.commit() + + def test_dry_run_does_not_delete(self, seed_messages): + """Dry-run must count eligible rows without deleting any of them.""" + data = seed_messages + msg_ids = data["msg_ids"] + all_ids = list(msg_ids.values()) + + svc = MessagesCleanService.from_time_range( + policy=BillingDisabledPolicy(), + start_from=_WINDOW_START, + end_before=_WINDOW_END, + batch_size=_DEFAULT_BATCH_SIZE, + dry_run=True, + ) + stats = svc.run() + + assert stats["filtered_messages"] == len(all_ids) + assert stats["total_deleted"] == 0 + + with session_factory.create_session() as session: + remaining = session.query(Message).where(Message.id.in_(all_ids)).count() + assert remaining == len(all_ids) + + def test_billing_disabled_deletes_all_in_range(self, seed_messages): + """All 3 seeded messages fall within the window and must be deleted.""" + data = seed_messages + msg_ids = data["msg_ids"] + all_ids = list(msg_ids.values()) + + svc = MessagesCleanService.from_time_range( + policy=BillingDisabledPolicy(), + start_from=_WINDOW_START, + end_before=_WINDOW_END, + batch_size=_DEFAULT_BATCH_SIZE, + dry_run=False, + ) + stats = svc.run() + + assert stats["total_deleted"] == len(all_ids) + + with session_factory.create_session() as session: + remaining = session.query(Message).where(Message.id.in_(all_ids)).count() + assert remaining == 0 + + def test_start_from_filters_correctly(self, seed_messages): + """Only the message at _OLD falls within the narrow ±1 h window.""" + data = seed_messages + msg_ids = data["msg_ids"] + + start = _OLD - datetime.timedelta(hours=1) + end = _OLD + datetime.timedelta(hours=1) + + svc = MessagesCleanService.from_time_range( + policy=BillingDisabledPolicy(), + start_from=start, + end_before=end, + batch_size=_DEFAULT_BATCH_SIZE, + ) + stats = svc.run() + + assert stats["total_deleted"] == 1 + + with session_factory.create_session() as session: + all_ids = list(msg_ids.values()) + remaining_ids = {r[0] for r in session.query(Message.id).where(Message.id.in_(all_ids)).all()} + + assert msg_ids["old"] not in remaining_ids + assert msg_ids["very_old"] in remaining_ids + assert msg_ids["recent"] in remaining_ids + + def test_cursor_pagination_across_batches(self, paginated_seed_messages): + """Messages must be deleted across multiple batches.""" + data = paginated_seed_messages + msg_ids = data["msg_ids"] + + # _OLD is the earliest; the last one is _OLD + (_PAGINATION_MESSAGE_COUNT - 1) s. + pagination_window_start = _OLD - datetime.timedelta(seconds=1) + pagination_window_end = _OLD + datetime.timedelta(seconds=_PAGINATION_MESSAGE_COUNT) + + svc = MessagesCleanService.from_time_range( + policy=BillingDisabledPolicy(), + start_from=pagination_window_start, + end_before=pagination_window_end, + batch_size=_PAGINATION_BATCH_SIZE, + ) + stats = svc.run() + + assert stats["total_deleted"] == _PAGINATION_MESSAGE_COUNT + expected_batches = math.ceil(_PAGINATION_MESSAGE_COUNT / _PAGINATION_BATCH_SIZE) + assert stats["batches"] >= expected_batches + + with session_factory.create_session() as session: + remaining = session.query(Message).where(Message.id.in_(msg_ids)).count() + assert remaining == 0 + + def test_no_messages_in_range_returns_empty_stats(self, seed_messages): + """A window entirely in the future must yield zero matches.""" + far_future = _NOW + datetime.timedelta(days=365) + even_further = far_future + datetime.timedelta(days=1) + + svc = MessagesCleanService.from_time_range( + policy=BillingDisabledPolicy(), + start_from=far_future, + end_before=even_further, + batch_size=_DEFAULT_BATCH_SIZE, + ) + stats = svc.run() + + assert stats["total_messages"] == 0 + assert stats["total_deleted"] == 0 + + def test_relation_cascade_deletes(self, cascade_test_data): + """Deleting a Message must cascade to its Feedback and Annotation rows.""" + data = cascade_test_data + msg_id = data["msg_id"] + fb_id = data["fb_id"] + ann_id = data["ann_id"] + + svc = MessagesCleanService.from_time_range( + policy=BillingDisabledPolicy(), + start_from=_OLD - datetime.timedelta(hours=1), + end_before=_OLD + datetime.timedelta(hours=1), + batch_size=_DEFAULT_BATCH_SIZE, + ) + stats = svc.run() + + assert stats["total_deleted"] == 1 + + with session_factory.create_session() as session: + assert session.query(Message).where(Message.id == msg_id).count() == 0 + assert session.query(MessageFeedback).where(MessageFeedback.id == fb_id).count() == 0 + assert session.query(MessageAnnotation).where(MessageAnnotation.id == ann_id).count() == 0 + + def test_factory_from_time_range_validation(self): + with pytest.raises(ValueError, match="start_from"): + MessagesCleanService.from_time_range( + policy=BillingDisabledPolicy(), + start_from=_NOW, + end_before=_OLD, + ) + + def test_factory_from_days_validation(self): + with pytest.raises(ValueError, match="days"): + MessagesCleanService.from_days( + policy=BillingDisabledPolicy(), + days=-1, + ) + + def test_factory_batch_size_validation(self): + with pytest.raises(ValueError, match="batch_size"): + MessagesCleanService.from_time_range( + policy=BillingDisabledPolicy(), + start_from=_OLD, + end_before=_NOW, + batch_size=0, + ) diff --git a/api/tests/integration_tests/services/retention/test_workflow_run_archiver.py b/api/tests/integration_tests/services/retention/test_workflow_run_archiver.py new file mode 100644 index 0000000000..5728eacdfb --- /dev/null +++ b/api/tests/integration_tests/services/retention/test_workflow_run_archiver.py @@ -0,0 +1,177 @@ +import datetime +import io +import json +import uuid +import zipfile +from unittest.mock import MagicMock, patch + +import pytest + +from services.retention.workflow_run.archive_paid_plan_workflow_run import ( + ArchiveSummary, + WorkflowRunArchiver, +) +from services.retention.workflow_run.constants import ARCHIVE_SCHEMA_VERSION + + +class TestWorkflowRunArchiverInit: + def test_start_from_without_end_before_raises(self): + with pytest.raises(ValueError, match="start_from and end_before must be provided together"): + WorkflowRunArchiver(start_from=datetime.datetime(2025, 1, 1)) + + def test_end_before_without_start_from_raises(self): + with pytest.raises(ValueError, match="start_from and end_before must be provided together"): + WorkflowRunArchiver(end_before=datetime.datetime(2025, 1, 1)) + + def test_start_equals_end_raises(self): + ts = datetime.datetime(2025, 1, 1) + with pytest.raises(ValueError, match="start_from must be earlier than end_before"): + WorkflowRunArchiver(start_from=ts, end_before=ts) + + def test_start_after_end_raises(self): + with pytest.raises(ValueError, match="start_from must be earlier than end_before"): + WorkflowRunArchiver( + start_from=datetime.datetime(2025, 6, 1), + end_before=datetime.datetime(2025, 1, 1), + ) + + def test_workers_zero_raises(self): + with pytest.raises(ValueError, match="workers must be at least 1"): + WorkflowRunArchiver(workers=0) + + def test_valid_init_defaults(self): + archiver = WorkflowRunArchiver(days=30, batch_size=50) + assert archiver.days == 30 + assert archiver.batch_size == 50 + assert archiver.dry_run is False + assert archiver.delete_after_archive is False + assert archiver.start_from is None + + def test_valid_init_with_time_range(self): + start = datetime.datetime(2025, 1, 1) + end = datetime.datetime(2025, 6, 1) + archiver = WorkflowRunArchiver(start_from=start, end_before=end, workers=2) + assert archiver.start_from is not None + assert archiver.end_before is not None + assert archiver.workers == 2 + + +class TestBuildArchiveBundle: + def test_bundle_contains_manifest_and_all_tables(self): + archiver = WorkflowRunArchiver(days=90) + + manifest_data = json.dumps({"schema_version": ARCHIVE_SCHEMA_VERSION}).encode("utf-8") + table_payloads = dict.fromkeys(archiver.ARCHIVED_TABLES, b"") + + bundle_bytes = archiver._build_archive_bundle(manifest_data, table_payloads) + + with zipfile.ZipFile(io.BytesIO(bundle_bytes), "r") as zf: + names = set(zf.namelist()) + assert "manifest.json" in names + for table in archiver.ARCHIVED_TABLES: + assert f"{table}.jsonl" in names, f"Missing {table}.jsonl in bundle" + + def test_bundle_missing_table_payload_raises(self): + archiver = WorkflowRunArchiver(days=90) + manifest_data = b"{}" + incomplete_payloads = {archiver.ARCHIVED_TABLES[0]: b"data"} + + with pytest.raises(ValueError, match="Missing archive payload"): + archiver._build_archive_bundle(manifest_data, incomplete_payloads) + + +class TestGenerateManifest: + def test_manifest_structure(self): + archiver = WorkflowRunArchiver(days=90) + from services.retention.workflow_run.archive_paid_plan_workflow_run import TableStats + + run = MagicMock() + run.id = str(uuid.uuid4()) + run.tenant_id = str(uuid.uuid4()) + run.app_id = str(uuid.uuid4()) + run.workflow_id = str(uuid.uuid4()) + run.created_at = datetime.datetime(2025, 3, 15, 10, 0, 0) + + stats = [ + TableStats(table_name="workflow_runs", row_count=1, checksum="abc123", size_bytes=512), + TableStats(table_name="workflow_app_logs", row_count=2, checksum="def456", size_bytes=1024), + ] + + manifest = archiver._generate_manifest(run, stats) + + assert manifest["schema_version"] == ARCHIVE_SCHEMA_VERSION + assert manifest["workflow_run_id"] == run.id + assert manifest["tenant_id"] == run.tenant_id + assert manifest["app_id"] == run.app_id + assert "tables" in manifest + assert manifest["tables"]["workflow_runs"]["row_count"] == 1 + assert manifest["tables"]["workflow_runs"]["checksum"] == "abc123" + assert manifest["tables"]["workflow_app_logs"]["row_count"] == 2 + + +class TestFilterPaidTenants: + def test_all_tenants_paid_when_billing_disabled(self): + archiver = WorkflowRunArchiver(days=90) + tenant_ids = {"t1", "t2", "t3"} + + with patch("services.retention.workflow_run.archive_paid_plan_workflow_run.dify_config") as cfg: + cfg.BILLING_ENABLED = False + result = archiver._filter_paid_tenants(tenant_ids) + + assert result == tenant_ids + + def test_empty_tenants_returns_empty(self): + archiver = WorkflowRunArchiver(days=90) + + with patch("services.retention.workflow_run.archive_paid_plan_workflow_run.dify_config") as cfg: + cfg.BILLING_ENABLED = True + result = archiver._filter_paid_tenants(set()) + + assert result == set() + + def test_only_paid_plans_returned(self): + archiver = WorkflowRunArchiver(days=90) + + mock_bulk = { + "t1": {"plan": "professional"}, + "t2": {"plan": "sandbox"}, + "t3": {"plan": "team"}, + } + + with ( + patch("services.retention.workflow_run.archive_paid_plan_workflow_run.dify_config") as cfg, + patch("services.retention.workflow_run.archive_paid_plan_workflow_run.BillingService") as billing, + ): + cfg.BILLING_ENABLED = True + billing.get_plan_bulk_with_cache.return_value = mock_bulk + result = archiver._filter_paid_tenants({"t1", "t2", "t3"}) + + assert "t1" in result + assert "t3" in result + assert "t2" not in result + + def test_billing_api_failure_returns_empty(self): + archiver = WorkflowRunArchiver(days=90) + + with ( + patch("services.retention.workflow_run.archive_paid_plan_workflow_run.dify_config") as cfg, + patch("services.retention.workflow_run.archive_paid_plan_workflow_run.BillingService") as billing, + ): + cfg.BILLING_ENABLED = True + billing.get_plan_bulk_with_cache.side_effect = RuntimeError("API down") + result = archiver._filter_paid_tenants({"t1"}) + + assert result == set() + + +class TestDryRunArchive: + @patch("services.retention.workflow_run.archive_paid_plan_workflow_run.get_archive_storage") + def test_dry_run_does_not_call_storage(self, mock_get_storage, flask_req_ctx): + archiver = WorkflowRunArchiver(days=90, dry_run=True) + + with patch.object(archiver, "_get_runs_batch", return_value=[]): + summary = archiver.run() + + mock_get_storage.assert_not_called() + assert isinstance(summary, ArchiveSummary) + assert summary.runs_failed == 0 diff --git a/api/tests/unit_tests/controllers/console/app/test_app_apis.py b/api/tests/test_containers_integration_tests/controllers/console/app/test_app_apis.py similarity index 90% rename from api/tests/unit_tests/controllers/console/app/test_app_apis.py rename to api/tests/test_containers_integration_tests/controllers/console/app/test_app_apis.py index 1d1e119fd6..fbaec069bb 100644 --- a/api/tests/unit_tests/controllers/console/app/test_app_apis.py +++ b/api/tests/test_containers_integration_tests/controllers/console/app/test_app_apis.py @@ -1,7 +1,4 @@ -""" -Additional tests to improve coverage for low-coverage modules in controllers/console/app. -Target: increase coverage for files with <75% coverage. -""" +"""Testcontainers integration tests for controllers/console/app endpoints.""" from __future__ import annotations @@ -70,26 +67,12 @@ def _unwrap(func): return func -class _ConnContext: - def __init__(self, rows): - self._rows = rows - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc, tb): - return False - - def execute(self, _query, _args): - return self._rows - - -# ========== Completion Tests ========== class TestCompletionEndpoints: - """Tests for completion API endpoints.""" + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers def test_completion_create_payload(self): - """Test completion creation payload.""" payload = CompletionMessagePayload(inputs={"prompt": "test"}, model_config={}) assert payload.inputs == {"prompt": "test"} @@ -209,7 +192,9 @@ class TestCompletionEndpoints: class TestAppEndpoints: - """Tests for app endpoints.""" + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers def test_app_put_should_preserve_icon_type_when_payload_omits_it(self, app, monkeypatch): api = app_module.AppApi() @@ -250,12 +235,12 @@ class TestAppEndpoints: ) -# ========== OpsTrace Tests ========== class TestOpsTraceEndpoints: - """Tests for ops_trace endpoint.""" + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers def test_ops_trace_query_basic(self): - """Test ops_trace query.""" query = TraceProviderQuery(tracing_provider="langfuse") assert query.tracing_provider == "langfuse" @@ -310,12 +295,12 @@ class TestOpsTraceEndpoints: method(app_id="app-1") -# ========== Site Tests ========== class TestSiteEndpoints: - """Tests for site endpoint.""" + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers def test_site_response_structure(self): - """Test site response structure.""" payload = AppSiteUpdatePayload(title="My Site", description="Test site") assert payload.title == "My Site" @@ -369,27 +354,22 @@ class TestSiteEndpoints: assert result is site -# ========== Workflow Tests ========== class TestWorkflowEndpoints: - """Tests for workflow endpoints.""" - def test_workflow_copy_payload(self): - """Test workflow copy payload.""" payload = SyncDraftWorkflowPayload(graph={}, features={}) assert payload.graph == {} def test_workflow_mode_query(self): - """Test workflow mode query.""" payload = AdvancedChatWorkflowRunPayload(inputs={}, query="hi") assert payload.query == "hi" -# ========== Workflow App Log Tests ========== class TestWorkflowAppLogEndpoints: - """Tests for workflow app log endpoints.""" + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers def test_workflow_app_log_query(self): - """Test workflow app log query.""" query = WorkflowAppLogQuery(keyword="test", page=1, limit=20) assert query.keyword == "test" @@ -427,12 +407,12 @@ class TestWorkflowAppLogEndpoints: assert result == {"items": [], "total": 0} -# ========== Workflow Draft Variable Tests ========== class TestWorkflowDraftVariableEndpoints: - """Tests for workflow draft variable endpoints.""" + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers def test_workflow_variable_creation(self): - """Test workflow variable creation.""" payload = WorkflowDraftVariableUpdatePayload(name="var1", value="test") assert payload.name == "var1" @@ -472,12 +452,12 @@ class TestWorkflowDraftVariableEndpoints: assert result == {"items": [], "total": 0} -# ========== Workflow Statistic Tests ========== class TestWorkflowStatisticEndpoints: - """Tests for workflow statistic endpoints.""" + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers def test_workflow_statistic_time_range(self): - """Test workflow statistic time range query.""" query = WorkflowStatisticQuery(start="2024-01-01", end="2024-12-31") assert query.start == "2024-01-01" @@ -541,12 +521,12 @@ class TestWorkflowStatisticEndpoints: assert response.get_json() == {"data": [{"date": "2024-01-02"}]} -# ========== Workflow Trigger Tests ========== class TestWorkflowTriggerEndpoints: - """Tests for workflow trigger endpoints.""" + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers def test_webhook_trigger_payload(self): - """Test webhook trigger payload.""" payload = Parser(node_id="node-1") assert payload.node_id == "node-1" @@ -578,22 +558,13 @@ class TestWorkflowTriggerEndpoints: assert result is trigger -# ========== Wraps Tests ========== class TestWrapsEndpoints: - """Tests for wraps utility functions.""" - def test_get_app_model_context(self): - """Test get_app_model wrapper context.""" - # These are decorator functions, so we test their availability assert hasattr(wraps_module, "get_app_model") -# ========== MCP Server Tests ========== class TestMCPServerEndpoints: - """Tests for MCP server endpoints.""" - def test_mcp_server_connection(self): - """Test MCP server connection.""" payload = MCPServerCreatePayload(parameters={"url": "http://localhost:3000"}) assert payload.parameters["url"] == "http://localhost:3000" @@ -602,22 +573,14 @@ class TestMCPServerEndpoints: assert payload.status == "active" -# ========== Error Handling Tests ========== class TestErrorHandling: - """Tests for error handling in various endpoints.""" - def test_annotation_list_query_validation(self): - """Test annotation list query validation.""" with pytest.raises(ValueError): annotation_module.AnnotationListQuery(page=0) -# ========== Integration-like Tests ========== class TestPayloadIntegration: - """Integration tests for payload handling.""" - def test_multiple_payload_types(self): - """Test handling of multiple payload types.""" payloads = [ annotation_module.AnnotationReplyPayload( score_threshold=0.5, embedding_provider_name="openai", embedding_model_name="text-embedding-3-small" diff --git a/api/tests/test_containers_integration_tests/controllers/console/app/test_app_import_api.py b/api/tests/test_containers_integration_tests/controllers/console/app/test_app_import_api.py new file mode 100644 index 0000000000..d8c6821f8d --- /dev/null +++ b/api/tests/test_containers_integration_tests/controllers/console/app/test_app_import_api.py @@ -0,0 +1,142 @@ +"""Testcontainers integration tests for controllers.console.app.app_import endpoints.""" + +from __future__ import annotations + +from types import SimpleNamespace +from unittest.mock import MagicMock + +import pytest + +from controllers.console.app import app_import as app_import_module +from services.app_dsl_service import ImportStatus + + +def _unwrap(func): + bound_self = getattr(func, "__self__", None) + while hasattr(func, "__wrapped__"): + func = func.__wrapped__ + if bound_self is not None: + return func.__get__(bound_self, bound_self.__class__) + return func + + +class _Result: + def __init__(self, status: ImportStatus, app_id: str | None = "app-1"): + self.status = status + self.app_id = app_id + + def model_dump(self, mode: str = "json"): + return {"status": self.status, "app_id": self.app_id} + + +def _install_features(monkeypatch: pytest.MonkeyPatch, enabled: bool) -> None: + features = SimpleNamespace(webapp_auth=SimpleNamespace(enabled=enabled)) + monkeypatch.setattr(app_import_module.FeatureService, "get_system_features", lambda: features) + + +class TestAppImportApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_import_post_returns_failed_status(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + api = app_import_module.AppImportApi() + method = _unwrap(api.post) + + _install_features(monkeypatch, enabled=False) + monkeypatch.setattr( + app_import_module.AppDslService, + "import_app", + lambda *_args, **_kwargs: _Result(ImportStatus.FAILED, app_id=None), + ) + monkeypatch.setattr(app_import_module, "current_account_with_tenant", lambda: (SimpleNamespace(id="u1"), "t1")) + + with app.test_request_context("/console/api/apps/imports", method="POST", json={"mode": "yaml-content"}): + response, status = method() + + assert status == 400 + assert response["status"] == ImportStatus.FAILED + + def test_import_post_returns_pending_status(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + api = app_import_module.AppImportApi() + method = _unwrap(api.post) + + _install_features(monkeypatch, enabled=False) + monkeypatch.setattr( + app_import_module.AppDslService, + "import_app", + lambda *_args, **_kwargs: _Result(ImportStatus.PENDING), + ) + monkeypatch.setattr(app_import_module, "current_account_with_tenant", lambda: (SimpleNamespace(id="u1"), "t1")) + + with app.test_request_context("/console/api/apps/imports", method="POST", json={"mode": "yaml-content"}): + response, status = method() + + assert status == 202 + assert response["status"] == ImportStatus.PENDING + + def test_import_post_updates_webapp_auth_when_enabled(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + api = app_import_module.AppImportApi() + method = _unwrap(api.post) + + _install_features(monkeypatch, enabled=True) + monkeypatch.setattr( + app_import_module.AppDslService, + "import_app", + lambda *_args, **_kwargs: _Result(ImportStatus.COMPLETED, app_id="app-123"), + ) + update_access = MagicMock() + monkeypatch.setattr(app_import_module.EnterpriseService.WebAppAuth, "update_app_access_mode", update_access) + monkeypatch.setattr(app_import_module, "current_account_with_tenant", lambda: (SimpleNamespace(id="u1"), "t1")) + + with app.test_request_context("/console/api/apps/imports", method="POST", json={"mode": "yaml-content"}): + response, status = method() + + update_access.assert_called_once_with("app-123", "private") + assert status == 200 + assert response["status"] == ImportStatus.COMPLETED + + +class TestAppImportConfirmApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_import_confirm_returns_failed_status(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + api = app_import_module.AppImportConfirmApi() + method = _unwrap(api.post) + + monkeypatch.setattr( + app_import_module.AppDslService, + "confirm_import", + lambda *_args, **_kwargs: _Result(ImportStatus.FAILED), + ) + monkeypatch.setattr(app_import_module, "current_account_with_tenant", lambda: (SimpleNamespace(id="u1"), "t1")) + + with app.test_request_context("/console/api/apps/imports/import-1/confirm", method="POST"): + response, status = method(import_id="import-1") + + assert status == 400 + assert response["status"] == ImportStatus.FAILED + + +class TestAppImportCheckDependenciesApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_import_check_dependencies_returns_result(self, app, monkeypatch: pytest.MonkeyPatch) -> None: + api = app_import_module.AppImportCheckDependenciesApi() + method = _unwrap(api.get) + + monkeypatch.setattr( + app_import_module.AppDslService, + "check_dependencies", + lambda *_args, **_kwargs: SimpleNamespace(model_dump=lambda mode="json": {"leaked_dependencies": []}), + ) + + with app.test_request_context("/console/api/apps/imports/app-1/check-dependencies", method="GET"): + response, status = method(app_model=SimpleNamespace(id="app-1")) + + assert status == 200 + assert response["leaked_dependencies"] == [] diff --git a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline.py b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline.py similarity index 77% rename from api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline.py rename to api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline.py index ebbb34e069..d5ae95dfb7 100644 --- a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline.py +++ b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline.py @@ -1,6 +1,12 @@ +"""Testcontainers integration tests for rag_pipeline controller endpoints.""" + +from __future__ import annotations + from unittest.mock import MagicMock, patch +from uuid import uuid4 import pytest +from sqlalchemy.orm import Session from controllers.console import console_ns from controllers.console.datasets.rag_pipeline.rag_pipeline import ( @@ -9,6 +15,7 @@ from controllers.console.datasets.rag_pipeline.rag_pipeline import ( PipelineTemplateListApi, PublishCustomizedPipelineTemplateApi, ) +from models.dataset import PipelineCustomizedTemplate def unwrap(func): @@ -18,6 +25,10 @@ def unwrap(func): class TestPipelineTemplateListApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_success(self, app): api = PipelineTemplateListApi() method = unwrap(api.get) @@ -38,6 +49,10 @@ class TestPipelineTemplateListApi: class TestPipelineTemplateDetailApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_success(self, app): api = PipelineTemplateDetailApi() method = unwrap(api.get) @@ -99,6 +114,10 @@ class TestPipelineTemplateDetailApi: class TestCustomizedPipelineTemplateApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_patch_success(self, app): api = CustomizedPipelineTemplateApi() method = unwrap(api.patch) @@ -136,35 +155,29 @@ class TestCustomizedPipelineTemplateApi: delete_mock.assert_called_once_with("tpl-1") assert response == 200 - def test_post_success(self, app): + def test_post_success(self, app, db_session_with_containers: Session): api = CustomizedPipelineTemplateApi() method = unwrap(api.post) - template = MagicMock() - template.yaml_content = "yaml-data" + tenant_id = str(uuid4()) + template = PipelineCustomizedTemplate( + tenant_id=tenant_id, + name="Test Template", + description="Test", + chunk_structure="hierarchical", + icon={"icon": "📘"}, + position=0, + yaml_content="yaml-data", + install_count=0, + language="en-US", + created_by=str(uuid4()), + ) + db_session_with_containers.add(template) + db_session_with_containers.commit() + db_session_with_containers.expire_all() - fake_db = MagicMock() - fake_db.engine = MagicMock() - - session = MagicMock() - session.query.return_value.where.return_value.first.return_value = template - - session_ctx = MagicMock() - session_ctx.__enter__.return_value = session - session_ctx.__exit__.return_value = None - - with ( - app.test_request_context("/"), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline.Session", - return_value=session_ctx, - ), - ): - response, status = method(api, "tpl-1") + with app.test_request_context("/"): + response, status = method(api, template.id) assert status == 200 assert response == {"data": "yaml-data"} @@ -173,32 +186,16 @@ class TestCustomizedPipelineTemplateApi: api = CustomizedPipelineTemplateApi() method = unwrap(api.post) - fake_db = MagicMock() - fake_db.engine = MagicMock() - - session = MagicMock() - session.query.return_value.where.return_value.first.return_value = None - - session_ctx = MagicMock() - session_ctx.__enter__.return_value = session - session_ctx.__exit__.return_value = None - - with ( - app.test_request_context("/"), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline.Session", - return_value=session_ctx, - ), - ): + with app.test_request_context("/"): with pytest.raises(ValueError): - method(api, "tpl-1") + method(api, str(uuid4())) class TestPublishCustomizedPipelineTemplateApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_post_success(self, app): api = PublishCustomizedPipelineTemplateApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_datasets.py b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_datasets.py similarity index 83% rename from api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_datasets.py rename to api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_datasets.py index fd38fcbb5e..64e3de2ca3 100644 --- a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_datasets.py +++ b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_datasets.py @@ -1,3 +1,7 @@ +"""Testcontainers integration tests for rag_pipeline_datasets controller endpoints.""" + +from __future__ import annotations + from unittest.mock import MagicMock, patch import pytest @@ -19,6 +23,10 @@ def unwrap(func): class TestCreateRagPipelineDatasetApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def _valid_payload(self): return {"yaml_content": "name: test"} @@ -33,13 +41,6 @@ class TestCreateRagPipelineDatasetApi: mock_service = MagicMock() mock_service.create_rag_pipeline_dataset.return_value = import_info - mock_session_ctx = MagicMock() - mock_session_ctx.__enter__.return_value = MagicMock() - mock_session_ctx.__exit__.return_value = None - - fake_db = MagicMock() - fake_db.engine = MagicMock() - with ( app.test_request_context("/", json=payload), patch.object(type(console_ns), "payload", payload), @@ -47,14 +48,6 @@ class TestCreateRagPipelineDatasetApi: "controllers.console.datasets.rag_pipeline.rag_pipeline_datasets.current_account_with_tenant", return_value=(user, "tenant-1"), ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_datasets.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_datasets.Session", - return_value=mock_session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_datasets.RagPipelineDslService", return_value=mock_service, @@ -93,13 +86,6 @@ class TestCreateRagPipelineDatasetApi: mock_service = MagicMock() mock_service.create_rag_pipeline_dataset.side_effect = services.errors.dataset.DatasetNameDuplicateError() - mock_session_ctx = MagicMock() - mock_session_ctx.__enter__.return_value = MagicMock() - mock_session_ctx.__exit__.return_value = None - - fake_db = MagicMock() - fake_db.engine = MagicMock() - with ( app.test_request_context("/", json=payload), patch.object(type(console_ns), "payload", payload), @@ -107,14 +93,6 @@ class TestCreateRagPipelineDatasetApi: "controllers.console.datasets.rag_pipeline.rag_pipeline_datasets.current_account_with_tenant", return_value=(user, "tenant-1"), ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_datasets.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_datasets.Session", - return_value=mock_session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_datasets.RagPipelineDslService", return_value=mock_service, @@ -143,6 +121,10 @@ class TestCreateRagPipelineDatasetApi: class TestCreateEmptyRagPipelineDatasetApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_post_success(self, app): api = CreateEmptyRagPipelineDatasetApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_import.py b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_import.py similarity index 66% rename from api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_import.py rename to api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_import.py index a72ad45110..cb67892878 100644 --- a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_import.py +++ b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_import.py @@ -1,5 +1,11 @@ +"""Testcontainers integration tests for rag_pipeline_import controller endpoints.""" + +from __future__ import annotations + from unittest.mock import MagicMock, patch +import pytest + from controllers.console import console_ns from controllers.console.datasets.rag_pipeline.rag_pipeline_import import ( RagPipelineExportApi, @@ -18,6 +24,10 @@ def unwrap(func): class TestRagPipelineImportApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def _payload(self, mode="create"): return { "mode": mode, @@ -30,7 +40,6 @@ class TestRagPipelineImportApi: method = unwrap(api.post) payload = self._payload() - user = MagicMock() result = MagicMock() result.status = "completed" @@ -39,13 +48,6 @@ class TestRagPipelineImportApi: service = MagicMock() service.import_rag_pipeline.return_value = result - fake_db = MagicMock() - fake_db.engine = MagicMock() - - session_ctx = MagicMock() - session_ctx.__enter__.return_value = MagicMock() - session_ctx.__exit__.return_value = None - with ( app.test_request_context("/", json=payload), patch.object(type(console_ns), "payload", payload), @@ -53,14 +55,6 @@ class TestRagPipelineImportApi: "controllers.console.datasets.rag_pipeline.rag_pipeline_import.current_account_with_tenant", return_value=(user, "tenant"), ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_import.RagPipelineDslService", return_value=service, @@ -76,7 +70,6 @@ class TestRagPipelineImportApi: method = unwrap(api.post) payload = self._payload() - user = MagicMock() result = MagicMock() result.status = ImportStatus.FAILED @@ -85,13 +78,6 @@ class TestRagPipelineImportApi: service = MagicMock() service.import_rag_pipeline.return_value = result - fake_db = MagicMock() - fake_db.engine = MagicMock() - - session_ctx = MagicMock() - session_ctx.__enter__.return_value = MagicMock() - session_ctx.__exit__.return_value = None - with ( app.test_request_context("/", json=payload), patch.object(type(console_ns), "payload", payload), @@ -99,14 +85,6 @@ class TestRagPipelineImportApi: "controllers.console.datasets.rag_pipeline.rag_pipeline_import.current_account_with_tenant", return_value=(user, "tenant"), ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_import.RagPipelineDslService", return_value=service, @@ -122,7 +100,6 @@ class TestRagPipelineImportApi: method = unwrap(api.post) payload = self._payload() - user = MagicMock() result = MagicMock() result.status = ImportStatus.PENDING @@ -131,13 +108,6 @@ class TestRagPipelineImportApi: service = MagicMock() service.import_rag_pipeline.return_value = result - fake_db = MagicMock() - fake_db.engine = MagicMock() - - session_ctx = MagicMock() - session_ctx.__enter__.return_value = MagicMock() - session_ctx.__exit__.return_value = None - with ( app.test_request_context("/", json=payload), patch.object(type(console_ns), "payload", payload), @@ -145,14 +115,6 @@ class TestRagPipelineImportApi: "controllers.console.datasets.rag_pipeline.rag_pipeline_import.current_account_with_tenant", return_value=(user, "tenant"), ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_import.RagPipelineDslService", return_value=service, @@ -165,6 +127,10 @@ class TestRagPipelineImportApi: class TestRagPipelineImportConfirmApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_confirm_success(self, app): api = RagPipelineImportConfirmApi() method = unwrap(api.post) @@ -177,27 +143,12 @@ class TestRagPipelineImportConfirmApi: service = MagicMock() service.confirm_import.return_value = result - fake_db = MagicMock() - fake_db.engine = MagicMock() - - session_ctx = MagicMock() - session_ctx.__enter__.return_value = MagicMock() - session_ctx.__exit__.return_value = None - with ( app.test_request_context("/"), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_import.current_account_with_tenant", return_value=(user, "tenant"), ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_import.RagPipelineDslService", return_value=service, @@ -220,27 +171,12 @@ class TestRagPipelineImportConfirmApi: service = MagicMock() service.confirm_import.return_value = result - fake_db = MagicMock() - fake_db.engine = MagicMock() - - session_ctx = MagicMock() - session_ctx.__enter__.return_value = MagicMock() - session_ctx.__exit__.return_value = None - with ( app.test_request_context("/"), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_import.current_account_with_tenant", return_value=(user, "tenant"), ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_import.RagPipelineDslService", return_value=service, @@ -253,6 +189,10 @@ class TestRagPipelineImportConfirmApi: class TestRagPipelineImportCheckDependenciesApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_success(self, app): api = RagPipelineImportCheckDependenciesApi() method = unwrap(api.get) @@ -264,23 +204,8 @@ class TestRagPipelineImportCheckDependenciesApi: service = MagicMock() service.check_dependencies.return_value = result - fake_db = MagicMock() - fake_db.engine = MagicMock() - - session_ctx = MagicMock() - session_ctx.__enter__.return_value = MagicMock() - session_ctx.__exit__.return_value = None - with ( app.test_request_context("/"), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_import.RagPipelineDslService", return_value=service, @@ -293,6 +218,10 @@ class TestRagPipelineImportCheckDependenciesApi: class TestRagPipelineExportApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_with_include_secret(self, app): api = RagPipelineExportApi() method = unwrap(api.get) @@ -301,23 +230,8 @@ class TestRagPipelineExportApi: service = MagicMock() service.export_rag_pipeline_dsl.return_value = {"yaml": "data"} - fake_db = MagicMock() - fake_db.engine = MagicMock() - - session_ctx = MagicMock() - session_ctx.__enter__.return_value = MagicMock() - session_ctx.__exit__.return_value = None - with ( app.test_request_context("/?include_secret=true"), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_import.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_import.RagPipelineDslService", return_value=service, diff --git a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_workflow.py b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_workflow.py similarity index 91% rename from api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_workflow.py rename to api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_workflow.py index a3c0592d76..c1f3122c2b 100644 --- a/api/tests/unit_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_workflow.py +++ b/api/tests/test_containers_integration_tests/controllers/console/datasets/rag_pipeline/test_rag_pipeline_workflow.py @@ -1,7 +1,13 @@ +"""Testcontainers integration tests for rag_pipeline_workflow controller endpoints.""" + +from __future__ import annotations + from datetime import datetime from unittest.mock import MagicMock, patch +from uuid import uuid4 import pytest +from sqlalchemy.orm import Session from werkzeug.exceptions import BadRequest, Forbidden, HTTPException, NotFound import services @@ -38,6 +44,10 @@ def unwrap(func): class TestDraftWorkflowApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_draft_success(self, app): api = DraftRagPipelineApi() method = unwrap(api.get) @@ -200,6 +210,10 @@ class TestDraftWorkflowApi: class TestDraftRunNodes: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_iteration_node_success(self, app): api = RagPipelineDraftRunIterationNodeApi() method = unwrap(api.post) @@ -275,6 +289,10 @@ class TestDraftRunNodes: class TestPipelineRunApis: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_draft_run_success(self, app): api = DraftRagPipelineRunApi() method = unwrap(api.post) @@ -337,6 +355,10 @@ class TestPipelineRunApis: class TestDraftNodeRun: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_execution_not_found(self, app): api = RagPipelineDraftNodeRunApi() method = unwrap(api.post) @@ -364,45 +386,43 @@ class TestDraftNodeRun: class TestPublishedPipelineApis: - def test_publish_success(self, app): + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_publish_success(self, app, db_session_with_containers: Session): + from models.dataset import Pipeline + api = PublishedRagPipelineApi() method = unwrap(api.post) - pipeline = MagicMock() + tenant_id = str(uuid4()) + pipeline = Pipeline( + tenant_id=tenant_id, + name="test-pipeline", + description="test", + created_by=str(uuid4()), + ) + db_session_with_containers.add(pipeline) + db_session_with_containers.commit() + db_session_with_containers.expire_all() + user = MagicMock(id="u1") workflow = MagicMock( - id="w1", + id=str(uuid4()), created_at=naive_utc_now(), ) - session = MagicMock() - session.merge.return_value = pipeline - - session_ctx = MagicMock() - session_ctx.__enter__.return_value = session - session_ctx.__exit__.return_value = None - service = MagicMock() service.publish_workflow.return_value = workflow - fake_db = MagicMock() - fake_db.engine = MagicMock() - with ( app.test_request_context("/"), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.current_account_with_tenant", return_value=(user, "t"), ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.RagPipelineService", return_value=service, @@ -415,6 +435,10 @@ class TestPublishedPipelineApis: class TestMiscApis: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_task_stop(self, app): api = RagPipelineTaskStopApi() method = unwrap(api.post) @@ -471,6 +495,10 @@ class TestMiscApis: class TestPublishedRagPipelineRunApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_published_run_success(self, app): api = PublishedRagPipelineRunApi() method = unwrap(api.post) @@ -536,6 +564,10 @@ class TestPublishedRagPipelineRunApi: class TestDefaultBlockConfigApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_block_config_success(self, app): api = DefaultRagPipelineBlockConfigApi() method = unwrap(api.get) @@ -567,6 +599,10 @@ class TestDefaultBlockConfigApi: class TestPublishedAllRagPipelineApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_published_workflows_success(self, app): api = PublishedAllRagPipelineApi() method = unwrap(api.get) @@ -577,28 +613,12 @@ class TestPublishedAllRagPipelineApi: service = MagicMock() service.get_all_published_workflow.return_value = ([{"id": "w1"}], False) - session = MagicMock() - session_ctx = MagicMock() - session_ctx.__enter__.return_value = session - session_ctx.__exit__.return_value = None - - fake_db = MagicMock() - fake_db.engine = MagicMock() - with ( app.test_request_context("/"), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.current_account_with_tenant", return_value=(user, "t"), ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.RagPipelineService", return_value=service, @@ -628,6 +648,10 @@ class TestPublishedAllRagPipelineApi: class TestRagPipelineByIdApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_patch_success(self, app): api = RagPipelineByIdApi() method = unwrap(api.patch) @@ -640,14 +664,6 @@ class TestRagPipelineByIdApi: service = MagicMock() service.update_workflow.return_value = workflow - session = MagicMock() - session_ctx = MagicMock() - session_ctx.__enter__.return_value = session - session_ctx.__exit__.return_value = None - - fake_db = MagicMock() - fake_db.engine = MagicMock() - payload = {"marked_name": "test"} with ( @@ -657,14 +673,6 @@ class TestRagPipelineByIdApi: "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.current_account_with_tenant", return_value=(user, "t"), ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.RagPipelineService", return_value=service, @@ -700,24 +708,8 @@ class TestRagPipelineByIdApi: workflow_service = MagicMock() - session = MagicMock() - session_ctx = MagicMock() - session_ctx.__enter__.return_value = session - session_ctx.__exit__.return_value = None - - fake_db = MagicMock() - fake_db.engine = MagicMock() - with ( app.test_request_context("/", method="DELETE"), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.db", - fake_db, - ), - patch( - "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.Session", - return_value=session_ctx, - ), patch( "controllers.console.datasets.rag_pipeline.rag_pipeline_workflow.WorkflowService", return_value=workflow_service, @@ -725,12 +717,7 @@ class TestRagPipelineByIdApi: ): result = method(api, pipeline, "old-workflow") - workflow_service.delete_workflow.assert_called_once_with( - session=session, - workflow_id="old-workflow", - tenant_id="t1", - ) - session.commit.assert_called_once() + workflow_service.delete_workflow.assert_called_once() assert result == (None, 204) def test_delete_active_workflow_rejected(self, app): @@ -745,6 +732,10 @@ class TestRagPipelineByIdApi: class TestRagPipelineWorkflowLastRunApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_last_run_success(self, app): api = RagPipelineWorkflowLastRunApi() method = unwrap(api.get) @@ -788,6 +779,10 @@ class TestRagPipelineWorkflowLastRunApi: class TestRagPipelineDatasourceVariableApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_set_datasource_variables_success(self, app): api = RagPipelineDatasourceVariableApi() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/datasets/test_data_source.py b/api/tests/test_containers_integration_tests/controllers/console/datasets/test_data_source.py similarity index 95% rename from api/tests/unit_tests/controllers/console/datasets/test_data_source.py rename to api/tests/test_containers_integration_tests/controllers/console/datasets/test_data_source.py index d841f67f9b..1c07d4ca1c 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_data_source.py +++ b/api/tests/test_containers_integration_tests/controllers/console/datasets/test_data_source.py @@ -1,3 +1,7 @@ +"""Testcontainers integration tests for controllers.console.datasets.data_source endpoints.""" + +from __future__ import annotations + from unittest.mock import MagicMock, PropertyMock, patch import pytest @@ -46,6 +50,10 @@ def mock_engine(): class TestDataSourceApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_success(self, app, patch_tenant): api = DataSourceApi() method = unwrap(api.get) @@ -179,6 +187,10 @@ class TestDataSourceApi: class TestDataSourceNotionListApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_credential_not_found(self, app, patch_tenant): api = DataSourceNotionListApi() method = unwrap(api.get) @@ -310,6 +322,10 @@ class TestDataSourceNotionListApi: class TestDataSourceNotionApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_preview_success(self, app, patch_tenant): api = DataSourceNotionApi() method = unwrap(api.get) @@ -364,6 +380,10 @@ class TestDataSourceNotionApi: class TestDataSourceNotionDatasetSyncApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_success(self, app, patch_tenant): api = DataSourceNotionDatasetSyncApi() method = unwrap(api.get) @@ -403,6 +423,10 @@ class TestDataSourceNotionDatasetSyncApi: class TestDataSourceNotionDocumentSyncApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_success(self, app, patch_tenant): api = DataSourceNotionDocumentSyncApi() method = unwrap(api.get) diff --git a/api/tests/unit_tests/controllers/console/explore/test_conversation.py b/api/tests/test_containers_integration_tests/controllers/console/explore/test_conversation.py similarity index 82% rename from api/tests/unit_tests/controllers/console/explore/test_conversation.py rename to api/tests/test_containers_integration_tests/controllers/console/explore/test_conversation.py index 65cc209725..83492048ef 100644 --- a/api/tests/unit_tests/controllers/console/explore/test_conversation.py +++ b/api/tests/test_containers_integration_tests/controllers/console/explore/test_conversation.py @@ -1,7 +1,10 @@ +"""Testcontainers integration tests for controllers.console.explore.conversation endpoints.""" + +from __future__ import annotations + from unittest.mock import MagicMock, patch import pytest -from flask import Flask from werkzeug.exceptions import NotFound import controllers.console.explore.conversation as conversation_module @@ -48,24 +51,12 @@ def user(): return user -@pytest.fixture(autouse=True) -def mock_db_and_session(): - with ( - patch.object( - conversation_module, - "db", - MagicMock(session=MagicMock(), engine=MagicMock()), - ), - patch( - "controllers.console.explore.conversation.Session", - MagicMock(), - ), - ): - yield - - class TestConversationListApi: - def test_get_success(self, app: Flask, chat_app, user): + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_get_success(self, app, chat_app, user): api = conversation_module.ConversationListApi() method = unwrap(api.get) @@ -90,7 +81,7 @@ class TestConversationListApi: assert result["has_more"] is False assert len(result["data"]) == 2 - def test_last_conversation_not_exists(self, app: Flask, chat_app, user): + def test_last_conversation_not_exists(self, app, chat_app, user): api = conversation_module.ConversationListApi() method = unwrap(api.get) @@ -106,7 +97,7 @@ class TestConversationListApi: with pytest.raises(NotFound): method(chat_app) - def test_wrong_app_mode(self, app: Flask, non_chat_app): + def test_wrong_app_mode(self, app, non_chat_app): api = conversation_module.ConversationListApi() method = unwrap(api.get) @@ -116,7 +107,11 @@ class TestConversationListApi: class TestConversationApi: - def test_delete_success(self, app: Flask, chat_app, user): + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_delete_success(self, app, chat_app, user): api = conversation_module.ConversationApi() method = unwrap(api.delete) @@ -134,7 +129,7 @@ class TestConversationApi: assert status == 204 assert body["result"] == "success" - def test_delete_not_found(self, app: Flask, chat_app, user): + def test_delete_not_found(self, app, chat_app, user): api = conversation_module.ConversationApi() method = unwrap(api.delete) @@ -150,7 +145,7 @@ class TestConversationApi: with pytest.raises(NotFound): method(chat_app, "cid") - def test_delete_wrong_app_mode(self, app: Flask, non_chat_app): + def test_delete_wrong_app_mode(self, app, non_chat_app): api = conversation_module.ConversationApi() method = unwrap(api.delete) @@ -160,7 +155,11 @@ class TestConversationApi: class TestConversationRenameApi: - def test_rename_success(self, app: Flask, chat_app, user): + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_rename_success(self, app, chat_app, user): api = conversation_module.ConversationRenameApi() method = unwrap(api.post) @@ -179,7 +178,7 @@ class TestConversationRenameApi: assert result["id"] == "cid" - def test_rename_not_found(self, app: Flask, chat_app, user): + def test_rename_not_found(self, app, chat_app, user): api = conversation_module.ConversationRenameApi() method = unwrap(api.post) @@ -197,7 +196,11 @@ class TestConversationRenameApi: class TestConversationPinApi: - def test_pin_success(self, app: Flask, chat_app, user): + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_pin_success(self, app, chat_app, user): api = conversation_module.ConversationPinApi() method = unwrap(api.patch) @@ -215,7 +218,11 @@ class TestConversationPinApi: class TestConversationUnPinApi: - def test_unpin_success(self, app: Flask, chat_app, user): + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_unpin_success(self, app, chat_app, user): api = conversation_module.ConversationUnPinApi() method = unwrap(api.patch) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_tool_provider.py b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_tool_provider.py similarity index 95% rename from api/tests/unit_tests/controllers/console/workspace/test_tool_provider.py rename to api/tests/test_containers_integration_tests/controllers/console/workspace/test_tool_provider.py index 16ea1bf509..e36bd213d9 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_tool_provider.py +++ b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_tool_provider.py @@ -1,9 +1,11 @@ +"""Testcontainers integration tests for controllers.console.workspace.tool_providers endpoints.""" + +from __future__ import annotations + import json from unittest.mock import MagicMock, patch import pytest -from flask import Flask -from flask_restx import Api from werkzeug.exceptions import Forbidden from controllers.console.workspace.tool_providers import ( @@ -31,7 +33,6 @@ from controllers.console.workspace.tool_providers import ( ToolOAuthCustomClient, ToolPluginOAuthApi, ToolProviderListApi, - ToolProviderMCPApi, ToolWorkflowListApi, ToolWorkflowProviderCreateApi, ToolWorkflowProviderDeleteApi, @@ -39,8 +40,6 @@ from controllers.console.workspace.tool_providers import ( ToolWorkflowProviderUpdateApi, is_valid_url, ) -from core.db.session_factory import configure_session_factory -from extensions.ext_database import db from services.tools.mcp_tools_manage_service import ReconnectResult @@ -61,17 +60,8 @@ def _mock_user_tenant(): @pytest.fixture -def client(): - app = Flask(__name__) - app.config["TESTING"] = True - app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:" - api = Api(app) - api.add_resource(ToolProviderMCPApi, "/console/api/workspaces/current/tool-provider/mcp") - db.init_app(app) - # Configure session factory used by controller code - with app.app_context(): - configure_session_factory(db.engine) - return app.test_client() +def client(flask_app_with_containers): + return flask_app_with_containers.test_client() @patch( @@ -152,10 +142,14 @@ class TestUtils: assert not is_valid_url("") assert not is_valid_url("ftp://example.com") assert not is_valid_url("not-a-url") - assert not is_valid_url(None) + assert not is_valid_url(None) # type: ignore[arg-type] class TestToolProviderListApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_success(self, app): api = ToolProviderListApi() method = unwrap(api.get) @@ -175,6 +169,10 @@ class TestToolProviderListApi: class TestBuiltinProviderApis: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_list_tools(self, app): api = ToolBuiltinProviderListToolsApi() method = unwrap(api.get) @@ -379,6 +377,10 @@ class TestBuiltinProviderApis: class TestApiProviderApis: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_add(self, app): api = ToolApiProviderAddApi() method = unwrap(api.post) @@ -502,6 +504,10 @@ class TestApiProviderApis: class TestWorkflowApis: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_create(self, app): api = ToolWorkflowProviderCreateApi() method = unwrap(api.post) @@ -587,6 +593,10 @@ class TestWorkflowApis: class TestLists: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_builtin_list(self, app): api = ToolBuiltinListApi() method = unwrap(api.get) @@ -649,6 +659,10 @@ class TestLists: class TestLabels: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_labels(self, app): api = ToolLabelsApi() method = unwrap(api.get) @@ -664,6 +678,10 @@ class TestLabels: class TestOAuth: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_oauth_no_client(self, app): api = ToolPluginOAuthApi() method = unwrap(api.get) @@ -692,6 +710,10 @@ class TestOAuth: class TestOAuthCustomClient: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_save_custom_client(self, app): api = ToolOAuthCustomClient() method = unwrap(api.post) diff --git a/api/tests/unit_tests/controllers/console/workspace/test_trigger_providers.py b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py similarity index 95% rename from api/tests/unit_tests/controllers/console/workspace/test_trigger_providers.py rename to api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py index 4776bc7af0..b4d12bff62 100644 --- a/api/tests/unit_tests/controllers/console/workspace/test_trigger_providers.py +++ b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_trigger_providers.py @@ -1,3 +1,7 @@ +"""Testcontainers integration tests for controllers.console.workspace.trigger_providers endpoints.""" + +from __future__ import annotations + from unittest.mock import MagicMock, patch import pytest @@ -40,6 +44,10 @@ def mock_user(): class TestTriggerProviderApis: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_icon_success(self, app): api = TriggerProviderIconApi() method = unwrap(api.get) @@ -84,6 +92,10 @@ class TestTriggerProviderApis: class TestTriggerSubscriptionListApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_list_success(self, app): api = TriggerSubscriptionListApi() method = unwrap(api.get) @@ -115,6 +127,10 @@ class TestTriggerSubscriptionListApi: class TestTriggerSubscriptionBuilderApis: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_create_builder(self, app): api = TriggerSubscriptionBuilderCreateApi() method = unwrap(api.post) @@ -219,6 +235,10 @@ class TestTriggerSubscriptionBuilderApis: class TestTriggerSubscriptionCrud: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_update_rename_only(self, app): api = TriggerSubscriptionUpdateApi() method = unwrap(api.post) @@ -321,6 +341,10 @@ class TestTriggerSubscriptionCrud: class TestTriggerOAuthApis: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_oauth_authorize_success(self, app): api = TriggerOAuthAuthorizeApi() method = unwrap(api.get) @@ -455,6 +479,10 @@ class TestTriggerOAuthApis: class TestTriggerOAuthClientManageApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_get_client(self, app): api = TriggerOAuthClientManageApi() method = unwrap(api.get) @@ -527,6 +555,10 @@ class TestTriggerOAuthClientManageApi: class TestTriggerSubscriptionVerifyApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + def test_verify_success(self, app): api = TriggerSubscriptionVerifyApi() method = unwrap(api.post) diff --git a/api/tests/test_containers_integration_tests/controllers/console/workspace/test_workspace_wraps.py b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_workspace_wraps.py new file mode 100644 index 0000000000..99cabb6cea --- /dev/null +++ b/api/tests/test_containers_integration_tests/controllers/console/workspace/test_workspace_wraps.py @@ -0,0 +1,185 @@ +"""Testcontainers integration tests for plugin_permission_required decorator.""" + +from __future__ import annotations + +from types import SimpleNamespace +from unittest.mock import patch + +import pytest +from sqlalchemy.orm import Session +from werkzeug.exceptions import Forbidden + +from controllers.console.workspace import plugin_permission_required +from models.account import Tenant, TenantPluginPermission, TenantStatus + + +def _create_tenant(db_session: Session) -> Tenant: + tenant = Tenant(name="test-tenant", status=TenantStatus.NORMAL, plan="basic") + db_session.add(tenant) + db_session.commit() + db_session.expire_all() + return tenant + + +def _create_permission( + db_session: Session, + tenant_id: str, + install: TenantPluginPermission.InstallPermission = TenantPluginPermission.InstallPermission.EVERYONE, + debug: TenantPluginPermission.DebugPermission = TenantPluginPermission.DebugPermission.EVERYONE, +) -> TenantPluginPermission: + perm = TenantPluginPermission( + tenant_id=tenant_id, + install_permission=install, + debug_permission=debug, + ) + db_session.add(perm) + db_session.commit() + db_session.expire_all() + return perm + + +class TestPluginPermissionRequired: + def test_allows_without_permission(self, db_session_with_containers: Session): + tenant = _create_tenant(db_session_with_containers) + user = SimpleNamespace(is_admin_or_owner=False) + + with patch( + "controllers.console.workspace.current_account_with_tenant", + return_value=(user, tenant.id), + ): + + @plugin_permission_required() + def handler(): + return "ok" + + assert handler() == "ok" + + def test_install_nobody_forbidden(self, db_session_with_containers: Session): + tenant = _create_tenant(db_session_with_containers) + _create_permission( + db_session_with_containers, + tenant.id, + install=TenantPluginPermission.InstallPermission.NOBODY, + debug=TenantPluginPermission.DebugPermission.EVERYONE, + ) + user = SimpleNamespace(is_admin_or_owner=True) + + with patch( + "controllers.console.workspace.current_account_with_tenant", + return_value=(user, tenant.id), + ): + + @plugin_permission_required(install_required=True) + def handler(): + return "ok" + + with pytest.raises(Forbidden): + handler() + + def test_install_admin_requires_admin(self, db_session_with_containers: Session): + tenant = _create_tenant(db_session_with_containers) + _create_permission( + db_session_with_containers, + tenant.id, + install=TenantPluginPermission.InstallPermission.ADMINS, + debug=TenantPluginPermission.DebugPermission.EVERYONE, + ) + user = SimpleNamespace(is_admin_or_owner=False) + + with patch( + "controllers.console.workspace.current_account_with_tenant", + return_value=(user, tenant.id), + ): + + @plugin_permission_required(install_required=True) + def handler(): + return "ok" + + with pytest.raises(Forbidden): + handler() + + def test_install_admin_allows_admin(self, db_session_with_containers: Session): + tenant = _create_tenant(db_session_with_containers) + _create_permission( + db_session_with_containers, + tenant.id, + install=TenantPluginPermission.InstallPermission.ADMINS, + debug=TenantPluginPermission.DebugPermission.EVERYONE, + ) + user = SimpleNamespace(is_admin_or_owner=True) + + with patch( + "controllers.console.workspace.current_account_with_tenant", + return_value=(user, tenant.id), + ): + + @plugin_permission_required(install_required=True) + def handler(): + return "ok" + + assert handler() == "ok" + + def test_debug_nobody_forbidden(self, db_session_with_containers: Session): + tenant = _create_tenant(db_session_with_containers) + _create_permission( + db_session_with_containers, + tenant.id, + install=TenantPluginPermission.InstallPermission.EVERYONE, + debug=TenantPluginPermission.DebugPermission.NOBODY, + ) + user = SimpleNamespace(is_admin_or_owner=True) + + with patch( + "controllers.console.workspace.current_account_with_tenant", + return_value=(user, tenant.id), + ): + + @plugin_permission_required(debug_required=True) + def handler(): + return "ok" + + with pytest.raises(Forbidden): + handler() + + def test_debug_admin_requires_admin(self, db_session_with_containers: Session): + tenant = _create_tenant(db_session_with_containers) + _create_permission( + db_session_with_containers, + tenant.id, + install=TenantPluginPermission.InstallPermission.EVERYONE, + debug=TenantPluginPermission.DebugPermission.ADMINS, + ) + user = SimpleNamespace(is_admin_or_owner=False) + + with patch( + "controllers.console.workspace.current_account_with_tenant", + return_value=(user, tenant.id), + ): + + @plugin_permission_required(debug_required=True) + def handler(): + return "ok" + + with pytest.raises(Forbidden): + handler() + + def test_debug_admin_allows_admin(self, db_session_with_containers: Session): + tenant = _create_tenant(db_session_with_containers) + _create_permission( + db_session_with_containers, + tenant.id, + install=TenantPluginPermission.InstallPermission.EVERYONE, + debug=TenantPluginPermission.DebugPermission.ADMINS, + ) + user = SimpleNamespace(is_admin_or_owner=True) + + with patch( + "controllers.console.workspace.current_account_with_tenant", + return_value=(user, tenant.id), + ): + + @plugin_permission_required(debug_required=True) + def handler(): + return "ok" + + assert handler() == "ok" diff --git a/api/tests/unit_tests/controllers/mcp/test_mcp.py b/api/tests/test_containers_integration_tests/controllers/mcp/test_mcp.py similarity index 96% rename from api/tests/unit_tests/controllers/mcp/test_mcp.py rename to api/tests/test_containers_integration_tests/controllers/mcp/test_mcp.py index b93770e9c2..90670a9db5 100644 --- a/api/tests/unit_tests/controllers/mcp/test_mcp.py +++ b/api/tests/test_containers_integration_tests/controllers/mcp/test_mcp.py @@ -1,5 +1,10 @@ +"""Testcontainers integration tests for controllers.mcp.mcp endpoints.""" + +from __future__ import annotations + import types from unittest.mock import MagicMock, patch +from uuid import uuid4 import pytest from flask import Response @@ -14,24 +19,6 @@ def unwrap(func): return func -@pytest.fixture(autouse=True) -def mock_db(): - module.db = types.SimpleNamespace(engine=object()) - - -@pytest.fixture -def fake_session(): - session = MagicMock() - session.__enter__.return_value = session - session.__exit__.return_value = False - return session - - -@pytest.fixture(autouse=True) -def mock_session(fake_session): - module.Session = MagicMock(return_value=fake_session) - - @pytest.fixture(autouse=True) def mock_mcp_ns(): fake_ns = types.SimpleNamespace() @@ -44,8 +31,13 @@ def fake_payload(data): module.mcp_ns.payload = data +_TENANT_ID = str(uuid4()) +_APP_ID = str(uuid4()) +_SERVER_ID = str(uuid4()) + + class DummyServer: - def __init__(self, status, app_id="app-1", tenant_id="tenant-1", server_id="srv-1"): + def __init__(self, status, app_id=_APP_ID, tenant_id=_TENANT_ID, server_id=_SERVER_ID): self.status = status self.app_id = app_id self.tenant_id = tenant_id @@ -54,8 +46,8 @@ class DummyServer: class DummyApp: def __init__(self, mode, workflow=None, app_model_config=None): - self.id = "app-1" - self.tenant_id = "tenant-1" + self.id = _APP_ID + self.tenant_id = _TENANT_ID self.mode = mode self.workflow = workflow self.app_model_config = app_model_config @@ -76,6 +68,7 @@ class DummyResult: return {"jsonrpc": "2.0", "result": "ok", "id": 1} +@pytest.mark.usefixtures("flask_req_ctx_with_containers") class TestMCPAppApi: @patch.object(module, "handle_mcp_request", return_value=DummyResult(), autospec=True) def test_success_request(self, mock_handle): diff --git a/api/tests/unit_tests/controllers/web/test_conversation.py b/api/tests/test_containers_integration_tests/controllers/web/test_conversation.py similarity index 72% rename from api/tests/unit_tests/controllers/web/test_conversation.py rename to api/tests/test_containers_integration_tests/controllers/web/test_conversation.py index e5adbbbf66..e1e6741014 100644 --- a/api/tests/unit_tests/controllers/web/test_conversation.py +++ b/api/tests/test_containers_integration_tests/controllers/web/test_conversation.py @@ -1,4 +1,4 @@ -"""Unit tests for controllers.web.conversation endpoints.""" +"""Testcontainers integration tests for controllers.web.conversation endpoints.""" from __future__ import annotations @@ -7,7 +7,6 @@ from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest -from flask import Flask from werkzeug.exceptions import NotFound from controllers.web.conversation import ( @@ -33,18 +32,18 @@ def _end_user() -> SimpleNamespace: return SimpleNamespace(id="eu-1") -# --------------------------------------------------------------------------- -# ConversationListApi -# --------------------------------------------------------------------------- class TestConversationListApi: - def test_non_chat_mode_raises(self, app: Flask) -> None: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_non_chat_mode_raises(self, app) -> None: with app.test_request_context("/conversations"): with pytest.raises(NotChatAppError): ConversationListApi().get(_completion_app(), _end_user()) @patch("controllers.web.conversation.WebConversationService.pagination_by_last_id") - @patch("controllers.web.conversation.db") - def test_happy_path(self, mock_db: MagicMock, mock_paginate: MagicMock, app: Flask) -> None: + def test_happy_path(self, mock_paginate: MagicMock, app) -> None: conv_id = str(uuid4()) conv = SimpleNamespace( id=conv_id, @@ -56,34 +55,26 @@ class TestConversationListApi: updated_at=1700000000, ) mock_paginate.return_value = SimpleNamespace(limit=20, has_more=False, data=[conv]) - mock_db.engine = "engine" - session_mock = MagicMock() - session_ctx = MagicMock() - session_ctx.__enter__ = MagicMock(return_value=session_mock) - session_ctx.__exit__ = MagicMock(return_value=False) - - with ( - app.test_request_context("/conversations?limit=20"), - patch("controllers.web.conversation.Session", return_value=session_ctx), - ): + with app.test_request_context("/conversations?limit=20"): result = ConversationListApi().get(_chat_app(), _end_user()) assert result["limit"] == 20 assert result["has_more"] is False -# --------------------------------------------------------------------------- -# ConversationApi (delete) -# --------------------------------------------------------------------------- class TestConversationApi: - def test_non_chat_mode_raises(self, app: Flask) -> None: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_non_chat_mode_raises(self, app) -> None: with app.test_request_context(f"/conversations/{uuid4()}"): with pytest.raises(NotChatAppError): ConversationApi().delete(_completion_app(), _end_user(), uuid4()) @patch("controllers.web.conversation.ConversationService.delete") - def test_delete_success(self, mock_delete: MagicMock, app: Flask) -> None: + def test_delete_success(self, mock_delete: MagicMock, app) -> None: c_id = uuid4() with app.test_request_context(f"/conversations/{c_id}"): result, status = ConversationApi().delete(_chat_app(), _end_user(), c_id) @@ -92,25 +83,26 @@ class TestConversationApi: assert result["result"] == "success" @patch("controllers.web.conversation.ConversationService.delete", side_effect=ConversationNotExistsError()) - def test_delete_not_found(self, mock_delete: MagicMock, app: Flask) -> None: + def test_delete_not_found(self, mock_delete: MagicMock, app) -> None: c_id = uuid4() with app.test_request_context(f"/conversations/{c_id}"): with pytest.raises(NotFound, match="Conversation Not Exists"): ConversationApi().delete(_chat_app(), _end_user(), c_id) -# --------------------------------------------------------------------------- -# ConversationRenameApi -# --------------------------------------------------------------------------- class TestConversationRenameApi: - def test_non_chat_mode_raises(self, app: Flask) -> None: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_non_chat_mode_raises(self, app) -> None: with app.test_request_context(f"/conversations/{uuid4()}/name", method="POST", json={"name": "x"}): with pytest.raises(NotChatAppError): ConversationRenameApi().post(_completion_app(), _end_user(), uuid4()) @patch("controllers.web.conversation.ConversationService.rename") @patch("controllers.web.conversation.web_ns") - def test_rename_success(self, mock_ns: MagicMock, mock_rename: MagicMock, app: Flask) -> None: + def test_rename_success(self, mock_ns: MagicMock, mock_rename: MagicMock, app) -> None: c_id = uuid4() mock_ns.payload = {"name": "New Name", "auto_generate": False} conv = SimpleNamespace( @@ -134,7 +126,7 @@ class TestConversationRenameApi: side_effect=ConversationNotExistsError(), ) @patch("controllers.web.conversation.web_ns") - def test_rename_not_found(self, mock_ns: MagicMock, mock_rename: MagicMock, app: Flask) -> None: + def test_rename_not_found(self, mock_ns: MagicMock, mock_rename: MagicMock, app) -> None: c_id = uuid4() mock_ns.payload = {"name": "X", "auto_generate": False} @@ -143,17 +135,18 @@ class TestConversationRenameApi: ConversationRenameApi().post(_chat_app(), _end_user(), c_id) -# --------------------------------------------------------------------------- -# ConversationPinApi / ConversationUnPinApi -# --------------------------------------------------------------------------- class TestConversationPinApi: - def test_non_chat_mode_raises(self, app: Flask) -> None: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_non_chat_mode_raises(self, app) -> None: with app.test_request_context(f"/conversations/{uuid4()}/pin", method="PATCH"): with pytest.raises(NotChatAppError): ConversationPinApi().patch(_completion_app(), _end_user(), uuid4()) @patch("controllers.web.conversation.WebConversationService.pin") - def test_pin_success(self, mock_pin: MagicMock, app: Flask) -> None: + def test_pin_success(self, mock_pin: MagicMock, app) -> None: c_id = uuid4() with app.test_request_context(f"/conversations/{c_id}/pin", method="PATCH"): result = ConversationPinApi().patch(_chat_app(), _end_user(), c_id) @@ -161,7 +154,7 @@ class TestConversationPinApi: assert result["result"] == "success" @patch("controllers.web.conversation.WebConversationService.pin", side_effect=ConversationNotExistsError()) - def test_pin_not_found(self, mock_pin: MagicMock, app: Flask) -> None: + def test_pin_not_found(self, mock_pin: MagicMock, app) -> None: c_id = uuid4() with app.test_request_context(f"/conversations/{c_id}/pin", method="PATCH"): with pytest.raises(NotFound): @@ -169,13 +162,17 @@ class TestConversationPinApi: class TestConversationUnPinApi: - def test_non_chat_mode_raises(self, app: Flask) -> None: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def test_non_chat_mode_raises(self, app) -> None: with app.test_request_context(f"/conversations/{uuid4()}/unpin", method="PATCH"): with pytest.raises(NotChatAppError): ConversationUnPinApi().patch(_completion_app(), _end_user(), uuid4()) @patch("controllers.web.conversation.WebConversationService.unpin") - def test_unpin_success(self, mock_unpin: MagicMock, app: Flask) -> None: + def test_unpin_success(self, mock_unpin: MagicMock, app) -> None: c_id = uuid4() with app.test_request_context(f"/conversations/{c_id}/unpin", method="PATCH"): result = ConversationUnPinApi().patch(_chat_app(), _end_user(), c_id) diff --git a/api/tests/unit_tests/controllers/web/test_web_forgot_password.py b/api/tests/test_containers_integration_tests/controllers/web/test_web_forgot_password.py similarity index 95% rename from api/tests/unit_tests/controllers/web/test_web_forgot_password.py rename to api/tests/test_containers_integration_tests/controllers/web/test_web_forgot_password.py index 3d7c319947..19057726c3 100644 --- a/api/tests/unit_tests/controllers/web/test_web_forgot_password.py +++ b/api/tests/test_containers_integration_tests/controllers/web/test_web_forgot_password.py @@ -1,9 +1,12 @@ +"""Testcontainers integration tests for controllers.web.forgot_password endpoints.""" + +from __future__ import annotations + import base64 from types import SimpleNamespace from unittest.mock import MagicMock, patch import pytest -from flask import Flask from controllers.web.forgot_password import ( ForgotPasswordCheckApi, @@ -12,13 +15,6 @@ from controllers.web.forgot_password import ( ) -@pytest.fixture -def app(): - flask_app = Flask(__name__) - flask_app.config["TESTING"] = True - return flask_app - - @pytest.fixture(autouse=True) def _patch_wraps(): wraps_features = SimpleNamespace(enable_email_password_login=True) @@ -33,6 +29,10 @@ def _patch_wraps(): class TestForgotPasswordSendEmailApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + @patch("controllers.web.forgot_password.AccountService.send_reset_password_email") @patch("controllers.web.forgot_password.AccountService.get_account_by_email_with_case_fallback") @patch("controllers.web.forgot_password.AccountService.is_email_send_ip_limit", return_value=False) @@ -69,6 +69,10 @@ class TestForgotPasswordSendEmailApi: class TestForgotPasswordCheckApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + @patch("controllers.web.forgot_password.AccountService.reset_forgot_password_error_rate_limit") @patch("controllers.web.forgot_password.AccountService.generate_reset_password_token") @patch("controllers.web.forgot_password.AccountService.revoke_reset_password_token") @@ -143,6 +147,10 @@ class TestForgotPasswordCheckApi: class TestForgotPasswordResetApi: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + @patch("controllers.web.forgot_password.ForgotPasswordResetApi._update_existing_account") @patch("controllers.web.forgot_password.AccountService.get_account_by_email_with_case_fallback") @patch("controllers.web.forgot_password.Session") diff --git a/api/tests/unit_tests/controllers/web/test_wraps.py b/api/tests/test_containers_integration_tests/controllers/web/test_wraps.py similarity index 67% rename from api/tests/unit_tests/controllers/web/test_wraps.py rename to api/tests/test_containers_integration_tests/controllers/web/test_wraps.py index 85049ae975..19833cc772 100644 --- a/api/tests/unit_tests/controllers/web/test_wraps.py +++ b/api/tests/test_containers_integration_tests/controllers/web/test_wraps.py @@ -1,13 +1,14 @@ -"""Unit tests for controllers.web.wraps — JWT auth decorator and validation helpers.""" +"""Testcontainers integration tests for controllers.web.wraps — JWT auth decorator and validation helpers.""" from __future__ import annotations from datetime import UTC, datetime, timedelta from types import SimpleNamespace from unittest.mock import MagicMock, patch +from uuid import uuid4 import pytest -from flask import Flask +from sqlalchemy.orm import Session from werkzeug.exceptions import BadRequest, NotFound, Unauthorized from controllers.web.error import WebAppAuthAccessDeniedError, WebAppAuthRequiredError @@ -18,12 +19,8 @@ from controllers.web.wraps import ( ) -# --------------------------------------------------------------------------- -# _validate_webapp_token -# --------------------------------------------------------------------------- class TestValidateWebappToken: def test_enterprise_enabled_and_app_auth_requires_webapp_source(self) -> None: - """When both flags are true, a non-webapp source must raise.""" decoded = {"token_source": "other"} with pytest.raises(WebAppAuthRequiredError): _validate_webapp_token(decoded, app_web_auth_enabled=True, system_webapp_auth_enabled=True) @@ -38,7 +35,6 @@ class TestValidateWebappToken: _validate_webapp_token(decoded, app_web_auth_enabled=True, system_webapp_auth_enabled=True) def test_public_app_rejects_webapp_source(self) -> None: - """When auth is not required, a webapp-sourced token must be rejected.""" decoded = {"token_source": "webapp"} with pytest.raises(Unauthorized): _validate_webapp_token(decoded, app_web_auth_enabled=False, system_webapp_auth_enabled=False) @@ -52,18 +48,13 @@ class TestValidateWebappToken: _validate_webapp_token(decoded, app_web_auth_enabled=False, system_webapp_auth_enabled=False) def test_system_enabled_but_app_public(self) -> None: - """system_webapp_auth_enabled=True but app is public — webapp source rejected.""" decoded = {"token_source": "webapp"} with pytest.raises(Unauthorized): _validate_webapp_token(decoded, app_web_auth_enabled=False, system_webapp_auth_enabled=True) -# --------------------------------------------------------------------------- -# _validate_user_accessibility -# --------------------------------------------------------------------------- class TestValidateUserAccessibility: def test_skips_when_auth_disabled(self) -> None: - """No checks when system or app auth is disabled.""" _validate_user_accessibility( decoded={}, app_code="code", @@ -123,7 +114,6 @@ class TestValidateUserAccessibility: def test_external_auth_type_checks_sso_update_time( self, mock_perm_check: MagicMock, mock_sso_time: MagicMock ) -> None: - # granted_at is before SSO update time → denied mock_sso_time.return_value = datetime.now(UTC) old_granted = int((datetime.now(UTC) - timedelta(hours=1)).timestamp()) decoded = {"user_id": "u1", "auth_type": "external", "granted_at": old_granted} @@ -164,7 +154,6 @@ class TestValidateUserAccessibility: recent_granted = int(datetime.now(UTC).timestamp()) decoded = {"user_id": "u1", "auth_type": "external", "granted_at": recent_granted} settings = SimpleNamespace(access_mode="public") - # Should not raise _validate_user_accessibility( decoded=decoded, app_code="code", @@ -191,10 +180,49 @@ class TestValidateUserAccessibility: ) -# --------------------------------------------------------------------------- -# decode_jwt_token -# --------------------------------------------------------------------------- class TestDecodeJwtToken: + @pytest.fixture + def app(self, flask_app_with_containers): + return flask_app_with_containers + + def _create_app_site_enduser(self, db_session: Session, *, enable_site: bool = True): + from models.model import App, AppMode, CustomizeTokenStrategy, EndUser, Site + + tenant_id = str(uuid4()) + app_model = App( + tenant_id=tenant_id, + mode=AppMode.CHAT.value, + name="test-app", + enable_site=enable_site, + enable_api=True, + ) + db_session.add(app_model) + db_session.commit() + db_session.expire_all() + + site = Site( + app_id=app_model.id, + title="test-site", + default_language="en-US", + customize_token_strategy=CustomizeTokenStrategy.NOT_ALLOW, + code="code1", + ) + db_session.add(site) + db_session.commit() + db_session.expire_all() + + end_user = EndUser( + tenant_id=tenant_id, + app_id=app_model.id, + type="browser", + session_id="sess-1", + ) + db_session.add(end_user) + db_session.commit() + db_session.expire_all() + + return app_model, site, end_user + @patch("controllers.web.wraps._validate_user_accessibility") @patch("controllers.web.wraps._validate_webapp_token") @patch("controllers.web.wraps.EnterpriseService.WebAppAuth.get_app_access_mode_by_id") @@ -202,10 +230,8 @@ class TestDecodeJwtToken: @patch("controllers.web.wraps.FeatureService.get_system_features") @patch("controllers.web.wraps.PassportService") @patch("controllers.web.wraps.extract_webapp_passport") - @patch("controllers.web.wraps.db") def test_happy_path( self, - mock_db: MagicMock, mock_extract: MagicMock, mock_passport_cls: MagicMock, mock_features: MagicMock, @@ -213,40 +239,28 @@ class TestDecodeJwtToken: mock_access_mode: MagicMock, mock_validate_token: MagicMock, mock_validate_user: MagicMock, - app: Flask, + app, + db_session_with_containers: Session, ) -> None: + app_model, site, end_user = self._create_app_site_enduser(db_session_with_containers) + mock_extract.return_value = "jwt-token" mock_passport_cls.return_value.verify.return_value = { - "app_code": "code1", - "app_id": "app-1", - "end_user_id": "eu-1", + "app_code": site.code, + "app_id": app_model.id, + "end_user_id": end_user.id, } mock_features.return_value = SimpleNamespace(webapp_auth=SimpleNamespace(enabled=False)) - app_model = SimpleNamespace(id="app-1", enable_site=True) - site = SimpleNamespace(code="code1") - end_user = SimpleNamespace(id="eu-1", session_id="sess-1") + with app.test_request_context("/", headers={"X-App-Code": site.code}): + result_app, result_user = decode_jwt_token() - # Configure session mock to return correct objects via scalar() - session_mock = MagicMock() - session_mock.scalar.side_effect = [app_model, site, end_user] - session_ctx = MagicMock() - session_ctx.__enter__ = MagicMock(return_value=session_mock) - session_ctx.__exit__ = MagicMock(return_value=False) - mock_db.engine = "engine" - - with patch("controllers.web.wraps.Session", return_value=session_ctx): - with app.test_request_context("/", headers={"X-App-Code": "code1"}): - result_app, result_user = decode_jwt_token() - - assert result_app.id == "app-1" - assert result_user.id == "eu-1" + assert result_app.id == app_model.id + assert result_user.id == end_user.id @patch("controllers.web.wraps.FeatureService.get_system_features") @patch("controllers.web.wraps.extract_webapp_passport") - def test_missing_token_raises_unauthorized( - self, mock_extract: MagicMock, mock_features: MagicMock, app: Flask - ) -> None: + def test_missing_token_raises_unauthorized(self, mock_extract: MagicMock, mock_features: MagicMock, app) -> None: mock_features.return_value = SimpleNamespace(webapp_auth=SimpleNamespace(enabled=False)) mock_extract.return_value = None @@ -257,137 +271,98 @@ class TestDecodeJwtToken: @patch("controllers.web.wraps.FeatureService.get_system_features") @patch("controllers.web.wraps.PassportService") @patch("controllers.web.wraps.extract_webapp_passport") - @patch("controllers.web.wraps.db") def test_missing_app_raises_not_found( self, - mock_db: MagicMock, mock_extract: MagicMock, mock_passport_cls: MagicMock, mock_features: MagicMock, - app: Flask, + app, ) -> None: + non_existent_id = str(uuid4()) mock_extract.return_value = "jwt-token" mock_passport_cls.return_value.verify.return_value = { "app_code": "code1", - "app_id": "app-1", - "end_user_id": "eu-1", + "app_id": non_existent_id, + "end_user_id": str(uuid4()), } mock_features.return_value = SimpleNamespace(webapp_auth=SimpleNamespace(enabled=False)) - session_mock = MagicMock() - session_mock.scalar.return_value = None # No app found - session_ctx = MagicMock() - session_ctx.__enter__ = MagicMock(return_value=session_mock) - session_ctx.__exit__ = MagicMock(return_value=False) - mock_db.engine = "engine" - - with patch("controllers.web.wraps.Session", return_value=session_ctx): - with app.test_request_context("/", headers={"X-App-Code": "code1"}): - with pytest.raises(NotFound): - decode_jwt_token() + with app.test_request_context("/", headers={"X-App-Code": "code1"}): + with pytest.raises(NotFound): + decode_jwt_token() @patch("controllers.web.wraps.FeatureService.get_system_features") @patch("controllers.web.wraps.PassportService") @patch("controllers.web.wraps.extract_webapp_passport") - @patch("controllers.web.wraps.db") def test_disabled_site_raises_bad_request( self, - mock_db: MagicMock, mock_extract: MagicMock, mock_passport_cls: MagicMock, mock_features: MagicMock, - app: Flask, + app, + db_session_with_containers: Session, ) -> None: + app_model, site, end_user = self._create_app_site_enduser(db_session_with_containers, enable_site=False) + mock_extract.return_value = "jwt-token" mock_passport_cls.return_value.verify.return_value = { - "app_code": "code1", - "app_id": "app-1", - "end_user_id": "eu-1", + "app_code": site.code, + "app_id": app_model.id, + "end_user_id": end_user.id, } mock_features.return_value = SimpleNamespace(webapp_auth=SimpleNamespace(enabled=False)) - app_model = SimpleNamespace(id="app-1", enable_site=False) - - session_mock = MagicMock() - # scalar calls: app_model, site (code found), then end_user - session_mock.scalar.side_effect = [app_model, SimpleNamespace(code="code1"), None] - session_ctx = MagicMock() - session_ctx.__enter__ = MagicMock(return_value=session_mock) - session_ctx.__exit__ = MagicMock(return_value=False) - mock_db.engine = "engine" - - with patch("controllers.web.wraps.Session", return_value=session_ctx): - with app.test_request_context("/", headers={"X-App-Code": "code1"}): - with pytest.raises(BadRequest, match="Site is disabled"): - decode_jwt_token() + with app.test_request_context("/", headers={"X-App-Code": site.code}): + with pytest.raises(BadRequest, match="Site is disabled"): + decode_jwt_token() @patch("controllers.web.wraps.FeatureService.get_system_features") @patch("controllers.web.wraps.PassportService") @patch("controllers.web.wraps.extract_webapp_passport") - @patch("controllers.web.wraps.db") def test_missing_end_user_raises_not_found( self, - mock_db: MagicMock, mock_extract: MagicMock, mock_passport_cls: MagicMock, mock_features: MagicMock, - app: Flask, + app, + db_session_with_containers: Session, ) -> None: + app_model, site, _ = self._create_app_site_enduser(db_session_with_containers) + non_existent_eu = str(uuid4()) + mock_extract.return_value = "jwt-token" mock_passport_cls.return_value.verify.return_value = { - "app_code": "code1", - "app_id": "app-1", - "end_user_id": "eu-1", + "app_code": site.code, + "app_id": app_model.id, + "end_user_id": non_existent_eu, } mock_features.return_value = SimpleNamespace(webapp_auth=SimpleNamespace(enabled=False)) - app_model = SimpleNamespace(id="app-1", enable_site=True) - site = SimpleNamespace(code="code1") - - session_mock = MagicMock() - session_mock.scalar.side_effect = [app_model, site, None] # end_user is None - session_ctx = MagicMock() - session_ctx.__enter__ = MagicMock(return_value=session_mock) - session_ctx.__exit__ = MagicMock(return_value=False) - mock_db.engine = "engine" - - with patch("controllers.web.wraps.Session", return_value=session_ctx): - with app.test_request_context("/", headers={"X-App-Code": "code1"}): - with pytest.raises(NotFound): - decode_jwt_token() + with app.test_request_context("/", headers={"X-App-Code": site.code}): + with pytest.raises(NotFound): + decode_jwt_token() @patch("controllers.web.wraps.FeatureService.get_system_features") @patch("controllers.web.wraps.PassportService") @patch("controllers.web.wraps.extract_webapp_passport") - @patch("controllers.web.wraps.db") def test_user_id_mismatch_raises_unauthorized( self, - mock_db: MagicMock, mock_extract: MagicMock, mock_passport_cls: MagicMock, mock_features: MagicMock, - app: Flask, + app, + db_session_with_containers: Session, ) -> None: + app_model, site, end_user = self._create_app_site_enduser(db_session_with_containers) + mock_extract.return_value = "jwt-token" mock_passport_cls.return_value.verify.return_value = { - "app_code": "code1", - "app_id": "app-1", - "end_user_id": "eu-1", + "app_code": site.code, + "app_id": app_model.id, + "end_user_id": end_user.id, } mock_features.return_value = SimpleNamespace(webapp_auth=SimpleNamespace(enabled=False)) - app_model = SimpleNamespace(id="app-1", enable_site=True) - site = SimpleNamespace(code="code1") - end_user = SimpleNamespace(id="eu-1", session_id="sess-1") - - session_mock = MagicMock() - session_mock.scalar.side_effect = [app_model, site, end_user] - session_ctx = MagicMock() - session_ctx.__enter__ = MagicMock(return_value=session_mock) - session_ctx.__exit__ = MagicMock(return_value=False) - mock_db.engine = "engine" - - with patch("controllers.web.wraps.Session", return_value=session_ctx): - with app.test_request_context("/", headers={"X-App-Code": "code1"}): - with pytest.raises(Unauthorized, match="expired"): - decode_jwt_token(user_id="different-user") + with app.test_request_context("/", headers={"X-App-Code": site.code}): + with pytest.raises(Unauthorized, match="expired"): + decode_jwt_token(user_id="different-user") diff --git a/api/tests/test_containers_integration_tests/services/test_model_load_balancing_service.py b/api/tests/test_containers_integration_tests/services/test_model_load_balancing_service.py index ca6e7afeab..aca3839135 100644 --- a/api/tests/test_containers_integration_tests/services/test_model_load_balancing_service.py +++ b/api/tests/test_containers_integration_tests/services/test_model_load_balancing_service.py @@ -141,7 +141,7 @@ class TestModelLoadBalancingService: tenant_id=tenant_id, provider_name="openai", model_name="gpt-3.5-turbo", - model_type="text-generation", # Use the origin model type that matches the query + model_type="llm", enabled=True, load_balancing_enabled=False, ) @@ -298,7 +298,7 @@ class TestModelLoadBalancingService: tenant_id=tenant.id, provider_name="openai", model_name="gpt-3.5-turbo", - model_type="text-generation", # Use the origin model type that matches the query + model_type="llm", name="config1", encrypted_config='{"api_key": "test_key"}', enabled=True, @@ -417,7 +417,7 @@ class TestModelLoadBalancingService: tenant_id=tenant.id, provider_name="openai", model_name="gpt-3.5-turbo", - model_type="text-generation", # Use the origin model type that matches the query + model_type="llm", name="config1", encrypted_config='{"api_key": "test_key"}', enabled=True, diff --git a/api/tests/unit_tests/controllers/console/app/test_app_import_api.py b/api/tests/unit_tests/controllers/console/app/test_app_import_api.py deleted file mode 100644 index 91f58460ac..0000000000 --- a/api/tests/unit_tests/controllers/console/app/test_app_import_api.py +++ /dev/null @@ -1,157 +0,0 @@ -from __future__ import annotations - -from types import SimpleNamespace -from unittest.mock import MagicMock - -import pytest - -from controllers.console.app import app_import as app_import_module -from services.app_dsl_service import ImportStatus - - -def _unwrap(func): - bound_self = getattr(func, "__self__", None) - while hasattr(func, "__wrapped__"): - func = func.__wrapped__ - if bound_self is not None: - return func.__get__(bound_self, bound_self.__class__) - return func - - -class _Result: - def __init__(self, status: ImportStatus, app_id: str | None = "app-1"): - self.status = status - self.app_id = app_id - - def model_dump(self, mode: str = "json"): - return {"status": self.status, "app_id": self.app_id} - - -class _SessionContext: - def __init__(self, session): - self._session = session - - def __enter__(self): - return self._session - - def __exit__(self, exc_type, exc, tb): - return False - - -def _install_session(monkeypatch: pytest.MonkeyPatch, session: MagicMock) -> None: - monkeypatch.setattr(app_import_module, "Session", lambda *_: _SessionContext(session)) - monkeypatch.setattr(app_import_module, "db", SimpleNamespace(engine=object())) - - -def _install_features(monkeypatch: pytest.MonkeyPatch, enabled: bool) -> None: - features = SimpleNamespace(webapp_auth=SimpleNamespace(enabled=enabled)) - monkeypatch.setattr(app_import_module.FeatureService, "get_system_features", lambda: features) - - -def test_import_post_returns_failed_status(app, monkeypatch: pytest.MonkeyPatch) -> None: - api = app_import_module.AppImportApi() - method = _unwrap(api.post) - - session = MagicMock() - _install_session(monkeypatch, session) - _install_features(monkeypatch, enabled=False) - monkeypatch.setattr( - app_import_module.AppDslService, - "import_app", - lambda *_args, **_kwargs: _Result(ImportStatus.FAILED, app_id=None), - ) - monkeypatch.setattr(app_import_module, "current_account_with_tenant", lambda: (SimpleNamespace(id="u1"), "t1")) - - with app.test_request_context("/console/api/apps/imports", method="POST", json={"mode": "yaml-content"}): - response, status = method() - - session.commit.assert_called_once() - assert status == 400 - assert response["status"] == ImportStatus.FAILED - - -def test_import_post_returns_pending_status(app, monkeypatch: pytest.MonkeyPatch) -> None: - api = app_import_module.AppImportApi() - method = _unwrap(api.post) - - session = MagicMock() - _install_session(monkeypatch, session) - _install_features(monkeypatch, enabled=False) - monkeypatch.setattr( - app_import_module.AppDslService, - "import_app", - lambda *_args, **_kwargs: _Result(ImportStatus.PENDING), - ) - monkeypatch.setattr(app_import_module, "current_account_with_tenant", lambda: (SimpleNamespace(id="u1"), "t1")) - - with app.test_request_context("/console/api/apps/imports", method="POST", json={"mode": "yaml-content"}): - response, status = method() - - session.commit.assert_called_once() - assert status == 202 - assert response["status"] == ImportStatus.PENDING - - -def test_import_post_updates_webapp_auth_when_enabled(app, monkeypatch: pytest.MonkeyPatch) -> None: - api = app_import_module.AppImportApi() - method = _unwrap(api.post) - - session = MagicMock() - _install_session(monkeypatch, session) - _install_features(monkeypatch, enabled=True) - monkeypatch.setattr( - app_import_module.AppDslService, - "import_app", - lambda *_args, **_kwargs: _Result(ImportStatus.COMPLETED, app_id="app-123"), - ) - update_access = MagicMock() - monkeypatch.setattr(app_import_module.EnterpriseService.WebAppAuth, "update_app_access_mode", update_access) - monkeypatch.setattr(app_import_module, "current_account_with_tenant", lambda: (SimpleNamespace(id="u1"), "t1")) - - with app.test_request_context("/console/api/apps/imports", method="POST", json={"mode": "yaml-content"}): - response, status = method() - - session.commit.assert_called_once() - update_access.assert_called_once_with("app-123", "private") - assert status == 200 - assert response["status"] == ImportStatus.COMPLETED - - -def test_import_confirm_returns_failed_status(app, monkeypatch: pytest.MonkeyPatch) -> None: - api = app_import_module.AppImportConfirmApi() - method = _unwrap(api.post) - - session = MagicMock() - _install_session(monkeypatch, session) - monkeypatch.setattr( - app_import_module.AppDslService, - "confirm_import", - lambda *_args, **_kwargs: _Result(ImportStatus.FAILED), - ) - monkeypatch.setattr(app_import_module, "current_account_with_tenant", lambda: (SimpleNamespace(id="u1"), "t1")) - - with app.test_request_context("/console/api/apps/imports/import-1/confirm", method="POST"): - response, status = method(import_id="import-1") - - session.commit.assert_called_once() - assert status == 400 - assert response["status"] == ImportStatus.FAILED - - -def test_import_check_dependencies_returns_result(app, monkeypatch: pytest.MonkeyPatch) -> None: - api = app_import_module.AppImportCheckDependenciesApi() - method = _unwrap(api.get) - - session = MagicMock() - _install_session(monkeypatch, session) - monkeypatch.setattr( - app_import_module.AppDslService, - "check_dependencies", - lambda *_args, **_kwargs: SimpleNamespace(model_dump=lambda mode="json": {"leaked_dependencies": []}), - ) - - with app.test_request_context("/console/api/apps/imports/app-1/check-dependencies", method="GET"): - response, status = method(app_model=SimpleNamespace(id="app-1")) - - assert status == 200 - assert response["leaked_dependencies"] == [] diff --git a/api/tests/unit_tests/controllers/console/workspace/test_workspace_wraps.py b/api/tests/unit_tests/controllers/console/workspace/test_workspace_wraps.py deleted file mode 100644 index b290748155..0000000000 --- a/api/tests/unit_tests/controllers/console/workspace/test_workspace_wraps.py +++ /dev/null @@ -1,142 +0,0 @@ -from __future__ import annotations - -import importlib -from types import SimpleNamespace - -import pytest -from werkzeug.exceptions import Forbidden - -from controllers.console.workspace import plugin_permission_required -from models.account import TenantPluginPermission - - -class _SessionStub: - def __init__(self, permission): - self._permission = permission - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc, tb): - return False - - def query(self, *_args, **_kwargs): - return self - - def where(self, *_args, **_kwargs): - return self - - def first(self): - return self._permission - - -def _workspace_module(): - return importlib.import_module(plugin_permission_required.__module__) - - -def _patch_session(monkeypatch: pytest.MonkeyPatch, permission): - module = _workspace_module() - monkeypatch.setattr(module, "Session", lambda *_args, **_kwargs: _SessionStub(permission)) - monkeypatch.setattr(module, "db", SimpleNamespace(engine=object())) - - -def test_plugin_permission_allows_without_permission(monkeypatch: pytest.MonkeyPatch) -> None: - user = SimpleNamespace(is_admin_or_owner=False) - module = _workspace_module() - monkeypatch.setattr(module, "current_account_with_tenant", lambda: (user, "t1")) - _patch_session(monkeypatch, None) - - @plugin_permission_required() - def handler(): - return "ok" - - assert handler() == "ok" - - -def test_plugin_permission_install_nobody_forbidden(monkeypatch: pytest.MonkeyPatch) -> None: - user = SimpleNamespace(is_admin_or_owner=True) - permission = SimpleNamespace( - install_permission=TenantPluginPermission.InstallPermission.NOBODY, - debug_permission=TenantPluginPermission.DebugPermission.EVERYONE, - ) - module = _workspace_module() - monkeypatch.setattr(module, "current_account_with_tenant", lambda: (user, "t1")) - _patch_session(monkeypatch, permission) - - @plugin_permission_required(install_required=True) - def handler(): - return "ok" - - with pytest.raises(Forbidden): - handler() - - -def test_plugin_permission_install_admin_requires_admin(monkeypatch: pytest.MonkeyPatch) -> None: - user = SimpleNamespace(is_admin_or_owner=False) - permission = SimpleNamespace( - install_permission=TenantPluginPermission.InstallPermission.ADMINS, - debug_permission=TenantPluginPermission.DebugPermission.EVERYONE, - ) - module = _workspace_module() - monkeypatch.setattr(module, "current_account_with_tenant", lambda: (user, "t1")) - _patch_session(monkeypatch, permission) - - @plugin_permission_required(install_required=True) - def handler(): - return "ok" - - with pytest.raises(Forbidden): - handler() - - -def test_plugin_permission_install_admin_allows_admin(monkeypatch: pytest.MonkeyPatch) -> None: - user = SimpleNamespace(is_admin_or_owner=True) - permission = SimpleNamespace( - install_permission=TenantPluginPermission.InstallPermission.ADMINS, - debug_permission=TenantPluginPermission.DebugPermission.EVERYONE, - ) - module = _workspace_module() - monkeypatch.setattr(module, "current_account_with_tenant", lambda: (user, "t1")) - _patch_session(monkeypatch, permission) - - @plugin_permission_required(install_required=True) - def handler(): - return "ok" - - assert handler() == "ok" - - -def test_plugin_permission_debug_nobody_forbidden(monkeypatch: pytest.MonkeyPatch) -> None: - user = SimpleNamespace(is_admin_or_owner=True) - permission = SimpleNamespace( - install_permission=TenantPluginPermission.InstallPermission.EVERYONE, - debug_permission=TenantPluginPermission.DebugPermission.NOBODY, - ) - module = _workspace_module() - monkeypatch.setattr(module, "current_account_with_tenant", lambda: (user, "t1")) - _patch_session(monkeypatch, permission) - - @plugin_permission_required(debug_required=True) - def handler(): - return "ok" - - with pytest.raises(Forbidden): - handler() - - -def test_plugin_permission_debug_admin_requires_admin(monkeypatch: pytest.MonkeyPatch) -> None: - user = SimpleNamespace(is_admin_or_owner=False) - permission = SimpleNamespace( - install_permission=TenantPluginPermission.InstallPermission.EVERYONE, - debug_permission=TenantPluginPermission.DebugPermission.ADMINS, - ) - module = _workspace_module() - monkeypatch.setattr(module, "current_account_with_tenant", lambda: (user, "t1")) - _patch_session(monkeypatch, permission) - - @plugin_permission_required(debug_required=True) - def handler(): - return "ok" - - with pytest.raises(Forbidden): - handler() diff --git a/api/tests/unit_tests/controllers/service_api/dataset/test_dataset_segment.py b/api/tests/unit_tests/controllers/service_api/dataset/test_dataset_segment.py index 7f5d6b0839..e9c3e6d376 100644 --- a/api/tests/unit_tests/controllers/service_api/dataset/test_dataset_segment.py +++ b/api/tests/unit_tests/controllers/service_api/dataset/test_dataset_segment.py @@ -768,6 +768,7 @@ class TestSegmentApiGet: ``current_account_with_tenant()`` and ``marshal``. """ + @patch("controllers.service_api.dataset.segment.SummaryIndexService") @patch("controllers.service_api.dataset.segment.marshal") @patch("controllers.service_api.dataset.segment.SegmentService") @patch("controllers.service_api.dataset.segment.DocumentService") @@ -780,6 +781,7 @@ class TestSegmentApiGet: mock_doc_svc, mock_seg_svc, mock_marshal, + mock_summary_svc, app, mock_tenant, mock_dataset, @@ -791,7 +793,8 @@ class TestSegmentApiGet: mock_db.session.scalar.return_value = mock_dataset mock_doc_svc.get_document.return_value = Mock(doc_form=IndexStructureType.PARAGRAPH_INDEX) mock_seg_svc.get_segments.return_value = ([mock_segment], 1) - mock_marshal.return_value = [{"id": mock_segment.id}] + mock_marshal.return_value = {"id": mock_segment.id} + mock_summary_svc.get_segments_summaries.return_value = {} # Act with app.test_request_context( @@ -872,6 +875,7 @@ class TestSegmentApiPost: mock_rate_limit.enabled = False mock_feature_svc.get_knowledge_rate_limit.return_value = mock_rate_limit + @patch("controllers.service_api.dataset.segment.SummaryIndexService") @patch("controllers.service_api.dataset.segment.marshal") @patch("controllers.service_api.dataset.segment.SegmentService") @patch("controllers.service_api.dataset.segment.DocumentService") @@ -888,6 +892,7 @@ class TestSegmentApiPost: mock_doc_svc, mock_seg_svc, mock_marshal, + mock_summary_svc, app, mock_tenant, mock_dataset, @@ -909,7 +914,8 @@ class TestSegmentApiPost: mock_seg_svc.segment_create_args_validate.return_value = None mock_seg_svc.multi_create_segment.return_value = [mock_segment] - mock_marshal.return_value = [{"id": mock_segment.id}] + mock_marshal.return_value = {"id": mock_segment.id} + mock_summary_svc.get_segments_summaries.return_value = {} segments_data = [{"content": "Test segment content", "answer": "Test answer"}] @@ -1206,6 +1212,7 @@ class TestDatasetSegmentApiUpdate: mock_rate_limit.enabled = False mock_feature_svc.get_knowledge_rate_limit.return_value = mock_rate_limit + @patch("controllers.service_api.dataset.segment.SummaryIndexService") @patch("controllers.service_api.dataset.segment.marshal") @patch("controllers.service_api.dataset.segment.SegmentService") @patch("controllers.service_api.dataset.segment.DocumentService") @@ -1224,6 +1231,7 @@ class TestDatasetSegmentApiUpdate: mock_doc_svc, mock_seg_svc, mock_marshal, + mock_summary_svc, app, mock_tenant, mock_dataset, @@ -1240,6 +1248,7 @@ class TestDatasetSegmentApiUpdate: updated = Mock() mock_seg_svc.update_segment.return_value = updated mock_marshal.return_value = {"id": mock_segment.id} + mock_summary_svc.get_segment_summary.return_value = None with app.test_request_context( f"/datasets/{mock_dataset.id}/documents/doc-id/segments/{mock_segment.id}", @@ -1349,6 +1358,7 @@ class TestDatasetSegmentApiGetSingle: ``current_account_with_tenant()`` and ``marshal``. """ + @patch("controllers.service_api.dataset.segment.SummaryIndexService") @patch("controllers.service_api.dataset.segment.marshal") @patch("controllers.service_api.dataset.segment.SegmentService") @patch("controllers.service_api.dataset.segment.DocumentService") @@ -1363,6 +1373,7 @@ class TestDatasetSegmentApiGetSingle: mock_doc_svc, mock_seg_svc, mock_marshal, + mock_summary_svc, app, mock_tenant, mock_dataset, @@ -1376,6 +1387,7 @@ class TestDatasetSegmentApiGetSingle: mock_doc_svc.get_document.return_value = mock_doc mock_seg_svc.get_segment_by_id.return_value = mock_segment mock_marshal.return_value = {"id": mock_segment.id} + mock_summary_svc.get_segment_summary.return_value = None with app.test_request_context( f"/datasets/{mock_dataset.id}/documents/doc-id/segments/{mock_segment.id}", @@ -1393,6 +1405,55 @@ class TestDatasetSegmentApiGetSingle: assert "data" in response assert response["doc_form"] == IndexStructureType.PARAGRAPH_INDEX + @patch("controllers.service_api.dataset.segment.SummaryIndexService") + @patch("controllers.service_api.dataset.segment.marshal") + @patch("controllers.service_api.dataset.segment.SegmentService") + @patch("controllers.service_api.dataset.segment.DocumentService") + @patch("controllers.service_api.dataset.segment.DatasetService") + @patch("controllers.service_api.dataset.segment.current_account_with_tenant") + @patch("controllers.service_api.dataset.segment.db") + def test_get_single_segment_includes_summary( + self, + mock_db, + mock_account_fn, + mock_dataset_svc, + mock_doc_svc, + mock_seg_svc, + mock_marshal, + mock_summary_svc, + app, + mock_tenant, + mock_dataset, + mock_segment, + ): + """Test that single segment response includes summary content from SummaryIndexService.""" + mock_account_fn.return_value = (Mock(), mock_tenant.id) + mock_db.session.scalar.return_value = mock_dataset + mock_dataset_svc.check_dataset_model_setting.return_value = None + mock_doc = Mock(doc_form=IndexStructureType.PARAGRAPH_INDEX) + mock_doc_svc.get_document.return_value = mock_doc + mock_seg_svc.get_segment_by_id.return_value = mock_segment + mock_marshal.return_value = {"id": mock_segment.id, "summary": None} + + mock_summary_record = Mock() + mock_summary_record.summary_content = "This is the segment summary" + mock_summary_svc.get_segment_summary.return_value = mock_summary_record + + with app.test_request_context( + f"/datasets/{mock_dataset.id}/documents/doc-id/segments/{mock_segment.id}", + method="GET", + ): + api = DatasetSegmentApi() + response, status = api.get( + tenant_id=mock_tenant.id, + dataset_id=mock_dataset.id, + document_id="doc-id", + segment_id=mock_segment.id, + ) + + assert status == 200 + assert response["data"]["summary"] == "This is the segment summary" + @patch("controllers.service_api.dataset.segment.current_account_with_tenant") @patch("controllers.service_api.dataset.segment.db") def test_get_single_segment_dataset_not_found( diff --git a/api/tests/unit_tests/core/mcp/server/test_streamable_http.py b/api/tests/unit_tests/core/mcp/server/test_streamable_http.py index 313d18c695..9a815fb94d 100644 --- a/api/tests/unit_tests/core/mcp/server/test_streamable_http.py +++ b/api/tests/unit_tests/core/mcp/server/test_streamable_http.py @@ -415,12 +415,44 @@ class TestUtilityFunctions: label="Upload", required=False, ), + VariableEntity( + type=VariableEntityType.CHECKBOX, + variable="enabled", + description="Enable flag", + label="Enabled", + required=False, + ), + VariableEntity( + type=VariableEntityType.JSON_OBJECT, + variable="config", + description="Config object", + label="Config", + required=True, + ), + VariableEntity( + type=VariableEntityType.JSON_OBJECT, + variable="schema_config", + description="Config with schema", + label="Schema Config", + required=False, + json_schema={ + "properties": { + "host": {"type": "string"}, + "port": {"type": "number"}, + }, + "required": ["host"], + "additionalProperties": False, + }, + ), ] parameters_dict: dict[str, str] = { "name": "Enter your name", "category": "Select category", "count": "Enter count", + "enabled": "Enable flag", + "config": "Config object", + "schema_config": "Config with schema", } parameters, required = convert_input_form_to_parameters(user_input_form, parameters_dict) @@ -437,20 +469,35 @@ class TestUtilityFunctions: assert "count" in parameters assert parameters["count"]["type"] == "number" - # FILE type should be skipped - it creates empty dict but gets filtered later - # Check that it doesn't have any meaningful content - if "upload" in parameters: - assert parameters["upload"] == {} + # FILE type is skipped entirely via `continue` — key should not exist + assert "upload" not in parameters + + # CHECKBOX maps to boolean + assert parameters["enabled"]["type"] == "boolean" + + # JSON_OBJECT without json_schema maps to object + assert parameters["config"]["type"] == "object" + assert "properties" not in parameters["config"] + + # JSON_OBJECT with json_schema forwards schema keys + assert parameters["schema_config"]["type"] == "object" + assert parameters["schema_config"]["properties"] == { + "host": {"type": "string"}, + "port": {"type": "number"}, + } + assert parameters["schema_config"]["required"] == ["host"] + assert parameters["schema_config"]["additionalProperties"] is False # Check required fields assert "name" in required assert "count" in required + assert "config" in required assert "category" not in required # Note: _get_request_id function has been removed as request_id is now passed as parameter def test_convert_input_form_to_parameters_jsonschema_validation_ok(self): - """Current schema uses 'number' for numeric fields; it should be a valid JSON Schema.""" + """Generated schema with all supported types should be valid JSON Schema.""" user_input_form = [ VariableEntity( type=VariableEntityType.NUMBER, @@ -466,11 +513,27 @@ class TestUtilityFunctions: label="Name", required=False, ), + VariableEntity( + type=VariableEntityType.CHECKBOX, + variable="enabled", + description="Toggle", + label="Enabled", + required=False, + ), + VariableEntity( + type=VariableEntityType.JSON_OBJECT, + variable="metadata", + description="Metadata", + label="Metadata", + required=False, + ), ] parameters_dict = { "count": "Enter count", "name": "Enter your name", + "enabled": "Toggle flag", + "metadata": "Metadata object", } parameters, required = convert_input_form_to_parameters(user_input_form, parameters_dict) @@ -485,9 +548,12 @@ class TestUtilityFunctions: # 1) The schema itself must be valid jsonschema.Draft202012Validator.check_schema(schema) - # 2) Both float and integer instances should pass validation + # 2) Validate instances with all types jsonschema.validate(instance={"count": 3.14, "name": "alice"}, schema=schema) - jsonschema.validate(instance={"count": 2, "name": "bob"}, schema=schema) + jsonschema.validate( + instance={"count": 2, "enabled": True, "metadata": {"key": "val"}}, + schema=schema, + ) def test_legacy_float_type_schema_is_invalid(self): """Legacy/buggy behavior: using 'float' should produce an invalid JSON Schema.""" diff --git a/api/tests/unit_tests/core/ops/langfuse_trace/test_langfuse_trace.py b/api/tests/unit_tests/core/ops/langfuse_trace/test_langfuse_trace.py index 97f7a16327..374371fb42 100644 --- a/api/tests/unit_tests/core/ops/langfuse_trace/test_langfuse_trace.py +++ b/api/tests/unit_tests/core/ops/langfuse_trace/test_langfuse_trace.py @@ -521,11 +521,11 @@ def test_generate_name_trace(trace_instance): def test_add_trace_success(trace_instance): data = LangfuseTrace(id="t1", name="trace") trace_instance.add_trace(data) - trace_instance.langfuse_client.trace.assert_called_once() + trace_instance.langfuse_client.api.ingestion.batch.assert_called_once() def test_add_trace_error(trace_instance): - trace_instance.langfuse_client.trace.side_effect = Exception("error") + trace_instance.langfuse_client.api.ingestion.batch.side_effect = Exception("error") data = LangfuseTrace(id="t1", name="trace") with pytest.raises(ValueError, match="LangFuse Failed to create trace: error"): trace_instance.add_trace(data) @@ -534,11 +534,11 @@ def test_add_trace_error(trace_instance): def test_add_span_success(trace_instance): data = LangfuseSpan(id="s1", name="span", trace_id="t1") trace_instance.add_span(data) - trace_instance.langfuse_client.span.assert_called_once() + trace_instance.langfuse_client.api.ingestion.batch.assert_called_once() def test_add_span_error(trace_instance): - trace_instance.langfuse_client.span.side_effect = Exception("error") + trace_instance.langfuse_client.api.ingestion.batch.side_effect = Exception("error") data = LangfuseSpan(id="s1", name="span", trace_id="t1") with pytest.raises(ValueError, match="LangFuse Failed to create span: error"): trace_instance.add_span(data) @@ -554,11 +554,11 @@ def test_update_span(trace_instance): def test_add_generation_success(trace_instance): data = LangfuseGeneration(id="g1", name="gen", trace_id="t1") trace_instance.add_generation(data) - trace_instance.langfuse_client.generation.assert_called_once() + trace_instance.langfuse_client.api.ingestion.batch.assert_called_once() def test_add_generation_error(trace_instance): - trace_instance.langfuse_client.generation.side_effect = Exception("error") + trace_instance.langfuse_client.api.ingestion.batch.side_effect = Exception("error") data = LangfuseGeneration(id="g1", name="gen", trace_id="t1") with pytest.raises(ValueError, match="LangFuse Failed to create generation: error"): trace_instance.add_generation(data) @@ -585,12 +585,12 @@ def test_api_check_error(trace_instance): def test_get_project_key_success(trace_instance): mock_data = MagicMock() mock_data.id = "proj-1" - trace_instance.langfuse_client.client.projects.get.return_value = MagicMock(data=[mock_data]) + trace_instance.langfuse_client.api.projects.get.return_value = MagicMock(data=[mock_data]) assert trace_instance.get_project_key() == "proj-1" def test_get_project_key_error(trace_instance): - trace_instance.langfuse_client.client.projects.get.side_effect = Exception("fail") + trace_instance.langfuse_client.api.projects.get.side_effect = Exception("fail") with pytest.raises(ValueError, match="LangFuse get project key failed: fail"): trace_instance.get_project_key() diff --git a/api/tests/unit_tests/core/rag/datasource/keyword/jieba/test_jieba.py b/api/tests/unit_tests/core/rag/datasource/keyword/jieba/test_jieba.py index 795a325a6b..bbdd476914 100644 --- a/api/tests/unit_tests/core/rag/datasource/keyword/jieba/test_jieba.py +++ b/api/tests/unit_tests/core/rag/datasource/keyword/jieba/test_jieba.py @@ -201,27 +201,23 @@ def test_search_returns_documents_in_rank_order_and_applies_filter(monkeypatch, document_id = _Field("document_id") keyword = Jieba(_dataset(_dataset_keyword_table())) - query_stmt = _FakeQuery() - patched_runtime.session.query.return_value = query_stmt - patched_runtime.session.execute.return_value = _FakeExecuteResult( - [ - SimpleNamespace( - index_node_id="node-2", - content="segment-content", - index_node_hash="hash-2", - document_id="doc-2", - dataset_id="dataset-1", - ) - ] - ) + patched_runtime.session.scalars.return_value.all.return_value = [ + SimpleNamespace( + index_node_id="node-2", + content="segment-content", + index_node_hash="hash-2", + document_id="doc-2", + dataset_id="dataset-1", + ) + ] monkeypatch.setattr(jieba_module, "DocumentSegment", _FakeDocumentSegment) + monkeypatch.setattr(jieba_module, "select", lambda *_: _FakeSelect()) monkeypatch.setattr(keyword, "_get_dataset_keyword_table", MagicMock(return_value={"k": {"node-1", "node-2"}})) monkeypatch.setattr(keyword, "_retrieve_ids_by_query", MagicMock(return_value=["node-1", "node-2"])) documents = keyword.search("query", top_k=2, document_ids_filter=["doc-2"]) - assert len(query_stmt.where_calls) == 2 assert len(documents) == 1 assert documents[0].page_content == "segment-content" assert documents[0].metadata["doc_id"] == "node-2" diff --git a/api/tests/unit_tests/core/rag/datasource/test_datasource_retrieval.py b/api/tests/unit_tests/core/rag/datasource/test_datasource_retrieval.py index 63de4b8af2..5dbd62580a 100644 --- a/api/tests/unit_tests/core/rag/datasource/test_datasource_retrieval.py +++ b/api/tests/unit_tests/core/rag/datasource/test_datasource_retrieval.py @@ -714,13 +714,13 @@ class TestRetrievalServiceInternals: dataset_id="dataset-id", ) - dataset_query = Mock() - dataset_query.where.return_value.options.return_value.all.return_value = [ + scalars_result = Mock() + scalars_result.all.return_value = [ dataset_doc_parent, dataset_doc_text, dataset_doc_parent_summary, ] - monkeypatch.setattr(retrieval_service_module.db.session, "query", Mock(return_value=dataset_query)) + monkeypatch.setattr(retrieval_service_module.db.session, "scalars", Mock(return_value=scalars_result)) monkeypatch.setattr(retrieval_service_module, "RetrievalChildChunk", _SimpleRetrievalChildChunk) monkeypatch.setattr(retrieval_service_module, "RetrievalSegments", _SimpleRetrievalSegment) @@ -882,7 +882,7 @@ class TestRetrievalServiceInternals: def test_format_retrieval_documents_rolls_back_and_raises_when_db_fails(self, monkeypatch): rollback = Mock() monkeypatch.setattr(retrieval_service_module.db.session, "rollback", rollback) - monkeypatch.setattr(retrieval_service_module.db.session, "query", Mock(side_effect=RuntimeError("db error"))) + monkeypatch.setattr(retrieval_service_module.db.session, "scalars", Mock(side_effect=RuntimeError("db error"))) documents = [Document(page_content="content", metadata={"document_id": "doc-1"}, provider="dify")] diff --git a/api/tests/unit_tests/core/rag/datasource/vdb/test_vector_factory.py b/api/tests/unit_tests/core/rag/datasource/vdb/test_vector_factory.py index 54ad6d330b..4e9ceddda9 100644 --- a/api/tests/unit_tests/core/rag/datasource/vdb/test_vector_factory.py +++ b/api/tests/unit_tests/core/rag/datasource/vdb/test_vector_factory.py @@ -340,15 +340,13 @@ def test_search_by_file_handles_missing_and_existing_upload(vector_factory_modul vector._embeddings = MagicMock() vector._vector_processor = MagicMock() + mock_session = SimpleNamespace(get=lambda _model, _id: None) monkeypatch.setattr(vector_factory_module, "UploadFile", SimpleNamespace(id=_Field())) - monkeypatch.setattr( - vector_factory_module, "db", SimpleNamespace(session=SimpleNamespace(query=lambda _model: upload_query)) - ) + monkeypatch.setattr(vector_factory_module, "db", SimpleNamespace(session=mock_session)) - upload_query.first.return_value = None assert vector.search_by_file("file-1") == [] - upload_query.first.return_value = SimpleNamespace(key="blob-key") + mock_session.get = lambda _model, _id: SimpleNamespace(key="blob-key") monkeypatch.setattr(vector_factory_module.storage, "load_once", MagicMock(return_value=b"file-bytes")) vector._embeddings.embed_multimodal_query.return_value = [0.3, 0.4] vector._vector_processor.search_by_vector.return_value = ["hit"] diff --git a/api/tests/unit_tests/core/rag/docstore/test_dataset_docstore.py b/api/tests/unit_tests/core/rag/docstore/test_dataset_docstore.py index 3ba0628fe2..a7b7c1595b 100644 --- a/api/tests/unit_tests/core/rag/docstore/test_dataset_docstore.py +++ b/api/tests/unit_tests/core/rag/docstore/test_dataset_docstore.py @@ -167,7 +167,7 @@ class TestDatasetDocumentStoreAddDocuments: ): mock_session = MagicMock() mock_db.session = mock_session - mock_db.session.query.return_value.where.return_value.scalar.return_value = None + mock_db.session.scalar.return_value = None mock_manager = MagicMock() mock_manager.get_model_instance.return_value = mock_model_instance @@ -211,7 +211,7 @@ class TestDatasetDocumentStoreAddDocuments: with patch("core.rag.docstore.dataset_docstore.db") as mock_db: mock_session = MagicMock() mock_db.session = mock_session - mock_db.session.query.return_value.where.return_value.scalar.return_value = 5 + mock_db.session.scalar.return_value = 5 with patch.object(DatasetDocumentStore, "get_document_segment", return_value=mock_existing_segment): with patch.object(DatasetDocumentStore, "add_multimodel_documents_binding"): @@ -276,7 +276,7 @@ class TestDatasetDocumentStoreAddDocuments: with patch("core.rag.docstore.dataset_docstore.db") as mock_db: mock_session = MagicMock() mock_db.session = mock_session - mock_db.session.query.return_value.where.return_value.scalar.return_value = None + mock_db.session.scalar.return_value = None with patch.object(DatasetDocumentStore, "get_document_segment", return_value=None): with patch.object(DatasetDocumentStore, "add_multimodel_documents_binding"): @@ -353,7 +353,7 @@ class TestDatasetDocumentStoreAddDocuments: with patch("core.rag.docstore.dataset_docstore.db") as mock_db: mock_session = MagicMock() mock_db.session = mock_session - mock_db.session.query.return_value.where.return_value.scalar.return_value = None + mock_db.session.scalar.return_value = None with patch.object(DatasetDocumentStore, "get_document_segment", return_value=None): with patch.object(DatasetDocumentStore, "add_multimodel_documents_binding"): @@ -755,7 +755,7 @@ class TestDatasetDocumentStoreAddDocumentsUpdateChild: with patch("core.rag.docstore.dataset_docstore.db") as mock_db: mock_session = MagicMock() mock_db.session = mock_session - mock_db.session.query.return_value.where.return_value.scalar.return_value = 5 + mock_db.session.scalar.return_value = 5 with patch.object(DatasetDocumentStore, "get_document_segment", return_value=mock_existing_segment): with patch.object(DatasetDocumentStore, "add_multimodel_documents_binding"): @@ -767,7 +767,7 @@ class TestDatasetDocumentStoreAddDocumentsUpdateChild: store.add_documents([mock_doc], save_child=True) - mock_db.session.query.return_value.where.return_value.delete.assert_called() + mock_db.session.execute.assert_called() mock_db.session.commit.assert_called() @@ -798,7 +798,7 @@ class TestDatasetDocumentStoreAddDocumentsUpdateAnswer: with patch("core.rag.docstore.dataset_docstore.db") as mock_db: mock_session = MagicMock() mock_db.session = mock_session - mock_db.session.query.return_value.where.return_value.scalar.return_value = 5 + mock_db.session.scalar.return_value = 5 with patch.object(DatasetDocumentStore, "get_document_segment", return_value=mock_existing_segment): with patch.object(DatasetDocumentStore, "add_multimodel_documents_binding"): diff --git a/api/tests/unit_tests/core/rag/embedding/test_cached_embedding.py b/api/tests/unit_tests/core/rag/embedding/test_cached_embedding.py index 6fd44be4d4..3563186186 100644 --- a/api/tests/unit_tests/core/rag/embedding/test_cached_embedding.py +++ b/api/tests/unit_tests/core/rag/embedding/test_cached_embedding.py @@ -69,7 +69,7 @@ class TestCacheEmbeddingMultimodalDocuments: documents = [{"file_id": "file123", "content": "test content"}] with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_multimodal_embedding.return_value = sample_multimodal_result result = cache_embedding.embed_multimodal_documents(documents) @@ -114,7 +114,7 @@ class TestCacheEmbeddingMultimodalDocuments: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_multimodal_embedding.return_value = embedding_result result = cache_embedding.embed_multimodal_documents(documents) @@ -134,7 +134,7 @@ class TestCacheEmbeddingMultimodalDocuments: mock_cached_embedding.get_embedding.return_value = normalized_cached with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = mock_cached_embedding + mock_session.scalar.return_value = mock_cached_embedding result = cache_embedding.embed_multimodal_documents(documents) @@ -180,18 +180,7 @@ class TestCacheEmbeddingMultimodalDocuments: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - call_count = [0] - - def mock_filter_by(**kwargs): - call_count[0] += 1 - mock_query = Mock() - if call_count[0] == 1: - mock_query.first.return_value = mock_cached_embedding - else: - mock_query.first.return_value = None - return mock_query - - mock_session.query.return_value.filter_by = mock_filter_by + mock_session.scalar.side_effect = [mock_cached_embedding, None, None] mock_model_instance.invoke_multimodal_embedding.return_value = embedding_result result = cache_embedding.embed_multimodal_documents(documents) @@ -224,7 +213,7 @@ class TestCacheEmbeddingMultimodalDocuments: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_multimodal_embedding.return_value = embedding_result with patch("core.rag.embedding.cached_embedding.logger") as mock_logger: @@ -265,7 +254,7 @@ class TestCacheEmbeddingMultimodalDocuments: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None batch_results = [create_batch_result(10), create_batch_result(10), create_batch_result(5)] mock_model_instance.invoke_multimodal_embedding.side_effect = batch_results @@ -281,7 +270,7 @@ class TestCacheEmbeddingMultimodalDocuments: documents = [{"file_id": "file123"}] with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_multimodal_embedding.side_effect = Exception("API Error") with pytest.raises(Exception) as exc_info: @@ -298,7 +287,7 @@ class TestCacheEmbeddingMultimodalDocuments: documents = [{"file_id": "file123"}] with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_multimodal_embedding.return_value = sample_multimodal_result mock_session.commit.side_effect = IntegrityError("Duplicate key", None, None) diff --git a/api/tests/unit_tests/core/rag/embedding/test_embedding_service.py b/api/tests/unit_tests/core/rag/embedding/test_embedding_service.py index d7ba944e58..408cf14a51 100644 --- a/api/tests/unit_tests/core/rag/embedding/test_embedding_service.py +++ b/api/tests/unit_tests/core/rag/embedding/test_embedding_service.py @@ -139,7 +139,7 @@ class TestCacheEmbeddingDocuments: # Mock database query to return no cached embedding (cache miss) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None # Mock model invocation mock_model_instance.invoke_text_embedding.return_value = sample_embedding_result @@ -203,7 +203,7 @@ class TestCacheEmbeddingDocuments: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -240,7 +240,7 @@ class TestCacheEmbeddingDocuments: with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: # Mock database to return cached embedding (cache hit) - mock_session.query.return_value.filter_by.return_value.first.return_value = mock_cached_embedding + mock_session.scalar.return_value = mock_cached_embedding # Act result = cache_embedding.embed_documents(texts) @@ -313,19 +313,7 @@ class TestCacheEmbeddingDocuments: mock_hash.side_effect = generate_hash # Mock database to return cached embedding only for first text (hash_1) - call_count = [0] - - def mock_filter_by(**kwargs): - call_count[0] += 1 - mock_query = Mock() - # First call (hash_1) returns cached, others return None - if call_count[0] == 1: - mock_query.first.return_value = mock_cached_embedding - else: - mock_query.first.return_value = None - return mock_query - - mock_session.query.return_value.filter_by = mock_filter_by + mock_session.scalar.side_effect = [mock_cached_embedding, None, None] mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -392,7 +380,7 @@ class TestCacheEmbeddingDocuments: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None # Mock model to return appropriate batch results batch_results = [ @@ -455,7 +443,7 @@ class TestCacheEmbeddingDocuments: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result with patch("core.rag.embedding.cached_embedding.logger") as mock_logger: @@ -489,7 +477,7 @@ class TestCacheEmbeddingDocuments: texts = ["Test text"] with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None # Mock model to raise connection error mock_model_instance.invoke_text_embedding.side_effect = InvokeConnectionError("Failed to connect to API") @@ -515,7 +503,7 @@ class TestCacheEmbeddingDocuments: texts = ["Test text"] with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None # Mock model to raise rate limit error mock_model_instance.invoke_text_embedding.side_effect = InvokeRateLimitError("Rate limit exceeded") @@ -539,7 +527,7 @@ class TestCacheEmbeddingDocuments: texts = ["Test text"] with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None # Mock model to raise authorization error mock_model_instance.invoke_text_embedding.side_effect = InvokeAuthorizationError("Invalid API key") @@ -564,7 +552,7 @@ class TestCacheEmbeddingDocuments: texts = ["Test text"] with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = sample_embedding_result # Mock database commit to raise IntegrityError @@ -884,7 +872,7 @@ class TestEmbeddingModelSwitching: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None model_instance_ada.invoke_text_embedding.return_value = result_ada model_instance_3_small.invoke_text_embedding.return_value = result_3_small @@ -1047,7 +1035,7 @@ class TestEmbeddingDimensionValidation: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -1100,7 +1088,7 @@ class TestEmbeddingDimensionValidation: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -1186,7 +1174,7 @@ class TestEmbeddingDimensionValidation: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None model_instance_ada.invoke_text_embedding.return_value = result_ada model_instance_cohere.invoke_text_embedding.return_value = result_cohere @@ -1284,7 +1272,7 @@ class TestEmbeddingEdgeCases: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -1327,7 +1315,7 @@ class TestEmbeddingEdgeCases: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -1375,7 +1363,7 @@ class TestEmbeddingEdgeCases: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -1427,7 +1415,7 @@ class TestEmbeddingEdgeCases: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -1483,7 +1471,7 @@ class TestEmbeddingEdgeCases: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -1551,7 +1539,7 @@ class TestEmbeddingEdgeCases: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -1649,7 +1637,7 @@ class TestEmbeddingEdgeCases: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None mock_model_instance.invoke_text_embedding.return_value = embedding_result # Act @@ -1728,7 +1716,7 @@ class TestEmbeddingCachePerformance: with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: # First call: cache miss - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None usage = EmbeddingUsage( tokens=5, @@ -1756,7 +1744,7 @@ class TestEmbeddingCachePerformance: assert len(result1) == 1 # Arrange - Second call: cache hit - mock_session.query.return_value.filter_by.return_value.first.return_value = mock_cached_embedding + mock_session.scalar.return_value = mock_cached_embedding # Act - Second call (cache hit) result2 = cache_embedding.embed_documents([text]) @@ -1816,7 +1804,7 @@ class TestEmbeddingCachePerformance: ) with patch("core.rag.embedding.cached_embedding.db.session") as mock_session: - mock_session.query.return_value.filter_by.return_value.first.return_value = None + mock_session.scalar.return_value = None # Mock model to return appropriate batch results batch_results = [ diff --git a/api/tests/unit_tests/core/rag/extractor/test_notion_extractor.py b/api/tests/unit_tests/core/rag/extractor/test_notion_extractor.py index 6daee11f8f..808e41867e 100644 --- a/api/tests/unit_tests/core/rag/extractor/test_notion_extractor.py +++ b/api/tests/unit_tests/core/rag/extractor/test_notion_extractor.py @@ -405,35 +405,36 @@ class TestNotionMetadataAndCredentialMethods: class FakeDocumentModel: data_source_info = "data_source_info" + id = "id" - update_calls = [] + execute_calls = [] - class FakeQuery: - def filter_by(self, **kwargs): + class FakeUpdateStmt: + def where(self, *args): return self - def update(self, payload): - update_calls.append(payload) + def values(self, **kwargs): + return self class FakeSession: committed = False - def query(self, model): - assert model is FakeDocumentModel - return FakeQuery() + def execute(self, stmt): + execute_calls.append(stmt) def commit(self): self.committed = True fake_db = SimpleNamespace(session=FakeSession()) monkeypatch.setattr(notion_extractor, "DocumentModel", FakeDocumentModel) + monkeypatch.setattr(notion_extractor, "update", lambda model: FakeUpdateStmt()) monkeypatch.setattr(notion_extractor, "db", fake_db) monkeypatch.setattr(extractor, "get_notion_last_edited_time", lambda: "2026-01-01T00:00:00.000Z") doc_model = SimpleNamespace(id="doc-1", data_source_info_dict={"source": "notion"}) extractor.update_last_edited_time(doc_model) - assert update_calls + assert execute_calls assert fake_db.session.committed is True def test_get_notion_last_edited_time_uses_page_and_database_urls(self, mocker: MockerFixture): diff --git a/api/tests/unit_tests/core/rag/indexing/processor/test_paragraph_index_processor.py b/api/tests/unit_tests/core/rag/indexing/processor/test_paragraph_index_processor.py index cc2873dd3f..d4b987c832 100644 --- a/api/tests/unit_tests/core/rag/indexing/processor/test_paragraph_index_processor.py +++ b/api/tests/unit_tests/core/rag/indexing/processor/test_paragraph_index_processor.py @@ -188,10 +188,10 @@ class TestParagraphIndexProcessor: mock_keyword_cls.return_value.add_texts.assert_called_once_with(docs) def test_clean_deletes_summaries_and_vector(self, processor: ParagraphIndexProcessor, dataset: Mock) -> None: - segment_query = Mock() - segment_query.filter.return_value.all.return_value = [SimpleNamespace(id="seg-1")] + scalars_result = Mock() + scalars_result.all.return_value = [SimpleNamespace(id="seg-1")] session = Mock() - session.query.return_value = segment_query + session.scalars.return_value = scalars_result with ( patch("core.rag.index_processor.processor.paragraph_index_processor.db.session", session), @@ -531,10 +531,10 @@ class TestParagraphIndexProcessor: size=1, key="key", ) - query = Mock() - query.where.return_value.all.return_value = [image_upload, non_image_upload] + scalars_result = Mock() + scalars_result.all.return_value = [image_upload, non_image_upload] session = Mock() - session.query.return_value = query + session.scalars.return_value = scalars_result with ( patch("core.rag.index_processor.processor.paragraph_index_processor.db.session", session), @@ -565,10 +565,10 @@ class TestParagraphIndexProcessor: size=1, key="key", ) - query = Mock() - query.where.return_value.all.return_value = [image_upload] + scalars_result = Mock() + scalars_result.all.return_value = [image_upload] session = Mock() - session.query.return_value = query + session.scalars.return_value = scalars_result with ( patch("core.rag.index_processor.processor.paragraph_index_processor.db.session", session), diff --git a/api/tests/unit_tests/core/rag/indexing/processor/test_parent_child_index_processor.py b/api/tests/unit_tests/core/rag/indexing/processor/test_parent_child_index_processor.py index b1ed735ee7..d363a0804d 100644 --- a/api/tests/unit_tests/core/rag/indexing/processor/test_parent_child_index_processor.py +++ b/api/tests/unit_tests/core/rag/indexing/processor/test_parent_child_index_processor.py @@ -208,11 +208,7 @@ class TestParentChildIndexProcessor: vector.create_multimodal.assert_called_once_with(multimodal_docs) def test_clean_with_precomputed_child_ids(self, processor: ParentChildIndexProcessor, dataset: Mock) -> None: - delete_query = Mock() - where_query = Mock() - where_query.delete.return_value = 2 session = Mock() - session.query.return_value.where.return_value = where_query with ( patch("core.rag.index_processor.processor.parent_child_index_processor.Vector") as mock_vector_cls, @@ -227,16 +223,16 @@ class TestParentChildIndexProcessor: ) vector.delete_by_ids.assert_called_once_with(["child-1", "child-2"]) - where_query.delete.assert_called_once_with(synchronize_session=False) + session.execute.assert_called() session.commit.assert_called_once() def test_clean_queries_child_ids_when_not_precomputed( self, processor: ParentChildIndexProcessor, dataset: Mock ) -> None: - child_query = Mock() - child_query.join.return_value.where.return_value.all.return_value = [("child-1",), (None,), ("child-2",)] + execute_result = Mock() + execute_result.all.return_value = [("child-1",), (None,), ("child-2",)] session = Mock() - session.query.return_value = child_query + session.execute.return_value = execute_result with ( patch("core.rag.index_processor.processor.parent_child_index_processor.Vector") as mock_vector_cls, @@ -248,10 +244,7 @@ class TestParentChildIndexProcessor: vector.delete_by_ids.assert_called_once_with(["child-1", "child-2"]) def test_clean_dataset_wide_cleanup(self, processor: ParentChildIndexProcessor, dataset: Mock) -> None: - where_query = Mock() - where_query.delete.return_value = 3 session = Mock() - session.query.return_value.where.return_value = where_query with ( patch("core.rag.index_processor.processor.parent_child_index_processor.Vector") as mock_vector_cls, @@ -261,7 +254,7 @@ class TestParentChildIndexProcessor: processor.clean(dataset, None, delete_child_chunks=True) vector.delete.assert_called_once() - where_query.delete.assert_called_once_with(synchronize_session=False) + session.execute.assert_called() session.commit.assert_called_once() def test_clean_deletes_summaries_when_requested(self, processor: ParentChildIndexProcessor, dataset: Mock) -> None: diff --git a/api/tests/unit_tests/core/rag/indexing/test_index_processor_base.py b/api/tests/unit_tests/core/rag/indexing/test_index_processor_base.py index b31bb6eea7..12c5238f5e 100644 --- a/api/tests/unit_tests/core/rag/indexing/test_index_processor_base.py +++ b/api/tests/unit_tests/core/rag/indexing/test_index_processor_base.py @@ -133,10 +133,10 @@ class TestBaseIndexProcessor: upload_b = SimpleNamespace(id="bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb", name="b.png") upload_tool = SimpleNamespace(id="tool-upload-id", name="tool.png") upload_remote = SimpleNamespace(id="remote-upload-id", name="remote.png") - db_query = Mock() - db_query.where.return_value.all.return_value = [upload_a, upload_b, upload_tool, upload_remote] + scalars_result = Mock() + scalars_result.all.return_value = [upload_a, upload_b, upload_tool, upload_remote] db_session = Mock() - db_session.query.return_value = db_query + db_session.scalars.return_value = scalars_result with ( patch.object(processor, "_extract_markdown_images", return_value=images), @@ -170,10 +170,10 @@ class TestBaseIndexProcessor: def test_get_content_files_ignores_missing_upload_records(self, processor: _ForwardingBaseIndexProcessor) -> None: document = Document(page_content="ignored", metadata={"document_id": "doc-1", "dataset_id": "ds-1"}) images = ["/files/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/image-preview"] - db_query = Mock() - db_query.where.return_value.all.return_value = [] + scalars_result = Mock() + scalars_result.all.return_value = [] db_session = Mock() - db_session.query.return_value = db_query + db_session.scalars.return_value = scalars_result with ( patch.object(processor, "_extract_markdown_images", return_value=images), @@ -259,20 +259,16 @@ class TestBaseIndexProcessor: assert processor._download_image("https://example.com/image.png", current_user=Mock()) is None def test_download_tool_file_returns_none_when_not_found(self, processor: _ForwardingBaseIndexProcessor) -> None: - db_query = Mock() - db_query.where.return_value.first.return_value = None db_session = Mock() - db_session.query.return_value = db_query + db_session.get.return_value = None with patch("core.rag.index_processor.index_processor_base.db.session", db_session): assert processor._download_tool_file("tool-id", current_user=Mock()) is None def test_download_tool_file_uploads_file_when_found(self, processor: _ForwardingBaseIndexProcessor) -> None: tool_file = SimpleNamespace(file_key="k1", name="tool.png", mimetype="image/png") - db_query = Mock() - db_query.where.return_value.first.return_value = tool_file db_session = Mock() - db_session.query.return_value = db_query + db_session.get.return_value = tool_file mock_db = Mock() mock_db.session = db_session mock_db.engine = Mock() diff --git a/api/tests/unit_tests/core/rag/rerank/test_reranker.py b/api/tests/unit_tests/core/rag/rerank/test_reranker.py index 2ec7f0498e..c279b00d3b 100644 --- a/api/tests/unit_tests/core/rag/rerank/test_reranker.py +++ b/api/tests/unit_tests/core/rag/rerank/test_reranker.py @@ -473,12 +473,10 @@ class TestRerankModelRunnerMultimodal: metadata={}, provider="external", ) - query = Mock() - query.where.return_value.first.return_value = SimpleNamespace(key="image-key") rerank_result = RerankResult(model="rerank-model", docs=[]) with ( - patch("core.rag.rerank.rerank_model.db.session.query", return_value=query), + patch("core.rag.rerank.rerank_model.db.session.get", return_value=SimpleNamespace(key="image-key")), patch("core.rag.rerank.rerank_model.storage.load_once", return_value=b"image-bytes") as mock_load_once, patch.object( rerank_runner, @@ -504,12 +502,10 @@ class TestRerankModelRunnerMultimodal: metadata={"doc_id": "img-missing", "doc_type": DocType.IMAGE}, provider="dify", ) - query = Mock() - query.where.return_value.first.return_value = None rerank_result = RerankResult(model="rerank-model", docs=[]) with ( - patch("core.rag.rerank.rerank_model.db.session.query", return_value=query), + patch("core.rag.rerank.rerank_model.db.session.get", return_value=None), patch.object( rerank_runner, "fetch_text_rerank", @@ -533,8 +529,6 @@ class TestRerankModelRunnerMultimodal: metadata={"doc_id": "txt-1", "doc_type": DocType.TEXT}, provider="dify", ) - query_chain = Mock() - query_chain.where.return_value.first.return_value = SimpleNamespace(key="query-image-key") rerank_result = RerankResult( model="rerank-model", docs=[RerankDocument(index=0, text="text-content", score=0.77)], @@ -542,7 +536,7 @@ class TestRerankModelRunnerMultimodal: mock_model_instance.invoke_multimodal_rerank.return_value = rerank_result session = MagicMock() - session.query.return_value = query_chain + session.get.return_value = SimpleNamespace(key="query-image-key") with ( patch("core.rag.rerank.rerank_model.db.session", session), patch("core.rag.rerank.rerank_model.storage.load_once", return_value=b"query-image-bytes"), @@ -563,10 +557,7 @@ class TestRerankModelRunnerMultimodal: assert "user" not in invoke_kwargs def test_fetch_multimodal_rerank_raises_when_query_image_not_found(self, rerank_runner): - query_chain = Mock() - query_chain.where.return_value.first.return_value = None - - with patch("core.rag.rerank.rerank_model.db.session.query", return_value=query_chain): + with patch("core.rag.rerank.rerank_model.db.session.get", return_value=None): with pytest.raises(ValueError, match="Upload file not found for query"): rerank_runner.fetch_multimodal_rerank( query="missing-upload-id", diff --git a/api/tests/unit_tests/core/rag/retrieval/test_dataset_retrieval.py b/api/tests/unit_tests/core/rag/retrieval/test_dataset_retrieval.py index c11426163e..fee7b168ad 100644 --- a/api/tests/unit_tests/core/rag/retrieval/test_dataset_retrieval.py +++ b/api/tests/unit_tests/core/rag/retrieval/test_dataset_retrieval.py @@ -3971,11 +3971,10 @@ class TestDatasetRetrievalAdditionalHelpers: ) def test_get_metadata_filter_condition(self, retrieval: DatasetRetrieval) -> None: - db_query = Mock() - db_query.where.return_value = db_query - db_query.all.return_value = [SimpleNamespace(dataset_id="d1", id="doc-1")] + scalars_result = Mock() + scalars_result.all.return_value = [SimpleNamespace(dataset_id="d1", id="doc-1")] - with patch("core.rag.retrieval.dataset_retrieval.db.session.query", return_value=db_query): + with patch("core.rag.retrieval.dataset_retrieval.db.session.scalars", return_value=scalars_result): mapping, condition = retrieval.get_metadata_filter_condition( dataset_ids=["d1"], query="python", @@ -3991,7 +3990,7 @@ class TestDatasetRetrievalAdditionalHelpers: automatic_filters = [{"condition": "contains", "metadata_name": "author", "value": "Alice"}] with ( - patch("core.rag.retrieval.dataset_retrieval.db.session.query", return_value=db_query), + patch("core.rag.retrieval.dataset_retrieval.db.session.scalars", return_value=scalars_result), patch.object(retrieval, "_automatic_metadata_filter_func", return_value=automatic_filters), ): mapping, condition = retrieval.get_metadata_filter_condition( @@ -4012,7 +4011,7 @@ class TestDatasetRetrievalAdditionalHelpers: logical_operator="and", conditions=[AppCondition(name="author", comparison_operator="contains", value="{{name}}")], ) - with patch("core.rag.retrieval.dataset_retrieval.db.session.query", return_value=db_query): + with patch("core.rag.retrieval.dataset_retrieval.db.session.scalars", return_value=scalars_result): mapping, condition = retrieval.get_metadata_filter_condition( dataset_ids=["d1"], query="python", @@ -4027,7 +4026,7 @@ class TestDatasetRetrievalAdditionalHelpers: assert condition is not None assert condition.conditions[0].value == "Alice" - with patch("core.rag.retrieval.dataset_retrieval.db.session.query", return_value=db_query): + with patch("core.rag.retrieval.dataset_retrieval.db.session.scalars", return_value=scalars_result): with pytest.raises(ValueError, match="Invalid metadata filtering mode"): retrieval.get_metadata_filter_condition( dataset_ids=["d1"], diff --git a/api/tests/unit_tests/core/test_provider_manager.py b/api/tests/unit_tests/core/test_provider_manager.py index 259cb5fdd0..ee26172459 100644 --- a/api/tests/unit_tests/core/test_provider_manager.py +++ b/api/tests/unit_tests/core/test_provider_manager.py @@ -48,7 +48,7 @@ def test__to_model_settings(mocker: MockerFixture, mock_provider_entity): tenant_id="tenant_id", provider_name="openai", model_name="gpt-4", - model_type="text-generation", + model_type="llm", enabled=True, load_balancing_enabled=True, ) @@ -61,7 +61,7 @@ def test__to_model_settings(mocker: MockerFixture, mock_provider_entity): tenant_id="tenant_id", provider_name="openai", model_name="gpt-4", - model_type="text-generation", + model_type="llm", name="__inherit__", encrypted_config=None, enabled=True, @@ -70,7 +70,7 @@ def test__to_model_settings(mocker: MockerFixture, mock_provider_entity): tenant_id="tenant_id", provider_name="openai", model_name="gpt-4", - model_type="text-generation", + model_type="llm", name="first", encrypted_config='{"openai_api_key": "fake_key"}', enabled=True, @@ -110,7 +110,7 @@ def test__to_model_settings_only_one_lb(mocker: MockerFixture, mock_provider_ent tenant_id="tenant_id", provider_name="openai", model_name="gpt-4", - model_type="text-generation", + model_type="llm", enabled=True, load_balancing_enabled=True, ) @@ -121,7 +121,7 @@ def test__to_model_settings_only_one_lb(mocker: MockerFixture, mock_provider_ent tenant_id="tenant_id", provider_name="openai", model_name="gpt-4", - model_type="text-generation", + model_type="llm", name="__inherit__", encrypted_config=None, enabled=True, @@ -157,7 +157,7 @@ def test__to_model_settings_lb_disabled(mocker: MockerFixture, mock_provider_ent tenant_id="tenant_id", provider_name="openai", model_name="gpt-4", - model_type="text-generation", + model_type="llm", enabled=True, load_balancing_enabled=False, ) @@ -168,7 +168,7 @@ def test__to_model_settings_lb_disabled(mocker: MockerFixture, mock_provider_ent tenant_id="tenant_id", provider_name="openai", model_name="gpt-4", - model_type="text-generation", + model_type="llm", name="__inherit__", encrypted_config=None, enabled=True, @@ -177,7 +177,7 @@ def test__to_model_settings_lb_disabled(mocker: MockerFixture, mock_provider_ent tenant_id="tenant_id", provider_name="openai", model_name="gpt-4", - model_type="text-generation", + model_type="llm", name="first", encrypted_config='{"openai_api_key": "fake_key"}', enabled=True, @@ -270,7 +270,7 @@ def test_get_default_model_uses_injected_runtime_for_existing_default_record(moc tenant_id="tenant-id", provider_name="openai", model_name="gpt-4", - model_type=ModelType.LLM.to_origin_model_type(), + model_type=ModelType.LLM, ) mock_session = Mock() mock_session.scalar.return_value = existing_default_model @@ -449,7 +449,7 @@ def test_update_default_model_record_updates_existing_record(mocker: MockerFixtu tenant_id="tenant-id", provider_name="anthropic", model_name="claude-3-sonnet", - model_type=ModelType.LLM.to_origin_model_type(), + model_type=ModelType.LLM, ) mock_session = Mock() mock_session.scalar.return_value = existing_default_model @@ -487,7 +487,7 @@ def test_update_default_model_record_creates_record_with_origin_model_type(mocke assert created_default_model.tenant_id == "tenant-id" assert created_default_model.provider_name == "openai" assert created_default_model.model_name == "gpt-4" - assert created_default_model.model_type == ModelType.LLM.to_origin_model_type() + assert created_default_model.model_type == ModelType.LLM mock_session.commit.assert_called_once() diff --git a/api/tests/unit_tests/models/test_provider_models.py b/api/tests/unit_tests/models/test_provider_models.py index f628e54a4d..d7b597e5fb 100644 --- a/api/tests/unit_tests/models/test_provider_models.py +++ b/api/tests/unit_tests/models/test_provider_models.py @@ -202,7 +202,7 @@ class TestProviderModel: # Assert assert provider.provider_type == ProviderType.CUSTOM assert provider.is_valid is False - assert provider.quota_type == "" + assert provider.quota_type is None assert provider.quota_limit is None assert provider.quota_used == 0 assert provider.credential_id is None diff --git a/api/tests/unit_tests/services/enterprise/test_enterprise_service.py b/api/tests/unit_tests/services/enterprise/test_enterprise_service.py index 59c07bfb37..6ad6a490b0 100644 --- a/api/tests/unit_tests/services/enterprise/test_enterprise_service.py +++ b/api/tests/unit_tests/services/enterprise/test_enterprise_service.py @@ -5,6 +5,7 @@ Covers: - License status caching (get_cached_license_status) """ +from datetime import datetime from unittest.mock import patch import pytest @@ -15,9 +16,178 @@ from services.enterprise.enterprise_service import ( VALID_LICENSE_CACHE_TTL, DefaultWorkspaceJoinResult, EnterpriseService, + WebAppSettings, + WorkspacePermission, try_join_default_workspace, ) +MODULE = "services.enterprise.enterprise_service" + + +class TestEnterpriseServiceInfo: + def test_get_info_delegates(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = {"version": "1.0"} + result = EnterpriseService.get_info() + + req.send_request.assert_called_once_with("GET", "/info") + assert result == {"version": "1.0"} + + def test_get_workspace_info_delegates(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = {"name": "ws"} + result = EnterpriseService.get_workspace_info("tenant-1") + + req.send_request.assert_called_once_with("GET", "/workspace/tenant-1/info") + assert result == {"name": "ws"} + + +class TestSsoSettingsLastUpdateTime: + def test_app_sso_parses_valid_timestamp(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = "2025-01-15T10:30:00+00:00" + result = EnterpriseService.get_app_sso_settings_last_update_time() + + assert isinstance(result, datetime) + assert result.year == 2025 + + def test_app_sso_raises_on_empty(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = "" + with pytest.raises(ValueError, match="No data found"): + EnterpriseService.get_app_sso_settings_last_update_time() + + def test_app_sso_raises_on_invalid_format(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = "not-a-date" + with pytest.raises(ValueError, match="Invalid date format"): + EnterpriseService.get_app_sso_settings_last_update_time() + + def test_workspace_sso_parses_valid_timestamp(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = "2025-06-01T00:00:00+00:00" + result = EnterpriseService.get_workspace_sso_settings_last_update_time() + + assert isinstance(result, datetime) + + def test_workspace_sso_raises_on_empty(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = None + with pytest.raises(ValueError, match="No data found"): + EnterpriseService.get_workspace_sso_settings_last_update_time() + + +class TestWorkspacePermissionService: + def test_raises_on_empty_workspace_id(self): + with pytest.raises(ValueError, match="workspace_id must be provided"): + EnterpriseService.WorkspacePermissionService.get_permission("") + + def test_raises_on_missing_data(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = None + with pytest.raises(ValueError, match="No data found"): + EnterpriseService.WorkspacePermissionService.get_permission("ws-1") + + def test_raises_on_missing_permission_key(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = {"other": "data"} + with pytest.raises(ValueError, match="No data found"): + EnterpriseService.WorkspacePermissionService.get_permission("ws-1") + + def test_returns_parsed_permission(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = { + "permission": { + "workspaceId": "ws-1", + "allowMemberInvite": True, + "allowOwnerTransfer": False, + } + } + result = EnterpriseService.WorkspacePermissionService.get_permission("ws-1") + + assert isinstance(result, WorkspacePermission) + assert result.workspace_id == "ws-1" + assert result.allow_member_invite is True + assert result.allow_owner_transfer is False + + +class TestWebAppAuth: + def test_is_user_allowed_returns_result_field(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = {"result": True} + assert EnterpriseService.WebAppAuth.is_user_allowed_to_access_webapp("u1", "a1") is True + + def test_is_user_allowed_defaults_false(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = {} + assert EnterpriseService.WebAppAuth.is_user_allowed_to_access_webapp("u1", "a1") is False + + def test_batch_is_user_allowed_returns_empty_for_no_apps(self): + assert EnterpriseService.WebAppAuth.batch_is_user_allowed_to_access_webapps("u1", []) == {} + + def test_batch_is_user_allowed_raises_on_empty_response(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = None + with pytest.raises(ValueError, match="No data found"): + EnterpriseService.WebAppAuth.batch_is_user_allowed_to_access_webapps("u1", ["a1"]) + + def test_get_app_access_mode_raises_on_empty_app_id(self): + with pytest.raises(ValueError, match="app_id must be provided"): + EnterpriseService.WebAppAuth.get_app_access_mode_by_id("") + + def test_get_app_access_mode_returns_settings(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = {"accessMode": "public"} + result = EnterpriseService.WebAppAuth.get_app_access_mode_by_id("a1") + + assert isinstance(result, WebAppSettings) + assert result.access_mode == "public" + + def test_batch_get_returns_empty_for_no_apps(self): + assert EnterpriseService.WebAppAuth.batch_get_app_access_mode_by_id([]) == {} + + def test_batch_get_maps_access_modes(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = {"accessModes": {"a1": "public", "a2": "private"}} + result = EnterpriseService.WebAppAuth.batch_get_app_access_mode_by_id(["a1", "a2"]) + + assert result["a1"].access_mode == "public" + assert result["a2"].access_mode == "private" + + def test_batch_get_raises_on_invalid_format(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = {"accessModes": "not-a-dict"} + with pytest.raises(ValueError, match="Invalid data format"): + EnterpriseService.WebAppAuth.batch_get_app_access_mode_by_id(["a1"]) + + def test_update_access_mode_raises_on_empty_app_id(self): + with pytest.raises(ValueError, match="app_id must be provided"): + EnterpriseService.WebAppAuth.update_app_access_mode("", "public") + + def test_update_access_mode_raises_on_invalid_mode(self): + with pytest.raises(ValueError, match="access_mode must be"): + EnterpriseService.WebAppAuth.update_app_access_mode("a1", "invalid") + + def test_update_access_mode_delegates_and_returns(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + req.send_request.return_value = {"result": True} + result = EnterpriseService.WebAppAuth.update_app_access_mode("a1", "public") + + assert result is True + req.send_request.assert_called_once_with( + "POST", "/webapp/access-mode", json={"appId": "a1", "accessMode": "public"} + ) + + def test_cleanup_webapp_raises_on_empty_app_id(self): + with pytest.raises(ValueError, match="app_id must be provided"): + EnterpriseService.WebAppAuth.cleanup_webapp("") + + def test_cleanup_webapp_delegates(self): + with patch(f"{MODULE}.EnterpriseRequest") as req: + EnterpriseService.WebAppAuth.cleanup_webapp("a1") + + req.send_request.assert_called_once_with("DELETE", "/webapp/clean", params={"appId": "a1"}) + class TestJoinDefaultWorkspace: def test_join_default_workspace_success(self): diff --git a/api/tests/unit_tests/services/enterprise/test_plugin_manager_service.py b/api/tests/unit_tests/services/enterprise/test_plugin_manager_service.py index 6ee328ae2c..759d907934 100644 --- a/api/tests/unit_tests/services/enterprise/test_plugin_manager_service.py +++ b/api/tests/unit_tests/services/enterprise/test_plugin_manager_service.py @@ -7,14 +7,20 @@ This module covers the pre-uninstall plugin hook behavior: from unittest.mock import patch +import pytest from httpx import HTTPStatusError from configs import dify_config from services.enterprise.plugin_manager_service import ( + CheckCredentialPolicyComplianceRequest, + CredentialPolicyViolationError, + PluginCredentialType, PluginManagerService, PreUninstallPluginRequest, ) +MODULE = "services.enterprise.plugin_manager_service" + class TestTryPreUninstallPlugin: def test_try_pre_uninstall_plugin_success(self): @@ -88,3 +94,46 @@ class TestTryPreUninstallPlugin: timeout=dify_config.ENTERPRISE_REQUEST_TIMEOUT, ) mock_logger.exception.assert_called_once() + + +class TestCheckCredentialPolicyCompliance: + def _request(self, cred_type=PluginCredentialType.MODEL): + return CheckCredentialPolicyComplianceRequest( + dify_credential_id="cred-1", provider="openai", credential_type=cred_type + ) + + def test_passes_when_result_true(self): + with patch(f"{MODULE}.EnterprisePluginManagerRequest") as req: + req.send_request.return_value = {"result": True} + PluginManagerService.check_credential_policy_compliance(self._request()) + + req.send_request.assert_called_once() + + def test_raises_violation_when_result_false(self): + with patch(f"{MODULE}.EnterprisePluginManagerRequest") as req: + req.send_request.return_value = {"result": False} + with pytest.raises(CredentialPolicyViolationError, match="Credentials not available"): + PluginManagerService.check_credential_policy_compliance(self._request()) + + def test_raises_violation_on_invalid_response_format(self): + with patch(f"{MODULE}.EnterprisePluginManagerRequest") as req: + req.send_request.return_value = "not-a-dict" + with pytest.raises(CredentialPolicyViolationError, match="error occurred"): + PluginManagerService.check_credential_policy_compliance(self._request()) + + def test_raises_violation_on_api_exception(self): + with patch(f"{MODULE}.EnterprisePluginManagerRequest") as req: + req.send_request.side_effect = ConnectionError("network fail") + with pytest.raises(CredentialPolicyViolationError, match="error occurred"): + PluginManagerService.check_credential_policy_compliance(self._request()) + + def test_model_dump_serializes_credential_type_as_number(self): + body = self._request(PluginCredentialType.TOOL) + data = body.model_dump() + + assert data["credential_type"] == 1 + assert data["dify_credential_id"] == "cred-1" + + def test_model_credential_type_values(self): + assert PluginCredentialType.MODEL.to_number() == 0 + assert PluginCredentialType.TOOL.to_number() == 1 diff --git a/api/tests/unit_tests/services/plugin/test_oauth_service.py b/api/tests/unit_tests/services/plugin/test_oauth_service.py index 6511385000..eee65b3a18 100644 --- a/api/tests/unit_tests/services/plugin/test_oauth_service.py +++ b/api/tests/unit_tests/services/plugin/test_oauth_service.py @@ -93,3 +93,20 @@ class TestUseProxyContext: assert result == stored expected_key = "oauth_proxy_context:valid-id" redis_client.delete.assert_called_once_with(expected_key) + + def test_returns_context_with_credential_id(self): + from extensions.ext_redis import redis_client + + stored = { + "user_id": "u1", + "tenant_id": "t1", + "plugin_id": "p1", + "provider": "github", + "credential_id": "cred-42", + } + redis_client.get.return_value = json.dumps(stored).encode() + + result = OAuthProxyService.use_proxy_context("ctx-with-cred") + + assert result["credential_id"] == "cred-42" + assert result["tenant_id"] == "t1" diff --git a/api/tests/unit_tests/services/plugin/test_plugin_auto_upgrade_service.py b/api/tests/unit_tests/services/plugin/test_plugin_auto_upgrade_service.py new file mode 100644 index 0000000000..edb50d09a6 --- /dev/null +++ b/api/tests/unit_tests/services/plugin/test_plugin_auto_upgrade_service.py @@ -0,0 +1,183 @@ +from unittest.mock import MagicMock, patch + +from models.account import TenantPluginAutoUpgradeStrategy + +MODULE = "services.plugin.plugin_auto_upgrade_service" + + +def _patched_session(): + """Patch Session(db.engine) to return a mock session as context manager.""" + session = MagicMock() + session_cls = MagicMock() + session_cls.return_value.__enter__ = MagicMock(return_value=session) + session_cls.return_value.__exit__ = MagicMock(return_value=False) + patcher = patch(f"{MODULE}.Session", session_cls) + db_patcher = patch(f"{MODULE}.db") + return patcher, db_patcher, session + + +class TestGetStrategy: + def test_returns_strategy_when_found(self): + p1, p2, session = _patched_session() + strategy = MagicMock() + session.query.return_value.where.return_value.first.return_value = strategy + + with p1, p2: + from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService + + result = PluginAutoUpgradeService.get_strategy("t1") + + assert result is strategy + + def test_returns_none_when_not_found(self): + p1, p2, session = _patched_session() + session.query.return_value.where.return_value.first.return_value = None + + with p1, p2: + from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService + + result = PluginAutoUpgradeService.get_strategy("t1") + + assert result is None + + +class TestChangeStrategy: + def test_creates_new_strategy(self): + p1, p2, session = _patched_session() + session.query.return_value.where.return_value.first.return_value = None + + with p1, p2, patch(f"{MODULE}.TenantPluginAutoUpgradeStrategy") as strat_cls: + strat_cls.return_value = MagicMock() + from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService + + result = PluginAutoUpgradeService.change_strategy( + "t1", + TenantPluginAutoUpgradeStrategy.StrategySetting.FIX_ONLY, + 3, + TenantPluginAutoUpgradeStrategy.UpgradeMode.ALL, + [], + [], + ) + + assert result is True + session.add.assert_called_once() + session.commit.assert_called_once() + + def test_updates_existing_strategy(self): + p1, p2, session = _patched_session() + existing = MagicMock() + session.query.return_value.where.return_value.first.return_value = existing + + with p1, p2: + from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService + + result = PluginAutoUpgradeService.change_strategy( + "t1", + TenantPluginAutoUpgradeStrategy.StrategySetting.LATEST, + 5, + TenantPluginAutoUpgradeStrategy.UpgradeMode.PARTIAL, + ["p1"], + ["p2"], + ) + + assert result is True + assert existing.strategy_setting == TenantPluginAutoUpgradeStrategy.StrategySetting.LATEST + assert existing.upgrade_time_of_day == 5 + assert existing.upgrade_mode == TenantPluginAutoUpgradeStrategy.UpgradeMode.PARTIAL + assert existing.exclude_plugins == ["p1"] + assert existing.include_plugins == ["p2"] + session.commit.assert_called_once() + + +class TestExcludePlugin: + def test_creates_default_strategy_when_none_exists(self): + p1, p2, session = _patched_session() + session.query.return_value.where.return_value.first.return_value = None + + with ( + p1, + p2, + patch(f"{MODULE}.TenantPluginAutoUpgradeStrategy") as strat_cls, + patch(f"{MODULE}.PluginAutoUpgradeService.change_strategy") as cs, + ): + strat_cls.StrategySetting.FIX_ONLY = "fix_only" + strat_cls.UpgradeMode.EXCLUDE = "exclude" + cs.return_value = True + from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService + + result = PluginAutoUpgradeService.exclude_plugin("t1", "plugin-1") + + assert result is True + cs.assert_called_once() + + def test_appends_to_exclude_list_in_exclude_mode(self): + p1, p2, session = _patched_session() + existing = MagicMock() + existing.upgrade_mode = "exclude" + existing.exclude_plugins = ["p-existing"] + session.query.return_value.where.return_value.first.return_value = existing + + with p1, p2, patch(f"{MODULE}.TenantPluginAutoUpgradeStrategy") as strat_cls: + strat_cls.UpgradeMode.EXCLUDE = "exclude" + strat_cls.UpgradeMode.PARTIAL = "partial" + strat_cls.UpgradeMode.ALL = "all" + from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService + + result = PluginAutoUpgradeService.exclude_plugin("t1", "p-new") + + assert result is True + assert existing.exclude_plugins == ["p-existing", "p-new"] + session.commit.assert_called_once() + + def test_removes_from_include_list_in_partial_mode(self): + p1, p2, session = _patched_session() + existing = MagicMock() + existing.upgrade_mode = "partial" + existing.include_plugins = ["p1", "p2"] + session.query.return_value.where.return_value.first.return_value = existing + + with p1, p2, patch(f"{MODULE}.TenantPluginAutoUpgradeStrategy") as strat_cls: + strat_cls.UpgradeMode.EXCLUDE = "exclude" + strat_cls.UpgradeMode.PARTIAL = "partial" + strat_cls.UpgradeMode.ALL = "all" + from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService + + result = PluginAutoUpgradeService.exclude_plugin("t1", "p1") + + assert result is True + assert existing.include_plugins == ["p2"] + + def test_switches_to_exclude_mode_from_all(self): + p1, p2, session = _patched_session() + existing = MagicMock() + existing.upgrade_mode = "all" + session.query.return_value.where.return_value.first.return_value = existing + + with p1, p2, patch(f"{MODULE}.TenantPluginAutoUpgradeStrategy") as strat_cls: + strat_cls.UpgradeMode.EXCLUDE = "exclude" + strat_cls.UpgradeMode.PARTIAL = "partial" + strat_cls.UpgradeMode.ALL = "all" + from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService + + result = PluginAutoUpgradeService.exclude_plugin("t1", "p1") + + assert result is True + assert existing.upgrade_mode == "exclude" + assert existing.exclude_plugins == ["p1"] + + def test_no_duplicate_in_exclude_list(self): + p1, p2, session = _patched_session() + existing = MagicMock() + existing.upgrade_mode = "exclude" + existing.exclude_plugins = ["p1"] + session.query.return_value.where.return_value.first.return_value = existing + + with p1, p2, patch(f"{MODULE}.TenantPluginAutoUpgradeStrategy") as strat_cls: + strat_cls.UpgradeMode.EXCLUDE = "exclude" + strat_cls.UpgradeMode.PARTIAL = "partial" + strat_cls.UpgradeMode.ALL = "all" + from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService + + PluginAutoUpgradeService.exclude_plugin("t1", "p1") + + assert existing.exclude_plugins == ["p1"] diff --git a/api/tests/unit_tests/services/plugin/test_plugin_permission_service.py b/api/tests/unit_tests/services/plugin/test_plugin_permission_service.py new file mode 100644 index 0000000000..69091110db --- /dev/null +++ b/api/tests/unit_tests/services/plugin/test_plugin_permission_service.py @@ -0,0 +1,75 @@ +from unittest.mock import MagicMock, patch + +from models.account import TenantPluginPermission + +MODULE = "services.plugin.plugin_permission_service" + + +def _patched_session(): + """Patch Session(db.engine) to return a mock session as context manager.""" + session = MagicMock() + session_cls = MagicMock() + session_cls.return_value.__enter__ = MagicMock(return_value=session) + session_cls.return_value.__exit__ = MagicMock(return_value=False) + patcher = patch(f"{MODULE}.Session", session_cls) + db_patcher = patch(f"{MODULE}.db") + return patcher, db_patcher, session + + +class TestGetPermission: + def test_returns_permission_when_found(self): + p1, p2, session = _patched_session() + permission = MagicMock() + session.query.return_value.where.return_value.first.return_value = permission + + with p1, p2: + from services.plugin.plugin_permission_service import PluginPermissionService + + result = PluginPermissionService.get_permission("t1") + + assert result is permission + + def test_returns_none_when_not_found(self): + p1, p2, session = _patched_session() + session.query.return_value.where.return_value.first.return_value = None + + with p1, p2: + from services.plugin.plugin_permission_service import PluginPermissionService + + result = PluginPermissionService.get_permission("t1") + + assert result is None + + +class TestChangePermission: + def test_creates_new_permission_when_not_exists(self): + p1, p2, session = _patched_session() + session.query.return_value.where.return_value.first.return_value = None + + with p1, p2, patch(f"{MODULE}.TenantPluginPermission") as perm_cls: + perm_cls.return_value = MagicMock() + from services.plugin.plugin_permission_service import PluginPermissionService + + result = PluginPermissionService.change_permission( + "t1", TenantPluginPermission.InstallPermission.EVERYONE, TenantPluginPermission.DebugPermission.EVERYONE + ) + + session.add.assert_called_once() + session.commit.assert_called_once() + + def test_updates_existing_permission(self): + p1, p2, session = _patched_session() + existing = MagicMock() + session.query.return_value.where.return_value.first.return_value = existing + + with p1, p2: + from services.plugin.plugin_permission_service import PluginPermissionService + + result = PluginPermissionService.change_permission( + "t1", TenantPluginPermission.InstallPermission.ADMINS, TenantPluginPermission.DebugPermission.ADMINS + ) + + assert existing.install_permission == TenantPluginPermission.InstallPermission.ADMINS + assert existing.debug_permission == TenantPluginPermission.DebugPermission.ADMINS + session.commit.assert_called_once() + session.add.assert_not_called() diff --git a/api/tests/unit_tests/services/retention/__init__.py b/api/tests/unit_tests/services/retention/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/unit_tests/services/retention/test_messages_clean_policy.py b/api/tests/unit_tests/services/retention/test_messages_clean_policy.py new file mode 100644 index 0000000000..79c079c683 --- /dev/null +++ b/api/tests/unit_tests/services/retention/test_messages_clean_policy.py @@ -0,0 +1,135 @@ +import datetime +from unittest.mock import MagicMock, patch + +from services.retention.conversation.messages_clean_policy import ( + BillingDisabledPolicy, + BillingSandboxPolicy, + SimpleMessage, + create_message_clean_policy, +) + +MODULE = "services.retention.conversation.messages_clean_policy" + + +def _msg(msg_id: str, app_id: str, days_ago: int = 0) -> SimpleMessage: + return SimpleMessage( + id=msg_id, + app_id=app_id, + created_at=datetime.datetime.now(datetime.UTC) - datetime.timedelta(days=days_ago), + ) + + +class TestBillingDisabledPolicy: + def test_returns_all_message_ids(self): + policy = BillingDisabledPolicy() + msgs = [_msg("m1", "app1"), _msg("m2", "app2"), _msg("m3", "app1")] + + result = policy.filter_message_ids(msgs, {"app1": "t1", "app2": "t2"}) + + assert set(result) == {"m1", "m2", "m3"} + + def test_empty_messages_returns_empty(self): + assert BillingDisabledPolicy().filter_message_ids([], {}) == [] + + +class TestBillingSandboxPolicy: + def _policy(self, plans, *, graceful_days=21, whitelist=None, now=1_000_000_000): + return BillingSandboxPolicy( + plan_provider=lambda _ids: plans, + graceful_period_days=graceful_days, + tenant_whitelist=whitelist, + current_timestamp=now, + ) + + def test_empty_messages_returns_empty(self): + policy = self._policy({}) + assert policy.filter_message_ids([], {"app1": "t1"}) == [] + + def test_empty_app_to_tenant_returns_empty(self): + policy = self._policy({}) + assert policy.filter_message_ids([_msg("m1", "app1")], {}) == [] + + def test_empty_plans_returns_empty(self): + policy = self._policy({}) + msgs = [_msg("m1", "app1")] + assert policy.filter_message_ids(msgs, {"app1": "t1"}) == [] + + def test_non_sandbox_tenant_skipped(self): + plans = {"t1": {"plan": "professional", "expiration_date": 0}} + policy = self._policy(plans) + msgs = [_msg("m1", "app1")] + + assert policy.filter_message_ids(msgs, {"app1": "t1"}) == [] + + def test_sandbox_no_previous_subscription_deletes(self): + plans = {"t1": {"plan": "sandbox", "expiration_date": -1}} + policy = self._policy(plans) + msgs = [_msg("m1", "app1")] + + assert policy.filter_message_ids(msgs, {"app1": "t1"}) == ["m1"] + + def test_sandbox_expired_beyond_grace_period_deletes(self): + now = 1_000_000_000 + expired_long_ago = now - (22 * 24 * 60 * 60) # 22 days ago > 21 day grace + plans = {"t1": {"plan": "sandbox", "expiration_date": expired_long_ago}} + policy = self._policy(plans, now=now) + msgs = [_msg("m1", "app1")] + + assert policy.filter_message_ids(msgs, {"app1": "t1"}) == ["m1"] + + def test_sandbox_within_grace_period_kept(self): + now = 1_000_000_000 + expired_recently = now - (10 * 24 * 60 * 60) # 10 days ago < 21 day grace + plans = {"t1": {"plan": "sandbox", "expiration_date": expired_recently}} + policy = self._policy(plans, now=now) + msgs = [_msg("m1", "app1")] + + assert policy.filter_message_ids(msgs, {"app1": "t1"}) == [] + + def test_whitelisted_tenant_skipped(self): + plans = {"t1": {"plan": "sandbox", "expiration_date": -1}} + policy = self._policy(plans, whitelist=["t1"]) + msgs = [_msg("m1", "app1")] + + assert policy.filter_message_ids(msgs, {"app1": "t1"}) == [] + + def test_message_without_tenant_mapping_skipped(self): + plans = {"t1": {"plan": "sandbox", "expiration_date": -1}} + policy = self._policy(plans) + msgs = [_msg("m1", "unmapped_app")] + + assert policy.filter_message_ids(msgs, {"app1": "t1"}) == [] + + def test_mixed_tenants_only_sandbox_deleted(self): + plans = { + "t_sandbox": {"plan": "sandbox", "expiration_date": -1}, + "t_pro": {"plan": "professional", "expiration_date": 0}, + } + policy = self._policy(plans) + msgs = [_msg("m1", "app_sandbox"), _msg("m2", "app_pro")] + app_map = {"app_sandbox": "t_sandbox", "app_pro": "t_pro"} + + result = policy.filter_message_ids(msgs, app_map) + + assert result == ["m1"] + + +class TestCreateMessageCleanPolicy: + def test_billing_disabled_returns_disabled_policy(self): + with patch(f"{MODULE}.dify_config") as cfg: + cfg.BILLING_ENABLED = False + policy = create_message_clean_policy() + + assert isinstance(policy, BillingDisabledPolicy) + + def test_billing_enabled_returns_sandbox_policy(self): + with ( + patch(f"{MODULE}.dify_config") as cfg, + patch(f"{MODULE}.BillingService") as bs, + ): + cfg.BILLING_ENABLED = True + bs.get_expired_subscription_cleanup_whitelist.return_value = ["wl1"] + bs.get_plan_bulk_with_cache = MagicMock() + policy = create_message_clean_policy(graceful_period_days=30) + + assert isinstance(policy, BillingSandboxPolicy) diff --git a/api/tests/unit_tests/services/retention/workflow_run/test_restore_archived_workflow_run.py b/api/tests/unit_tests/services/retention/workflow_run/test_restore_archived_workflow_run.py index 4bfdba87a0..628e4e594d 100644 --- a/api/tests/unit_tests/services/retention/workflow_run/test_restore_archived_workflow_run.py +++ b/api/tests/unit_tests/services/retention/workflow_run/test_restore_archived_workflow_run.py @@ -13,6 +13,7 @@ from datetime import datetime from unittest.mock import Mock, create_autospec, patch import pytest +from pydantic import ValidationError from sqlalchemy import Column, Integer, MetaData, String, Table from libs.archive_storage import ArchiveStorageNotConfiguredError @@ -292,7 +293,7 @@ class TestLoadManifestFromZip: zip_buffer.seek(0) with zipfile.ZipFile(zip_buffer, "r") as archive: - with pytest.raises(json.JSONDecodeError): + with pytest.raises(ValidationError): WorkflowRunRestore._load_manifest_from_zip(archive) diff --git a/api/tests/unit_tests/services/test_model_load_balancing_service.py b/api/tests/unit_tests/services/test_model_load_balancing_service.py index b43e79dff5..f85f1ace16 100644 --- a/api/tests/unit_tests/services/test_model_load_balancing_service.py +++ b/api/tests/unit_tests/services/test_model_load_balancing_service.py @@ -317,7 +317,7 @@ def test_init_inherit_config_should_create_and_persist_inherit_configuration( assert inherit_config.tenant_id == "tenant-1" assert inherit_config.provider_name == "openai" assert inherit_config.model_name == "gpt-4o-mini" - assert inherit_config.model_type == "text-generation" + assert inherit_config.model_type == "llm" assert inherit_config.name == "__inherit__" mock_db.session.add.assert_called_once_with(inherit_config) mock_db.session.commit.assert_called_once() diff --git a/api/tests/unit_tests/services/tools/test_tools_transform_service.py b/api/tests/unit_tests/services/tools/test_tools_transform_service.py new file mode 100644 index 0000000000..32c1a00d30 --- /dev/null +++ b/api/tests/unit_tests/services/tools/test_tools_transform_service.py @@ -0,0 +1,598 @@ +from unittest.mock import MagicMock, Mock, patch + +from core.tools.__base.tool import Tool +from core.tools.entities.api_entities import ToolApiEntity, ToolProviderApiEntity +from core.tools.entities.common_entities import I18nObject +from core.tools.entities.tool_entities import ApiProviderAuthType, ToolParameter, ToolProviderType +from services.tools.tools_transform_service import ToolTransformService + +MODULE = "services.tools.tools_transform_service" + + +class TestToolTransformService: + """Test cases for ToolTransformService.convert_tool_entity_to_api_entity method""" + + def test_convert_tool_with_parameter_override(self): + """Test that runtime parameters correctly override base parameters""" + # Create mock base parameters + base_param1 = Mock(spec=ToolParameter) + base_param1.name = "param1" + base_param1.form = ToolParameter.ToolParameterForm.FORM + base_param1.type = "string" + base_param1.label = "Base Param 1" + + base_param2 = Mock(spec=ToolParameter) + base_param2.name = "param2" + base_param2.form = ToolParameter.ToolParameterForm.FORM + base_param2.type = "string" + base_param2.label = "Base Param 2" + + # Create mock runtime parameters that override base parameters + runtime_param1 = Mock(spec=ToolParameter) + runtime_param1.name = "param1" + runtime_param1.form = ToolParameter.ToolParameterForm.FORM + runtime_param1.type = "string" + runtime_param1.label = "Runtime Param 1" # Different label to verify override + + # Create mock tool + mock_tool = Mock(spec=Tool) + mock_tool.entity = Mock() + mock_tool.entity.parameters = [base_param1, base_param2] + mock_tool.entity.identity = Mock() + mock_tool.entity.identity.author = "test_author" + mock_tool.entity.identity.name = "test_tool" + mock_tool.entity.identity.label = I18nObject(en_US="Test Tool") + mock_tool.entity.description = Mock() + mock_tool.entity.description.human = I18nObject(en_US="Test description") + mock_tool.entity.output_schema = {} + mock_tool.get_runtime_parameters.return_value = [runtime_param1] + + # Mock fork_tool_runtime to return the same tool + mock_tool.fork_tool_runtime.return_value = mock_tool + + # Call the method + result = ToolTransformService.convert_tool_entity_to_api_entity(mock_tool, "test_tenant", None) + + # Verify the result + assert isinstance(result, ToolApiEntity) + assert result.author == "test_author" + assert result.name == "test_tool" + assert result.parameters is not None + assert len(result.parameters) == 2 + + # Find the overridden parameter + overridden_param = next((p for p in result.parameters if p.name == "param1"), None) + assert overridden_param is not None + assert overridden_param.label == "Runtime Param 1" # Should be runtime version + + # Find the non-overridden parameter + original_param = next((p for p in result.parameters if p.name == "param2"), None) + assert original_param is not None + assert original_param.label == "Base Param 2" # Should be base version + + def test_convert_tool_with_additional_runtime_parameters(self): + """Test that additional runtime parameters are added to the final list""" + # Create mock base parameters + base_param1 = Mock(spec=ToolParameter) + base_param1.name = "param1" + base_param1.form = ToolParameter.ToolParameterForm.FORM + base_param1.type = "string" + base_param1.label = "Base Param 1" + + # Create mock runtime parameters - one that overrides and one that's new + runtime_param1 = Mock(spec=ToolParameter) + runtime_param1.name = "param1" + runtime_param1.form = ToolParameter.ToolParameterForm.FORM + runtime_param1.type = "string" + runtime_param1.label = "Runtime Param 1" + + runtime_param2 = Mock(spec=ToolParameter) + runtime_param2.name = "runtime_only" + runtime_param2.form = ToolParameter.ToolParameterForm.FORM + runtime_param2.type = "string" + runtime_param2.label = "Runtime Only Param" + + # Create mock tool + mock_tool = Mock(spec=Tool) + mock_tool.entity = Mock() + mock_tool.entity.parameters = [base_param1] + mock_tool.entity.identity = Mock() + mock_tool.entity.identity.author = "test_author" + mock_tool.entity.identity.name = "test_tool" + mock_tool.entity.identity.label = I18nObject(en_US="Test Tool") + mock_tool.entity.description = Mock() + mock_tool.entity.description.human = I18nObject(en_US="Test description") + mock_tool.entity.output_schema = {} + mock_tool.get_runtime_parameters.return_value = [runtime_param1, runtime_param2] + + # Mock fork_tool_runtime to return the same tool + mock_tool.fork_tool_runtime.return_value = mock_tool + + # Call the method + result = ToolTransformService.convert_tool_entity_to_api_entity(mock_tool, "test_tenant", None) + + # Verify the result + assert isinstance(result, ToolApiEntity) + assert result.parameters is not None + assert len(result.parameters) == 2 + + # Check that both parameters are present + param_names = [p.name for p in result.parameters] + assert "param1" in param_names + assert "runtime_only" in param_names + + # Verify the overridden parameter has runtime version + overridden_param = next((p for p in result.parameters if p.name == "param1"), None) + assert overridden_param is not None + assert overridden_param.label == "Runtime Param 1" + + # Verify the new runtime parameter is included + new_param = next((p for p in result.parameters if p.name == "runtime_only"), None) + assert new_param is not None + assert new_param.label == "Runtime Only Param" + + def test_convert_tool_with_non_form_runtime_parameters(self): + """Test that non-FORM runtime parameters are not added as new parameters""" + # Create mock base parameters + base_param1 = Mock(spec=ToolParameter) + base_param1.name = "param1" + base_param1.form = ToolParameter.ToolParameterForm.FORM + base_param1.type = "string" + base_param1.label = "Base Param 1" + + # Create mock runtime parameters with different forms + runtime_param1 = Mock(spec=ToolParameter) + runtime_param1.name = "param1" + runtime_param1.form = ToolParameter.ToolParameterForm.FORM + runtime_param1.type = "string" + runtime_param1.label = "Runtime Param 1" + + runtime_param2 = Mock(spec=ToolParameter) + runtime_param2.name = "llm_param" + runtime_param2.form = ToolParameter.ToolParameterForm.LLM + runtime_param2.type = "string" + runtime_param2.label = "LLM Param" + + # Create mock tool + mock_tool = Mock(spec=Tool) + mock_tool.entity = Mock() + mock_tool.entity.parameters = [base_param1] + mock_tool.entity.identity = Mock() + mock_tool.entity.identity.author = "test_author" + mock_tool.entity.identity.name = "test_tool" + mock_tool.entity.identity.label = I18nObject(en_US="Test Tool") + mock_tool.entity.description = Mock() + mock_tool.entity.description.human = I18nObject(en_US="Test description") + mock_tool.entity.output_schema = {} + mock_tool.get_runtime_parameters.return_value = [runtime_param1, runtime_param2] + + # Mock fork_tool_runtime to return the same tool + mock_tool.fork_tool_runtime.return_value = mock_tool + + # Call the method + result = ToolTransformService.convert_tool_entity_to_api_entity(mock_tool, "test_tenant", None) + + # Verify the result + assert isinstance(result, ToolApiEntity) + assert result.parameters is not None + assert len(result.parameters) == 1 # Only the FORM parameter should be present + + # Check that only the FORM parameter is present + param_names = [p.name for p in result.parameters] + assert "param1" in param_names + assert "llm_param" not in param_names + + def test_convert_tool_with_empty_parameters(self): + """Test conversion with empty base and runtime parameters""" + # Create mock tool with no parameters + mock_tool = Mock(spec=Tool) + mock_tool.entity = Mock() + mock_tool.entity.parameters = [] + mock_tool.entity.identity = Mock() + mock_tool.entity.identity.author = "test_author" + mock_tool.entity.identity.name = "test_tool" + mock_tool.entity.identity.label = I18nObject(en_US="Test Tool") + mock_tool.entity.description = Mock() + mock_tool.entity.description.human = I18nObject(en_US="Test description") + mock_tool.entity.output_schema = {} + mock_tool.get_runtime_parameters.return_value = [] + + # Mock fork_tool_runtime to return the same tool + mock_tool.fork_tool_runtime.return_value = mock_tool + + # Call the method + result = ToolTransformService.convert_tool_entity_to_api_entity(mock_tool, "test_tenant", None) + + # Verify the result + assert isinstance(result, ToolApiEntity) + assert result.parameters is not None + assert len(result.parameters) == 0 + + def test_convert_tool_with_none_parameters(self): + """Test conversion when base parameters is None""" + # Create mock tool with None parameters + mock_tool = Mock(spec=Tool) + mock_tool.entity = Mock() + mock_tool.entity.parameters = None + mock_tool.entity.identity = Mock() + mock_tool.entity.identity.author = "test_author" + mock_tool.entity.identity.name = "test_tool" + mock_tool.entity.identity.label = I18nObject(en_US="Test Tool") + mock_tool.entity.description = Mock() + mock_tool.entity.description.human = I18nObject(en_US="Test description") + mock_tool.entity.output_schema = {} + mock_tool.get_runtime_parameters.return_value = [] + + # Mock fork_tool_runtime to return the same tool + mock_tool.fork_tool_runtime.return_value = mock_tool + + # Call the method + result = ToolTransformService.convert_tool_entity_to_api_entity(mock_tool, "test_tenant", None) + + # Verify the result + assert isinstance(result, ToolApiEntity) + assert result.parameters is not None + assert len(result.parameters) == 0 + + def test_convert_tool_parameter_order_preserved(self): + """Test that parameter order is preserved correctly""" + # Create mock base parameters in specific order + base_param1 = Mock(spec=ToolParameter) + base_param1.name = "param1" + base_param1.form = ToolParameter.ToolParameterForm.FORM + base_param1.type = "string" + base_param1.label = "Base Param 1" + + base_param2 = Mock(spec=ToolParameter) + base_param2.name = "param2" + base_param2.form = ToolParameter.ToolParameterForm.FORM + base_param2.type = "string" + base_param2.label = "Base Param 2" + + base_param3 = Mock(spec=ToolParameter) + base_param3.name = "param3" + base_param3.form = ToolParameter.ToolParameterForm.FORM + base_param3.type = "string" + base_param3.label = "Base Param 3" + + # Create runtime parameter that overrides middle parameter + runtime_param2 = Mock(spec=ToolParameter) + runtime_param2.name = "param2" + runtime_param2.form = ToolParameter.ToolParameterForm.FORM + runtime_param2.type = "string" + runtime_param2.label = "Runtime Param 2" + + # Create new runtime parameter + runtime_param4 = Mock(spec=ToolParameter) + runtime_param4.name = "param4" + runtime_param4.form = ToolParameter.ToolParameterForm.FORM + runtime_param4.type = "string" + runtime_param4.label = "Runtime Param 4" + + # Create mock tool + mock_tool = Mock(spec=Tool) + mock_tool.entity = Mock() + mock_tool.entity.parameters = [base_param1, base_param2, base_param3] + mock_tool.entity.identity = Mock() + mock_tool.entity.identity.author = "test_author" + mock_tool.entity.identity.name = "test_tool" + mock_tool.entity.identity.label = I18nObject(en_US="Test Tool") + mock_tool.entity.description = Mock() + mock_tool.entity.description.human = I18nObject(en_US="Test description") + mock_tool.entity.output_schema = {} + mock_tool.get_runtime_parameters.return_value = [runtime_param2, runtime_param4] + + # Mock fork_tool_runtime to return the same tool + mock_tool.fork_tool_runtime.return_value = mock_tool + + # Call the method + result = ToolTransformService.convert_tool_entity_to_api_entity(mock_tool, "test_tenant", None) + + # Verify the result + assert isinstance(result, ToolApiEntity) + assert result.parameters is not None + assert len(result.parameters) == 4 + + # Check that order is maintained: base parameters first, then new runtime parameters + param_names = [p.name for p in result.parameters] + assert param_names == ["param1", "param2", "param3", "param4"] + + # Verify that param2 was overridden with runtime version + param2 = result.parameters[1] + assert param2.name == "param2" + assert param2.label == "Runtime Param 2" + + +class TestWorkflowProviderToUserProvider: + """Test cases for ToolTransformService.workflow_provider_to_user_provider method""" + + def test_workflow_provider_to_user_provider_with_workflow_app_id(self): + """Test that workflow_provider_to_user_provider correctly sets workflow_app_id.""" + from core.tools.workflow_as_tool.provider import WorkflowToolProviderController + + # Create mock workflow tool provider controller + workflow_app_id = "app_123" + provider_id = "provider_123" + mock_controller = Mock(spec=WorkflowToolProviderController) + mock_controller.provider_id = provider_id + mock_controller.entity = Mock() + mock_controller.entity.identity = Mock() + mock_controller.entity.identity.author = "test_author" + mock_controller.entity.identity.name = "test_workflow_tool" + mock_controller.entity.identity.description = I18nObject(en_US="Test description") + mock_controller.entity.identity.icon = {"type": "emoji", "content": "🔧"} + mock_controller.entity.identity.icon_dark = None + mock_controller.entity.identity.label = I18nObject(en_US="Test Workflow Tool") + + # Call the method + result = ToolTransformService.workflow_provider_to_user_provider( + provider_controller=mock_controller, + labels=["label1", "label2"], + workflow_app_id=workflow_app_id, + ) + + # Verify the result + assert isinstance(result, ToolProviderApiEntity) + assert result.id == provider_id + assert result.author == "test_author" + assert result.name == "test_workflow_tool" + assert result.type == ToolProviderType.WORKFLOW + assert result.workflow_app_id == workflow_app_id + assert result.labels == ["label1", "label2"] + assert result.is_team_authorization is True + assert result.plugin_id is None + assert result.plugin_unique_identifier is None + assert result.tools == [] + + def test_workflow_provider_to_user_provider_without_workflow_app_id(self): + """Test that workflow_provider_to_user_provider works when workflow_app_id is not provided.""" + from core.tools.workflow_as_tool.provider import WorkflowToolProviderController + + # Create mock workflow tool provider controller + provider_id = "provider_123" + mock_controller = Mock(spec=WorkflowToolProviderController) + mock_controller.provider_id = provider_id + mock_controller.entity = Mock() + mock_controller.entity.identity = Mock() + mock_controller.entity.identity.author = "test_author" + mock_controller.entity.identity.name = "test_workflow_tool" + mock_controller.entity.identity.description = I18nObject(en_US="Test description") + mock_controller.entity.identity.icon = {"type": "emoji", "content": "🔧"} + mock_controller.entity.identity.icon_dark = None + mock_controller.entity.identity.label = I18nObject(en_US="Test Workflow Tool") + + # Call the method without workflow_app_id + result = ToolTransformService.workflow_provider_to_user_provider( + provider_controller=mock_controller, + labels=["label1"], + ) + + # Verify the result + assert isinstance(result, ToolProviderApiEntity) + assert result.id == provider_id + assert result.workflow_app_id is None + assert result.labels == ["label1"] + + def test_workflow_provider_to_user_provider_workflow_app_id_none(self): + """Test that workflow_provider_to_user_provider handles None workflow_app_id explicitly.""" + from core.tools.workflow_as_tool.provider import WorkflowToolProviderController + + # Create mock workflow tool provider controller + provider_id = "provider_123" + mock_controller = Mock(spec=WorkflowToolProviderController) + mock_controller.provider_id = provider_id + mock_controller.entity = Mock() + mock_controller.entity.identity = Mock() + mock_controller.entity.identity.author = "test_author" + mock_controller.entity.identity.name = "test_workflow_tool" + mock_controller.entity.identity.description = I18nObject(en_US="Test description") + mock_controller.entity.identity.icon = {"type": "emoji", "content": "🔧"} + mock_controller.entity.identity.icon_dark = None + mock_controller.entity.identity.label = I18nObject(en_US="Test Workflow Tool") + + # Call the method with explicit None values + result = ToolTransformService.workflow_provider_to_user_provider( + provider_controller=mock_controller, + labels=None, + workflow_app_id=None, + ) + + # Verify the result + assert isinstance(result, ToolProviderApiEntity) + assert result.id == provider_id + assert result.workflow_app_id is None + assert result.labels == [] + + def test_workflow_provider_to_user_provider_preserves_other_fields(self): + """Test that workflow_provider_to_user_provider preserves all other entity fields.""" + from core.tools.workflow_as_tool.provider import WorkflowToolProviderController + + # Create mock workflow tool provider controller with various fields + workflow_app_id = "app_456" + provider_id = "provider_456" + mock_controller = Mock(spec=WorkflowToolProviderController) + mock_controller.provider_id = provider_id + mock_controller.entity = Mock() + mock_controller.entity.identity = Mock() + mock_controller.entity.identity.author = "another_author" + mock_controller.entity.identity.name = "another_workflow_tool" + mock_controller.entity.identity.description = I18nObject( + en_US="Another description", zh_Hans="Another description" + ) + mock_controller.entity.identity.icon = {"type": "emoji", "content": "⚙️"} + mock_controller.entity.identity.icon_dark = {"type": "emoji", "content": "🔧"} + mock_controller.entity.identity.label = I18nObject( + en_US="Another Workflow Tool", zh_Hans="Another Workflow Tool" + ) + + # Call the method + result = ToolTransformService.workflow_provider_to_user_provider( + provider_controller=mock_controller, + labels=["automation", "workflow"], + workflow_app_id=workflow_app_id, + ) + + # Verify all fields are preserved correctly + assert isinstance(result, ToolProviderApiEntity) + assert result.id == provider_id + assert result.author == "another_author" + assert result.name == "another_workflow_tool" + assert result.description.en_US == "Another description" + assert result.description.zh_Hans == "Another description" + assert result.icon == {"type": "emoji", "content": "⚙️"} + assert result.icon_dark == {"type": "emoji", "content": "🔧"} + assert result.label.en_US == "Another Workflow Tool" + assert result.label.zh_Hans == "Another Workflow Tool" + assert result.type == ToolProviderType.WORKFLOW + assert result.workflow_app_id == workflow_app_id + assert result.labels == ["automation", "workflow"] + assert result.masked_credentials == {} + assert result.is_team_authorization is True + assert result.allow_delete is True + assert result.plugin_id is None + assert result.plugin_unique_identifier is None + assert result.tools == [] + + +class TestGetToolProviderIconUrl: + def test_builtin_provider_returns_console_url(self): + with patch(f"{MODULE}.dify_config") as cfg: + cfg.CONSOLE_API_URL = "https://app.dify.ai" + url = ToolTransformService.get_tool_provider_icon_url("builtin", "google", "icon.png") + + assert "/builtin/google/icon" in url + assert url.startswith("https://app.dify.ai/console/api/workspaces/current/tool-provider") + + def test_builtin_provider_with_no_console_url(self): + with patch(f"{MODULE}.dify_config") as cfg: + cfg.CONSOLE_API_URL = None + url = ToolTransformService.get_tool_provider_icon_url("builtin", "slack", "icon.png") + + assert "/builtin/slack/icon" in url + + def test_api_provider_parses_json_icon(self): + icon_json = '{"background": "#fff", "content": "A"}' + result = ToolTransformService.get_tool_provider_icon_url("api", "my-api", icon_json) + assert result == {"background": "#fff", "content": "A"} + + def test_api_provider_returns_dict_icon_directly(self): + icon = {"background": "#000", "content": "B"} + result = ToolTransformService.get_tool_provider_icon_url("api", "my-api", icon) + assert result == icon + + def test_api_provider_returns_fallback_on_invalid_json(self): + result = ToolTransformService.get_tool_provider_icon_url("api", "my-api", "not-json") + assert result == {"background": "#252525", "content": "\ud83d\ude01"} + + def test_workflow_provider_behaves_like_api(self): + icon = {"background": "#123", "content": "W"} + assert ToolTransformService.get_tool_provider_icon_url("workflow", "wf", icon) == icon + + def test_mcp_returns_icon_as_is(self): + assert ToolTransformService.get_tool_provider_icon_url("mcp", "srv", "icon-value") == "icon-value" + + def test_unknown_type_returns_empty(self): + assert ToolTransformService.get_tool_provider_icon_url("unknown", "x", "i") == "" + + +class TestRepackProvider: + def test_repacks_dict_provider_icon(self): + provider = {"type": "builtin", "name": "google", "icon": "old"} + with patch.object(ToolTransformService, "get_tool_provider_icon_url", return_value="/new-url") as mock_fn: + ToolTransformService.repack_provider("t1", provider) + + assert provider["icon"] == "/new-url" + mock_fn.assert_called_once_with(provider_type="builtin", provider_name="google", icon="old") + + def test_repacks_tool_provider_api_entity_without_plugin(self): + entity = MagicMock(spec=ToolProviderApiEntity) + entity.plugin_id = None + entity.type = ToolProviderType.BUILT_IN + entity.name = "slack" + entity.icon = "icon.svg" + entity.icon_dark = "dark.svg" + + with patch.object(ToolTransformService, "get_tool_provider_icon_url", return_value="/url"): + ToolTransformService.repack_provider("t1", entity) + + assert entity.icon == "/url" + assert entity.icon_dark == "/url" + + +class TestConvertMcpSchemaToParameter: + def test_simple_object_schema(self): + schema = { + "type": "object", + "properties": { + "query": {"type": "string", "description": "Search query"}, + "count": {"type": "integer", "description": "Result count"}, + }, + "required": ["query"], + } + + params = ToolTransformService.convert_mcp_schema_to_parameter(schema) + + assert len(params) == 2 + query_param = next(p for p in params if p.name == "query") + count_param = next(p for p in params if p.name == "count") + assert query_param.required is True + assert count_param.required is False + assert count_param.type.value == "number" + + def test_float_maps_to_number(self): + schema = {"type": "object", "properties": {"rate": {"type": "float"}}, "required": []} + assert ToolTransformService.convert_mcp_schema_to_parameter(schema)[0].type.value == "number" + + def test_array_type_attaches_input_schema(self): + prop = {"type": "array", "description": "Items", "items": {"type": "string"}} + schema = {"type": "object", "properties": {"items": prop}, "required": []} + param = ToolTransformService.convert_mcp_schema_to_parameter(schema)[0] + assert param.input_schema is not None + + def test_non_object_schema_returns_empty(self): + assert ToolTransformService.convert_mcp_schema_to_parameter({"type": "string"}) == [] + + def test_missing_properties_returns_empty(self): + assert ToolTransformService.convert_mcp_schema_to_parameter({"type": "object"}) == [] + + def test_list_type_uses_first_element(self): + schema = {"type": "object", "properties": {"f": {"type": ["string", "null"]}}, "required": []} + assert ToolTransformService.convert_mcp_schema_to_parameter(schema)[0].type.value == "string" + + def test_missing_description_defaults_empty(self): + schema = {"type": "object", "properties": {"f": {"type": "string"}}, "required": []} + assert ToolTransformService.convert_mcp_schema_to_parameter(schema)[0].llm_description == "" + + +class TestApiProviderToController: + def test_api_key_header_auth(self): + db_provider = MagicMock() + db_provider.credentials = {"auth_type": "api_key_header"} + with patch(f"{MODULE}.ApiToolProviderController") as ctrl_cls: + ctrl_cls.from_db.return_value = MagicMock() + ToolTransformService.api_provider_to_controller(db_provider) + ctrl_cls.from_db.assert_called_once_with(db_provider=db_provider, auth_type=ApiProviderAuthType.API_KEY_HEADER) + + def test_api_key_query_auth(self): + db_provider = MagicMock() + db_provider.credentials = {"auth_type": "api_key_query"} + with patch(f"{MODULE}.ApiToolProviderController") as ctrl_cls: + ctrl_cls.from_db.return_value = MagicMock() + ToolTransformService.api_provider_to_controller(db_provider) + ctrl_cls.from_db.assert_called_once_with(db_provider=db_provider, auth_type=ApiProviderAuthType.API_KEY_QUERY) + + def test_legacy_api_key_maps_to_header(self): + db_provider = MagicMock() + db_provider.credentials = {"auth_type": "api_key"} + with patch(f"{MODULE}.ApiToolProviderController") as ctrl_cls: + ctrl_cls.from_db.return_value = MagicMock() + ToolTransformService.api_provider_to_controller(db_provider) + ctrl_cls.from_db.assert_called_once_with(db_provider=db_provider, auth_type=ApiProviderAuthType.API_KEY_HEADER) + + def test_unknown_auth_defaults_to_none(self): + db_provider = MagicMock() + db_provider.credentials = {"auth_type": "something_else"} + with patch(f"{MODULE}.ApiToolProviderController") as ctrl_cls: + ctrl_cls.from_db.return_value = MagicMock() + ToolTransformService.api_provider_to_controller(db_provider) + ctrl_cls.from_db.assert_called_once_with(db_provider=db_provider, auth_type=ApiProviderAuthType.NONE) diff --git a/api/uv.lock b/api/uv.lock index c4cf31e3f5..39c362eda0 100644 --- a/api/uv.lock +++ b/api/uv.lock @@ -1700,30 +1700,30 @@ requires-dist = [ { name = "httpx-sse", specifier = "~=0.4.0" }, { name = "jieba", specifier = "==0.42.1" }, { name = "json-repair", specifier = ">=0.55.1" }, - { name = "langfuse", specifier = "~=2.51.3" }, + { name = "langfuse", specifier = ">=3.0.0,<5.0.0" }, { name = "langsmith", specifier = "~=0.7.16" }, { name = "litellm", specifier = "==1.82.6" }, { name = "markdown", specifier = "~=3.10.2" }, { name = "mlflow-skinny", specifier = ">=3.0.0" }, { name = "numpy", specifier = "~=1.26.4" }, { name = "openpyxl", specifier = "~=3.1.5" }, - { name = "opentelemetry-api", specifier = "==1.28.0" }, - { name = "opentelemetry-distro", specifier = "==0.49b0" }, - { name = "opentelemetry-exporter-otlp", specifier = "==1.28.0" }, - { name = "opentelemetry-exporter-otlp-proto-common", specifier = "==1.28.0" }, - { name = "opentelemetry-exporter-otlp-proto-grpc", specifier = "==1.28.0" }, - { name = "opentelemetry-exporter-otlp-proto-http", specifier = "==1.28.0" }, - { name = "opentelemetry-instrumentation", specifier = "==0.49b0" }, - { name = "opentelemetry-instrumentation-celery", specifier = "==0.49b0" }, - { name = "opentelemetry-instrumentation-flask", specifier = "==0.49b0" }, - { name = "opentelemetry-instrumentation-httpx", specifier = "==0.49b0" }, - { name = "opentelemetry-instrumentation-redis", specifier = "==0.49b0" }, - { name = "opentelemetry-instrumentation-sqlalchemy", specifier = "==0.49b0" }, + { name = "opentelemetry-api", specifier = "==1.40.0" }, + { name = "opentelemetry-distro", specifier = "==0.61b0" }, + { name = "opentelemetry-exporter-otlp", specifier = "==1.40.0" }, + { name = "opentelemetry-exporter-otlp-proto-common", specifier = "==1.40.0" }, + { name = "opentelemetry-exporter-otlp-proto-grpc", specifier = "==1.40.0" }, + { name = "opentelemetry-exporter-otlp-proto-http", specifier = "==1.40.0" }, + { name = "opentelemetry-instrumentation", specifier = "==0.61b0" }, + { name = "opentelemetry-instrumentation-celery", specifier = "==0.61b0" }, + { name = "opentelemetry-instrumentation-flask", specifier = "==0.61b0" }, + { name = "opentelemetry-instrumentation-httpx", specifier = "==0.61b0" }, + { name = "opentelemetry-instrumentation-redis", specifier = "==0.61b0" }, + { name = "opentelemetry-instrumentation-sqlalchemy", specifier = "==0.61b0" }, { name = "opentelemetry-propagator-b3", specifier = "==1.40.0" }, - { name = "opentelemetry-proto", specifier = "==1.28.0" }, - { name = "opentelemetry-sdk", specifier = "==1.28.0" }, - { name = "opentelemetry-semantic-conventions", specifier = "==0.49b0" }, - { name = "opentelemetry-util-http", specifier = "==0.49b0" }, + { name = "opentelemetry-proto", specifier = "==1.40.0" }, + { name = "opentelemetry-sdk", specifier = "==1.40.0" }, + { name = "opentelemetry-semantic-conventions", specifier = "==0.61b0" }, + { name = "opentelemetry-util-http", specifier = "==0.61b0" }, { name = "opik", specifier = "~=1.10.37" }, { name = "packaging", specifier = "~=23.2" }, { name = "pandas", extras = ["excel", "output-formatting", "performance"], specifier = "~=3.0.1" }, @@ -3393,20 +3393,22 @@ sdist = { url = "https://files.pythonhosted.org/packages/0e/72/a3add0e4eec4eb9e2 [[package]] name = "langfuse" -version = "2.51.5" +version = "4.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio" }, { name = "backoff" }, { name = "httpx" }, - { name = "idna" }, + { name = "openai" }, + { name = "opentelemetry-api" }, + { name = "opentelemetry-exporter-otlp-proto-http" }, + { name = "opentelemetry-sdk" }, { name = "packaging" }, { name = "pydantic" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/e9/22c9c05d877ab85da6d9008aaa7360f2a9ad58787a8e36e00b1b5be9a990/langfuse-2.51.5.tar.gz", hash = "sha256:55bc37b5c5d3ae133c1a95db09117cfb3117add110ba02ebbf2ce45ac4395c5b", size = 117574, upload-time = "2024-10-09T00:59:15.016Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/94/ab00e21fa5977d6b9c68fb3a95de2aa1a1e586964ff2af3e37405bf65d9f/langfuse-4.0.1.tar.gz", hash = "sha256:40a6daf3ab505945c314246d5b577d48fcfde0a47e8c05267ea6bd494ae9608e", size = 272749, upload-time = "2026-03-19T14:03:34.508Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/f7/242a13ca094c78464b7d4df77dfe7d4c44ed77b15fed3d2e3486afa5d2e1/langfuse-2.51.5-py3-none-any.whl", hash = "sha256:b95401ca710ef94b521afa6541933b6f93d7cfd4a97523c8fc75bca4d6d219fb", size = 214281, upload-time = "2024-10-09T00:59:12.596Z" }, + { url = "https://files.pythonhosted.org/packages/27/8f/3145ef00940f9c29d7e0200fd040f35616eac21c6ab4610a1ba14f3a04c1/langfuse-4.0.1-py3-none-any.whl", hash = "sha256:e22f49ea31304f97fc31a97c014ba63baa8802d9568295d54f06b00b43c30524", size = 465049, upload-time = "2026-03-19T14:03:32.527Z" }, ] [[package]] @@ -4200,95 +4202,95 @@ wheels = [ [[package]] name = "opentelemetry-api" -version = "1.28.0" +version = "1.40.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "deprecated" }, { name = "importlib-metadata" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/79/36/260eaea0f74fdd0c0d8f22ed3a3031109ea1c85531f94f4fde266c29e29a/opentelemetry_api-1.28.0.tar.gz", hash = "sha256:578610bcb8aa5cdcb11169d136cc752958548fb6ccffb0969c1036b0ee9e5353", size = 62803, upload-time = "2024-11-05T19:14:45.497Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/1d/4049a9e8698361cc1a1aa03a6c59e4fa4c71e0c0f94a30f988a6876a2ae6/opentelemetry_api-1.40.0.tar.gz", hash = "sha256:159be641c0b04d11e9ecd576906462773eb97ae1b657730f0ecf64d32071569f", size = 70851, upload-time = "2026-03-04T14:17:21.555Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/e4/3b25d8b856791c04d8a62b1257b5fc09dc41a057800db06885af8ddcdce1/opentelemetry_api-1.28.0-py3-none-any.whl", hash = "sha256:8457cd2c59ea1bd0988560f021656cecd254ad7ef6be4ba09dbefeca2409ce52", size = 64314, upload-time = "2024-11-05T19:14:21.659Z" }, + { url = "https://files.pythonhosted.org/packages/5f/bf/93795954016c522008da367da292adceed71cca6ee1717e1d64c83089099/opentelemetry_api-1.40.0-py3-none-any.whl", hash = "sha256:82dd69331ae74b06f6a874704be0cfaa49a1650e1537d4a813b86ecef7d0ecf9", size = 68676, upload-time = "2026-03-04T14:17:01.24Z" }, ] [[package]] name = "opentelemetry-distro" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, { name = "opentelemetry-instrumentation" }, { name = "opentelemetry-sdk" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4d/75/7cb7c33899e66bb366d40a889111a78c22df0951038b6699f1663e715a9f/opentelemetry_distro-0.49b0.tar.gz", hash = "sha256:1bafa274f9e83baa0d2a5d47ed02caffcf9bcca60107b389b145400d82b07513", size = 2560, upload-time = "2024-11-05T19:21:39.379Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/00/1f8acc51326956a596fefaf67751380001af36029132a7a07d4debce3c06/opentelemetry_distro-0.61b0.tar.gz", hash = "sha256:975b845f50181ad53753becf4fd4b123b54fa04df5a9d78812264436d6518981", size = 2590, upload-time = "2026-03-04T14:20:12.453Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/db/806172b6a4933966eee518db814b375e620602f7fe776b74ef795690f135/opentelemetry_distro-0.49b0-py3-none-any.whl", hash = "sha256:1af4074702f605ea210753dd41947dc2fd61b39724f23cdcf15d5654867cd3c2", size = 3318, upload-time = "2024-11-05T19:20:34.065Z" }, + { url = "https://files.pythonhosted.org/packages/56/2c/efcc995cd7484e6e55b1d26bd7fa6c55ca96bd415ff94310b52c19f330b0/opentelemetry_distro-0.61b0-py3-none-any.whl", hash = "sha256:f21d1ac0627549795d75e332006dd068877f00e461b1b2e8fe4568d6eb7b9590", size = 3349, upload-time = "2026-03-04T14:18:57.788Z" }, ] [[package]] name = "opentelemetry-exporter-otlp" -version = "1.28.0" +version = "1.40.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-exporter-otlp-proto-grpc" }, { name = "opentelemetry-exporter-otlp-proto-http" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/eb/16/14e3fc163930ea68f0980a4cdd4ae5796e60aeb898965990e13263d64baf/opentelemetry_exporter_otlp-1.28.0.tar.gz", hash = "sha256:31ae7495831681dd3da34ac457f6970f147465ae4b9aae3a888d7a581c7cd868", size = 6170, upload-time = "2024-11-05T19:14:47.349Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/37/b6708e0eff5c5fb9aba2e0ea09f7f3bcbfd12a592d2a780241b5f6014df7/opentelemetry_exporter_otlp-1.40.0.tar.gz", hash = "sha256:7caa0870b95e2fcb59d64e16e2b639ecffb07771b6cd0000b5d12e5e4fef765a", size = 6152, upload-time = "2026-03-04T14:17:23.235Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/82/3f521b3c1f2a411ed60a24a8c9f486c1beeaf8c6c55337c87d3ae1642151/opentelemetry_exporter_otlp-1.28.0-py3-none-any.whl", hash = "sha256:1fd02d70f2c1b7ac5579c81e78de4594b188d3317c8ceb69e8b53900fb7b40fd", size = 7024, upload-time = "2024-11-05T19:14:24.534Z" }, + { url = "https://files.pythonhosted.org/packages/2d/fc/aea77c28d9f3ffef2fdafdc3f4a235aee4091d262ddabd25882f47ce5c5f/opentelemetry_exporter_otlp-1.40.0-py3-none-any.whl", hash = "sha256:48c87e539ec9afb30dc443775a1334cc5487de2f72a770a4c00b1610bf6c697d", size = 7023, upload-time = "2026-03-04T14:17:03.612Z" }, ] [[package]] name = "opentelemetry-exporter-otlp-proto-common" -version = "1.28.0" +version = "1.40.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-proto" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/8d/5d411084ac441052f4c9bae03a1aec65ae5d16b439fea7b9c5ac3842c013/opentelemetry_exporter_otlp_proto_common-1.28.0.tar.gz", hash = "sha256:5fa0419b0c8e291180b0fc8430a20dd44a3f3236f8e0827992145914f273ec4f", size = 18505, upload-time = "2024-11-05T19:14:48.204Z" } +sdist = { url = "https://files.pythonhosted.org/packages/51/bc/1559d46557fe6eca0b46c88d4c2676285f1f3be2e8d06bb5d15fbffc814a/opentelemetry_exporter_otlp_proto_common-1.40.0.tar.gz", hash = "sha256:1cbee86a4064790b362a86601ee7934f368b81cd4cc2f2e163902a6e7818a0fa", size = 20416, upload-time = "2026-03-04T14:17:23.801Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/72/3c44aabc74db325aaba09361b6a0d80f6d601f0ff86ecea8ee655c9538fc/opentelemetry_exporter_otlp_proto_common-1.28.0-py3-none-any.whl", hash = "sha256:467e6437d24e020156dffecece8c0a4471a8a60f6a34afeda7386df31a092410", size = 18403, upload-time = "2024-11-05T19:14:25.798Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ca/8f122055c97a932311a3f640273f084e738008933503d0c2563cd5d591fc/opentelemetry_exporter_otlp_proto_common-1.40.0-py3-none-any.whl", hash = "sha256:7081ff453835a82417bf38dccf122c827c3cbc94f2079b03bba02a3165f25149", size = 18369, upload-time = "2026-03-04T14:17:04.796Z" }, ] [[package]] name = "opentelemetry-exporter-otlp-proto-grpc" -version = "1.28.0" +version = "1.40.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "deprecated" }, { name = "googleapis-common-protos" }, { name = "grpcio" }, { name = "opentelemetry-api" }, { name = "opentelemetry-exporter-otlp-proto-common" }, { name = "opentelemetry-proto" }, { name = "opentelemetry-sdk" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/43/4d/f215162e58041afb4bdf5dbd0d8faf0b7fc9bf7b3d3fc0e44e06f9e7e869/opentelemetry_exporter_otlp_proto_grpc-1.28.0.tar.gz", hash = "sha256:47a11c19dc7f4289e220108e113b7de90d59791cb4c37fc29f69a6a56f2c3735", size = 26237, upload-time = "2024-11-05T19:14:49.026Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8f/7f/b9e60435cfcc7590fa87436edad6822240dddbc184643a2a005301cc31f4/opentelemetry_exporter_otlp_proto_grpc-1.40.0.tar.gz", hash = "sha256:bd4015183e40b635b3dab8da528b27161ba83bf4ef545776b196f0fb4ec47740", size = 25759, upload-time = "2026-03-04T14:17:24.4Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/b5/afabc8106abc0f9cfeecf5b3e682622b3e04bba1d9b967dbfcd91b9c4ebe/opentelemetry_exporter_otlp_proto_grpc-1.28.0-py3-none-any.whl", hash = "sha256:edbdc53e7783f88d4535db5807cb91bd7b1ec9e9b9cdbfee14cd378f29a3b328", size = 18532, upload-time = "2024-11-05T19:14:26.853Z" }, + { url = "https://files.pythonhosted.org/packages/96/6f/7ee0980afcbdcd2d40362da16f7f9796bd083bf7f0b8e038abfbc0300f5d/opentelemetry_exporter_otlp_proto_grpc-1.40.0-py3-none-any.whl", hash = "sha256:2aa0ca53483fe0cf6405087a7491472b70335bc5c7944378a0a8e72e86995c52", size = 20304, upload-time = "2026-03-04T14:17:05.942Z" }, ] [[package]] name = "opentelemetry-exporter-otlp-proto-http" -version = "1.28.0" +version = "1.40.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "deprecated" }, { name = "googleapis-common-protos" }, { name = "opentelemetry-api" }, { name = "opentelemetry-exporter-otlp-proto-common" }, { name = "opentelemetry-proto" }, { name = "opentelemetry-sdk" }, { name = "requests" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f1/2a/555f2845928086cd51aa6941c7a546470805b68ed631ec139ce7d841763d/opentelemetry_exporter_otlp_proto_http-1.28.0.tar.gz", hash = "sha256:d83a9a03a8367ead577f02a64127d827c79567de91560029688dd5cfd0152a8e", size = 15051, upload-time = "2024-11-05T19:14:49.813Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/fa/73d50e2c15c56be4d000c98e24221d494674b0cc95524e2a8cb3856d95a4/opentelemetry_exporter_otlp_proto_http-1.40.0.tar.gz", hash = "sha256:db48f5e0f33217588bbc00274a31517ba830da576e59503507c839b38fa0869c", size = 17772, upload-time = "2026-03-04T14:17:25.324Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/ce/80d5adabbf7ab4a0ca7b5e0f4039b24d273be370c3ba85fc05b13794411c/opentelemetry_exporter_otlp_proto_http-1.28.0-py3-none-any.whl", hash = "sha256:e8f3f7961b747edb6b44d51de4901a61e9c01d50debd747b120a08c4996c7e7b", size = 17228, upload-time = "2024-11-05T19:14:28.613Z" }, + { url = "https://files.pythonhosted.org/packages/a0/3a/8865d6754e61c9fb170cdd530a124a53769ee5f740236064816eb0ca7301/opentelemetry_exporter_otlp_proto_http-1.40.0-py3-none-any.whl", hash = "sha256:a8d1dab28f504c5d96577d6509f80a8150e44e8f45f82cdbe0e34c99ab040069", size = 19960, upload-time = "2026-03-04T14:17:07.153Z" }, ] [[package]] name = "opentelemetry-instrumentation" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, @@ -4296,14 +4298,14 @@ dependencies = [ { name = "packaging" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/de/6b/6c25b15063c92a011cf3f68375971e2c58a9c764690847edc97df2d94eeb/opentelemetry_instrumentation-0.49b0.tar.gz", hash = "sha256:398a93e0b9dc2d11cc8627e1761665c506fe08c6b2df252a2ab3ade53d751c46", size = 26478, upload-time = "2024-11-05T19:21:41.402Z" } +sdist = { url = "https://files.pythonhosted.org/packages/da/37/6bf8e66bfcee5d3c6515b79cb2ee9ad05fe573c20f7ceb288d0e7eeec28c/opentelemetry_instrumentation-0.61b0.tar.gz", hash = "sha256:cb21b48db738c9de196eba6b805b4ff9de3b7f187e4bbf9a466fa170514f1fc7", size = 32606, upload-time = "2026-03-04T14:20:16.825Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/93/61/e0d21e958d6072ce25c4f5e26a1d22835fc86f80836660adf6badb6038ce/opentelemetry_instrumentation-0.49b0-py3-none-any.whl", hash = "sha256:68364d73a1ff40894574cbc6138c5f98674790cae1f3b0865e21cf702f24dcb3", size = 30694, upload-time = "2024-11-05T19:20:38.584Z" }, + { url = "https://files.pythonhosted.org/packages/d8/3e/f6f10f178b6316de67f0dfdbbb699a24fbe8917cf1743c1595fb9dcdd461/opentelemetry_instrumentation-0.61b0-py3-none-any.whl", hash = "sha256:92a93a280e69788e8f88391247cc530fd81f16f2b011979d4d6398f805cfbc63", size = 33448, upload-time = "2026-03-04T14:19:02.447Z" }, ] [[package]] name = "opentelemetry-instrumentation-asgi" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "asgiref" }, @@ -4312,28 +4314,28 @@ dependencies = [ { name = "opentelemetry-semantic-conventions" }, { name = "opentelemetry-util-http" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e8/55/693c3d0938ba5fead5c3aa4ac7022a992b4ff99a8e9979800d0feb843ff4/opentelemetry_instrumentation_asgi-0.49b0.tar.gz", hash = "sha256:959fd9b1345c92f20c6ef1d42f92ef6a76b3c3083fbc4104d59da6859b15b083", size = 24117, upload-time = "2024-11-05T19:21:46.769Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/3e/143cf5c034e58037307e6a24f06e0dd64b2c49ae60a965fc580027581931/opentelemetry_instrumentation_asgi-0.61b0.tar.gz", hash = "sha256:9d08e127244361dc33976d39dd4ca8f128b5aa5a7ae425208400a80a095019b5", size = 26691, upload-time = "2026-03-04T14:20:21.038Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/0b/7900c782a1dfaa584588d724bc3bbdf8405a32497537dd96b3fcbf8461b9/opentelemetry_instrumentation_asgi-0.49b0-py3-none-any.whl", hash = "sha256:722a90856457c81956c88f35a6db606cc7db3231046b708aae2ddde065723dbe", size = 16326, upload-time = "2024-11-05T19:20:46.176Z" }, + { url = "https://files.pythonhosted.org/packages/19/78/154470cf9d741a7487fbb5067357b87386475bbb77948a6707cae982e158/opentelemetry_instrumentation_asgi-0.61b0-py3-none-any.whl", hash = "sha256:e4b3ce6b66074e525e717efff20745434e5efd5d9df6557710856fba356da7a4", size = 16980, upload-time = "2026-03-04T14:19:10.894Z" }, ] [[package]] name = "opentelemetry-instrumentation-celery" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, { name = "opentelemetry-instrumentation" }, { name = "opentelemetry-semantic-conventions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4c/8b/9b8a9dda3ed53354c6f707a45cdb7a4730e1c109b50fc1b413525493f811/opentelemetry_instrumentation_celery-0.49b0.tar.gz", hash = "sha256:afbaee97cc9c75f29bcc9784f16f8e37c415d4fe9b334748c5b90a3d30d12473", size = 14702, upload-time = "2024-11-05T19:21:53.672Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8d/43/e79108a804d16b1dc8ff28edd0e94ac393cf6359a5adcd7cdd2ec4be85f4/opentelemetry_instrumentation_celery-0.61b0.tar.gz", hash = "sha256:0e352a567dc89ed8bc083fc635035ce3c5b96bbbd92831ffd676e93b87f8e94f", size = 14780, upload-time = "2026-03-04T14:20:27.776Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/21/8c/d7d4adb36abbc0e517a69f7a069f32742122ae22d6017202f64570d9f4c5/opentelemetry_instrumentation_celery-0.49b0-py3-none-any.whl", hash = "sha256:38d4a78c78f33020032ef77ef0ead756bdf7838bcfb603de10f5925d39f14929", size = 13749, upload-time = "2024-11-05T19:20:54.98Z" }, + { url = "https://files.pythonhosted.org/packages/a2/ed/c05f3c84b455654eb6c047474ffde61ed92efc24030f64213c98bca9d44b/opentelemetry_instrumentation_celery-0.61b0-py3-none-any.whl", hash = "sha256:01235733ff0cdf571cb03b270645abb14b9c8d830313dc5842097ec90146320b", size = 13856, upload-time = "2026-03-04T14:19:20.98Z" }, ] [[package]] name = "opentelemetry-instrumentation-fastapi" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, @@ -4342,14 +4344,14 @@ dependencies = [ { name = "opentelemetry-semantic-conventions" }, { name = "opentelemetry-util-http" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/bf/8e6d2a4807360f2203192017eb4845f5628dbeaf0597adf3d141cc5c24e1/opentelemetry_instrumentation_fastapi-0.49b0.tar.gz", hash = "sha256:6d14935c41fd3e49328188b6a59dd4c37bd17a66b01c15b0c64afa9714a1f905", size = 19230, upload-time = "2024-11-05T19:21:59.361Z" } +sdist = { url = "https://files.pythonhosted.org/packages/37/35/aa727bb6e6ef930dcdc96a617b83748fece57b43c47d83ba8d83fbeca657/opentelemetry_instrumentation_fastapi-0.61b0.tar.gz", hash = "sha256:3a24f35b07c557ae1bbc483bf8412221f25d79a405f8b047de8b670722e2fa9f", size = 24800, upload-time = "2026-03-04T14:20:32.759Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/f4/0895b9410c10abf987c90dee1b7688a8f2214a284fe15e575648f6a1473a/opentelemetry_instrumentation_fastapi-0.49b0-py3-none-any.whl", hash = "sha256:646e1b18523cbe6860ae9711eb2c7b9c85466c3c7697cd6b8fb5180d85d3fe6e", size = 12101, upload-time = "2024-11-05T19:21:01.805Z" }, + { url = "https://files.pythonhosted.org/packages/91/05/acfeb2cccd434242a0a7d0ea29afaf077e04b42b35b485d89aee4e0d9340/opentelemetry_instrumentation_fastapi-0.61b0-py3-none-any.whl", hash = "sha256:a1a844d846540d687d377516b2ff698b51d87c781b59f47c214359c4a241047c", size = 13485, upload-time = "2026-03-04T14:19:30.351Z" }, ] [[package]] name = "opentelemetry-instrumentation-flask" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, @@ -4359,14 +4361,14 @@ dependencies = [ { name = "opentelemetry-util-http" }, { name = "packaging" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/12/dc72873fb1e35699941d8eb6a53ef25e8c5843dea37665dad33bd720f047/opentelemetry_instrumentation_flask-0.49b0.tar.gz", hash = "sha256:f7c5ab67753c4781a2e21c8f43dc5fc02ece74fdd819466c75d025db80aa7576", size = 19176, upload-time = "2024-11-05T19:22:00.816Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d9/33/d6852d8f2c3eef86f2f8c858d6f5315983c7063e07e595519e96d4c31c06/opentelemetry_instrumentation_flask-0.61b0.tar.gz", hash = "sha256:e9faf58dfd9860a1868442d180142645abdafc1a652dd73d469a5efd106a7d49", size = 24071, upload-time = "2026-03-04T14:20:33.437Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/fc/354da8f33ef0daebfc8e4eac995d342ae13a35097bbad512cfe0d2f3c61a/opentelemetry_instrumentation_flask-0.49b0-py3-none-any.whl", hash = "sha256:f3ef330c3cee3e2c161f27f1e7017c8800b9bfb6f9204f2f7bfb0b274874be0e", size = 14582, upload-time = "2024-11-05T19:21:02.793Z" }, + { url = "https://files.pythonhosted.org/packages/3e/41/619f3530324a58491f2d20f216a10dd7393629b29db4610dda642a27f4ed/opentelemetry_instrumentation_flask-0.61b0-py3-none-any.whl", hash = "sha256:e8ce474d7ce543bfbbb3e93f8a6f8263348af9d7b45502f387420cf3afa71253", size = 15996, upload-time = "2026-03-04T14:19:31.304Z" }, ] [[package]] name = "opentelemetry-instrumentation-httpx" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, @@ -4375,14 +4377,14 @@ dependencies = [ { name = "opentelemetry-util-http" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a0/53/8b5e05e55a513d846ead5afb0509bec37a34a1c3e82f30b13d14156334b1/opentelemetry_instrumentation_httpx-0.49b0.tar.gz", hash = "sha256:07165b624f3e58638cee47ecf1c81939a8c2beb7e42ce9f69e25a9f21dc3f4cf", size = 17750, upload-time = "2024-11-05T19:22:02.911Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/2a/e2becd55e33c29d1d9ef76e2579040ed1951cb33bacba259f6aff2fdd2a6/opentelemetry_instrumentation_httpx-0.61b0.tar.gz", hash = "sha256:6569ec097946c5551c2a4252f74c98666addd1bf047c1dde6b4ef426719ff8dd", size = 24104, upload-time = "2026-03-04T14:20:34.752Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/9f/843391c6d645cd4f6914b27bc807fc1ff52b97f84cbe3ca675641976b23f/opentelemetry_instrumentation_httpx-0.49b0-py3-none-any.whl", hash = "sha256:e59e0d2fda5ef841630c68da1d78ff9192f63590a9099f12f0eab614abdf239a", size = 14110, upload-time = "2024-11-05T19:21:04.698Z" }, + { url = "https://files.pythonhosted.org/packages/af/88/dde310dce56e2d85cf1a09507f5888544955309edc4b8d22971d6d3d1417/opentelemetry_instrumentation_httpx-0.61b0-py3-none-any.whl", hash = "sha256:dee05c93a6593a5dc3ae5d9d5c01df8b4e2c5d02e49275e5558534ee46343d5e", size = 17198, upload-time = "2026-03-04T14:19:33.585Z" }, ] [[package]] name = "opentelemetry-instrumentation-redis" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, @@ -4390,14 +4392,14 @@ dependencies = [ { name = "opentelemetry-semantic-conventions" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/19/5b/1398eb2f92fd76787ccec28d24dc4c7dfaaf97a7557e7729e2f7c2c05d84/opentelemetry_instrumentation_redis-0.49b0.tar.gz", hash = "sha256:922542c3bd192ad4ba74e2c7e0a253c7c58a5cefbd6f89da2aba4d193a974703", size = 11353, upload-time = "2024-11-05T19:22:12.822Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/21/26205f89358a5f2be3ee5512d3d3bce16b622977f64aeaa9d3fa8887dd39/opentelemetry_instrumentation_redis-0.61b0.tar.gz", hash = "sha256:ae0fbb56be9a641e621d55b02a7d62977a2c77c5ee760addd79b9b266e46e523", size = 14781, upload-time = "2026-03-04T14:20:45.694Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/24/e4/4f258fef0759629f2e8a0210d5533cfef3ecad69ff35be044637a3e2783e/opentelemetry_instrumentation_redis-0.49b0-py3-none-any.whl", hash = "sha256:b7d8f758bac53e77b7e7ca98ce80f91230577502dacb619ebe8e8b6058042067", size = 12453, upload-time = "2024-11-05T19:21:18.534Z" }, + { url = "https://files.pythonhosted.org/packages/a5/e1/8f4c8e4194291dbe828aeabe779050a8497b379ad90040a5a0a7074b1d08/opentelemetry_instrumentation_redis-0.61b0-py3-none-any.whl", hash = "sha256:8d4e850bbb5f8eeafa44c0eac3a007990c7125de187bc9c3659e29ff7e091172", size = 15506, upload-time = "2026-03-04T14:19:48.588Z" }, ] [[package]] name = "opentelemetry-instrumentation-sqlalchemy" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, @@ -4406,14 +4408,14 @@ dependencies = [ { name = "packaging" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a0/a7/24f6cce3808ae1802dd1b60d752fbab877db5655198929cf4ee8ea416923/opentelemetry_instrumentation_sqlalchemy-0.49b0.tar.gz", hash = "sha256:32658e520fc8b35823c722f5d8831d3a410b76dd2724adb2887befc041ddef04", size = 13194, upload-time = "2024-11-05T19:22:14.92Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/4f/3a325b180944610697a0a926d49d782b41a86120050d44fefb2715b630ac/opentelemetry_instrumentation_sqlalchemy-0.61b0.tar.gz", hash = "sha256:13a3a159a2043a52f0180b3757fbaa26741b0e08abb50deddce4394c118956e6", size = 15343, upload-time = "2026-03-04T14:20:47.648Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/6b/a1a3685fed593282999cdc374ece15efbd56f8d774bd368bf7ff2cf5923c/opentelemetry_instrumentation_sqlalchemy-0.49b0-py3-none-any.whl", hash = "sha256:d854052d2b02cd0562e5628a514c8153fceada7f585137e173165dfd0a46ef6a", size = 13358, upload-time = "2024-11-05T19:21:23.654Z" }, + { url = "https://files.pythonhosted.org/packages/1f/97/b906a930c6a1a20c53ecc8b58cabc2cdd0ce560a2b5d44259084ffe4333e/opentelemetry_instrumentation_sqlalchemy-0.61b0-py3-none-any.whl", hash = "sha256:f115e0be54116ba4c327b8d7b68db4045ee18d44439d888ab8130a549c50d1c1", size = 14547, upload-time = "2026-03-04T14:19:53.088Z" }, ] [[package]] name = "opentelemetry-instrumentation-wsgi" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, @@ -4421,9 +4423,9 @@ dependencies = [ { name = "opentelemetry-semantic-conventions" }, { name = "opentelemetry-util-http" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/2b/91b022b004ac9e9ab0eefd10bc4257975291f88adc81b4ef2c601ddb1adf/opentelemetry_instrumentation_wsgi-0.49b0.tar.gz", hash = "sha256:0812a02e132f8fc3d5c897bba84e530c37b85c315b199bb97ca6508279e7eb23", size = 17733, upload-time = "2024-11-05T19:22:24.3Z" } +sdist = { url = "https://files.pythonhosted.org/packages/89/e5/189f2845362cfe78e356ba127eab21456309def411c6874aa4800c3de816/opentelemetry_instrumentation_wsgi-0.61b0.tar.gz", hash = "sha256:380f2ae61714e5303275a80b2e14c58571573cd1fddf496d8c39fb9551c5e532", size = 19898, upload-time = "2026-03-04T14:20:54.068Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/1d/59979665778ed8c85bc31c92b75571cd7afb8e3322fb513c87fe1bad6d78/opentelemetry_instrumentation_wsgi-0.49b0-py3-none-any.whl", hash = "sha256:8869ccf96611827e4448417718920e9eec6d25bffb5bf72c7952c7346ec33fbc", size = 13699, upload-time = "2024-11-05T19:21:35.039Z" }, + { url = "https://files.pythonhosted.org/packages/96/75/d6b42ba26f3c921be6d01b16561b7bb863f843bad7ac3a5011f62617bcab/opentelemetry_instrumentation_wsgi-0.61b0-py3-none-any.whl", hash = "sha256:bd33b0824166f24134a3400648805e8d2e6a7951f070241294e8b8866611d7fa", size = 14628, upload-time = "2026-03-04T14:20:03.934Z" }, ] [[package]] @@ -4441,50 +4443,50 @@ wheels = [ [[package]] name = "opentelemetry-proto" -version = "1.28.0" +version = "1.40.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/63/ac4cef4d30ea0ca1d2153ad2fc62d91d1cf3b89b0e4e5cbd61a8c567885f/opentelemetry_proto-1.28.0.tar.gz", hash = "sha256:4a45728dfefa33f7908b828b9b7c9f2c6de42a05d5ec7b285662ddae71c4c870", size = 34331, upload-time = "2024-11-05T19:14:59.503Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/77/dd38991db037fdfce45849491cb61de5ab000f49824a00230afb112a4392/opentelemetry_proto-1.40.0.tar.gz", hash = "sha256:03f639ca129ba513f5819810f5b1f42bcb371391405d99c168fe6937c62febcd", size = 45667, upload-time = "2026-03-04T14:17:31.194Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/86/94/c0b43d16e1d96ee1e699373aa59f14a3aa2e7126af3f11d6adc5dcc531cd/opentelemetry_proto-1.28.0-py3-none-any.whl", hash = "sha256:d5ad31b997846543b8e15504657d9a8cf1ad3c71dcbbb6c4799b1ab29e38f7f9", size = 55832, upload-time = "2024-11-05T19:14:40.446Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b2/189b2577dde745b15625b3214302605b1353436219d42b7912e77fa8dc24/opentelemetry_proto-1.40.0-py3-none-any.whl", hash = "sha256:266c4385d88923a23d63e353e9761af0f47a6ed0d486979777fe4de59dc9b25f", size = 72073, upload-time = "2026-03-04T14:17:16.673Z" }, ] [[package]] name = "opentelemetry-sdk" -version = "1.28.0" +version = "1.40.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "opentelemetry-api" }, { name = "opentelemetry-semantic-conventions" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0c/5b/a509ccab93eacc6044591d5ec437d8266e76f893d0389bbf7e5592c7da32/opentelemetry_sdk-1.28.0.tar.gz", hash = "sha256:41d5420b2e3fb7716ff4981b510d551eff1fc60eb5a95cf7335b31166812a893", size = 156155, upload-time = "2024-11-05T19:15:00.451Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/fd/3c3125b20ba18ce2155ba9ea74acb0ae5d25f8cd39cfd37455601b7955cc/opentelemetry_sdk-1.40.0.tar.gz", hash = "sha256:18e9f5ec20d859d268c7cb3c5198c8d105d073714db3de50b593b8c1345a48f2", size = 184252, upload-time = "2026-03-04T14:17:31.87Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/fe/c8decbebb5660529f1d6ba65e50a45b1294022dfcba2968fc9c8697c42b2/opentelemetry_sdk-1.28.0-py3-none-any.whl", hash = "sha256:4b37da81d7fad67f6683c4420288c97f4ed0d988845d5886435f428ec4b8429a", size = 118692, upload-time = "2024-11-05T19:14:41.669Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c5/6a852903d8bfac758c6dc6e9a68b015d3c33f2f1be5e9591e0f4b69c7e0a/opentelemetry_sdk-1.40.0-py3-none-any.whl", hash = "sha256:787d2154a71f4b3d81f20524a8ce061b7db667d24e46753f32a7bc48f1c1f3f1", size = 141951, upload-time = "2026-03-04T14:17:17.961Z" }, ] [[package]] name = "opentelemetry-semantic-conventions" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "deprecated" }, { name = "opentelemetry-api" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ee/c8/433b0e54143f8c9369f5c4a7a83e73eec7eb2ee7d0b7e81a9243e78c8e80/opentelemetry_semantic_conventions-0.49b0.tar.gz", hash = "sha256:dbc7b28339e5390b6b28e022835f9bac4e134a80ebf640848306d3c5192557e8", size = 95227, upload-time = "2024-11-05T19:15:01.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/c0/4ae7973f3c2cfd2b6e321f1675626f0dab0a97027cc7a297474c9c8f3d04/opentelemetry_semantic_conventions-0.61b0.tar.gz", hash = "sha256:072f65473c5d7c6dc0355b27d6c9d1a679d63b6d4b4b16a9773062cb7e31192a", size = 145755, upload-time = "2026-03-04T14:17:32.664Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/05/20104df4ef07d3bf5c3fd6bcc796ef70ab4ea4309378a9ba57bc4b4d01fa/opentelemetry_semantic_conventions-0.49b0-py3-none-any.whl", hash = "sha256:0458117f6ead0b12e3221813e3e511d85698c31901cac84682052adb9c17c7cd", size = 159214, upload-time = "2024-11-05T19:14:43.047Z" }, + { url = "https://files.pythonhosted.org/packages/b2/37/cc6a55e448deaa9b27377d087da8615a3416d8ad523d5960b78dbeadd02a/opentelemetry_semantic_conventions-0.61b0-py3-none-any.whl", hash = "sha256:fa530a96be229795f8cef353739b618148b0fe2b4b3f005e60e262926c4d38e2", size = 231621, upload-time = "2026-03-04T14:17:19.33Z" }, ] [[package]] name = "opentelemetry-util-http" -version = "0.49b0" +version = "0.61b0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a3/99/377ef446928808211b127b9ab31c348bc465c8da4514ebeec6e4a3de3d21/opentelemetry_util_http-0.49b0.tar.gz", hash = "sha256:02928496afcffd58a7c15baf99d2cedae9b8325a8ac52b0d0877b2e8f936dd1b", size = 7863, upload-time = "2024-11-05T19:22:26.973Z" } +sdist = { url = "https://files.pythonhosted.org/packages/57/3c/f0196223efc5c4ca19f8fad3d5462b171ac6333013335ce540c01af419e9/opentelemetry_util_http-0.61b0.tar.gz", hash = "sha256:1039cb891334ad2731affdf034d8fb8b48c239af9b6dd295e5fabd07f1c95572", size = 11361, upload-time = "2026-03-04T14:20:57.01Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/66/0e/ab0a89b315d0bacdd355a345bb69b20c50fc1f0804b52b56fe1c35a60e68/opentelemetry_util_http-0.49b0-py3-none-any.whl", hash = "sha256:8661bbd6aea1839badc44de067ec9c15c05eab05f729f496c856c50a1203caf1", size = 6945, upload-time = "2024-11-05T19:21:37.81Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e5/c08aaaf2f64288d2b6ef65741d2de5454e64af3e050f34285fb1907492fe/opentelemetry_util_http-0.61b0-py3-none-any.whl", hash = "sha256:8e715e848233e9527ea47e275659ea60a57a75edf5206a3b937e236a6da5fc33", size = 9281, upload-time = "2026-03-04T14:20:08.364Z" }, ] [[package]] @@ -5253,11 +5255,11 @@ wheels = [ [[package]] name = "pygments" -version = "2.19.2" +version = "2.20.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, ] [[package]] diff --git a/dev/setup b/dev/setup index 399c8f28a5..4236ff7fa7 100755 --- a/dev/setup +++ b/dev/setup @@ -24,5 +24,4 @@ cp "$MIDDLEWARE_ENV_EXAMPLE" "$MIDDLEWARE_ENV" cd "$ROOT/api" uv sync --group dev -cd "$ROOT/web" -pnpm install +pnpm --dir "$ROOT" install diff --git a/dev/start-docker-compose b/dev/start-docker-compose index 9652be169d..aa4f66a6cf 100755 --- a/dev/start-docker-compose +++ b/dev/start-docker-compose @@ -1,8 +1,8 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(dirname "$(realpath "$0")")" -ROOT="$(dirname "$SCRIPT_DIR")" - -cd "$ROOT/docker" -docker compose -f docker-compose.middleware.yaml --profile postgresql --profile weaviate -p dify up -d +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(dirname "$(realpath "$0")")" +ROOT="$(dirname "$SCRIPT_DIR")" + +cd "$ROOT/docker" +docker compose --env-file middleware.env -f docker-compose.middleware.yaml -p dify up -d diff --git a/dev/start-web b/dev/start-web index f853f4a895..baf008274b 100755 --- a/dev/start-web +++ b/dev/start-web @@ -3,6 +3,6 @@ set -x SCRIPT_DIR="$(dirname "$(realpath "$0")")" -cd "$SCRIPT_DIR/../web" +ROOT_DIR="$(dirname "$SCRIPT_DIR")" -pnpm install && pnpm dev:inspect +pnpm --dir "$ROOT_DIR" install && pnpm --dir "$ROOT_DIR/web" dev:inspect diff --git a/docker/.env.example b/docker/.env.example index 9fbf9a9e72..b2d6244b46 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -186,8 +186,10 @@ CELERY_WORKER_CLASS= # it is recommended to set it to 360 to support a longer sse connection time. GUNICORN_TIMEOUT=360 -# The number of Celery workers. The default is 1, and can be set as needed. -CELERY_WORKER_AMOUNT= +# The number of Celery workers. The default is 4 for development environments +# to allow parallel processing of workflows, document indexing, and other async tasks. +# Adjust based on your system resources and workload requirements. +CELERY_WORKER_AMOUNT=4 # Flag indicating whether to enable autoscaling of Celery workers. # diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 737a62020c..ed68107f46 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -46,7 +46,7 @@ x-shared-env: &shared-api-worker-env SERVER_WORKER_CONNECTIONS: ${SERVER_WORKER_CONNECTIONS:-10} CELERY_WORKER_CLASS: ${CELERY_WORKER_CLASS:-} GUNICORN_TIMEOUT: ${GUNICORN_TIMEOUT:-360} - CELERY_WORKER_AMOUNT: ${CELERY_WORKER_AMOUNT:-} + CELERY_WORKER_AMOUNT: ${CELERY_WORKER_AMOUNT:-4} CELERY_AUTO_SCALE: ${CELERY_AUTO_SCALE:-false} CELERY_MAX_WORKERS: ${CELERY_MAX_WORKERS:-} CELERY_MIN_WORKERS: ${CELERY_MIN_WORKERS:-} diff --git a/e2e/AGENTS.md b/e2e/AGENTS.md index 245c9863d4..ae642768f5 100644 --- a/e2e/AGENTS.md +++ b/e2e/AGENTS.md @@ -19,15 +19,18 @@ It tests: - `uv` - Docker +Run the following commands from the repository root. + Install Playwright browsers once: ```bash -cd e2e pnpm install -pnpm e2e:install -pnpm check +pnpm -C e2e e2e:install +pnpm -C e2e check ``` +`pnpm install` is resolved through the repository workspace and uses the shared root lockfile plus `pnpm-workspace.yaml`. + Use `pnpm check` as the default local verification step after editing E2E TypeScript, Cucumber support code, or feature glue. It runs formatting, linting, and type checks for this package. Common commands: @@ -35,20 +38,20 @@ Common commands: ```bash # authenticated-only regression (default excludes @fresh) # expects backend API, frontend artifact, and middleware stack to already be running -pnpm e2e +pnpm -C e2e e2e # full reset + fresh install + authenticated scenarios # starts required middleware/dependencies for you -pnpm e2e:full +pnpm -C e2e e2e:full # run a tagged subset -pnpm e2e -- --tags @smoke +pnpm -C e2e e2e -- --tags @smoke # headed browser -pnpm e2e:headed -- --tags @smoke +pnpm -C e2e e2e:headed -- --tags @smoke # slow down browser actions for local debugging -E2E_SLOW_MO=500 pnpm e2e:headed -- --tags @smoke +E2E_SLOW_MO=500 pnpm -C e2e e2e:headed -- --tags @smoke ``` Frontend artifact behavior: @@ -101,7 +104,7 @@ Because of that, the `@fresh` install scenario only runs in the `pnpm e2e:full*` Reset all persisted E2E state: ```bash -pnpm e2e:reset +pnpm -C e2e e2e:reset ``` This removes: @@ -117,7 +120,7 @@ This removes: Start the full middleware stack: ```bash -pnpm e2e:middleware:up +pnpm -C e2e e2e:middleware:up ``` Stop the full middleware stack: diff --git a/e2e/package.json b/e2e/package.json index 9b8a1f873f..0ee2afff7f 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -14,21 +14,11 @@ "e2e:reset": "tsx ./scripts/setup.ts reset" }, "devDependencies": { - "@cucumber/cucumber": "12.7.0", - "@playwright/test": "1.51.1", - "@types/node": "25.5.0", - "tsx": "4.21.0", - "typescript": "5.9.3", - "vite-plus": "latest" - }, - "engines": { - "node": "^22.22.1" - }, - "packageManager": "pnpm@10.32.1", - "pnpm": { - "overrides": { - "vite": "npm:@voidzero-dev/vite-plus-core@latest", - "vitest": "npm:@voidzero-dev/vite-plus-test@latest" - } + "@cucumber/cucumber": "catalog:", + "@playwright/test": "catalog:", + "@types/node": "catalog:", + "tsx": "catalog:", + "typescript": "catalog:", + "vite-plus": "catalog:" } } diff --git a/e2e/pnpm-lock.yaml b/e2e/pnpm-lock.yaml deleted file mode 100644 index b63458ad4a..0000000000 --- a/e2e/pnpm-lock.yaml +++ /dev/null @@ -1,2632 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -overrides: - vite: npm:@voidzero-dev/vite-plus-core@latest - vitest: npm:@voidzero-dev/vite-plus-test@latest - -importers: - - .: - devDependencies: - '@cucumber/cucumber': - specifier: 12.7.0 - version: 12.7.0 - '@playwright/test': - specifier: 1.51.1 - version: 1.51.1 - '@types/node': - specifier: 25.5.0 - version: 25.5.0 - tsx: - specifier: 4.21.0 - version: 4.21.0 - typescript: - specifier: 5.9.3 - version: 5.9.3 - vite-plus: - specifier: latest - version: 0.1.14(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3) - -packages: - - '@babel/code-frame@7.29.0': - resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - - '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} - - '@cucumber/ci-environment@13.0.0': - resolution: {integrity: sha512-cs+3NzfNkGbcmHPddjEv4TKFiBpZRQ6WJEEufB9mw+ExS22V/4R/zpDSEG+fsJ/iSNCd6A2sATdY8PFOyY3YnA==} - - '@cucumber/cucumber-expressions@19.0.0': - resolution: {integrity: sha512-4FKoOQh2Uf6F6/Ln+1OxuK8LkTg6PyAqekhf2Ix8zqV2M54sH+m7XNJNLhOFOAW/t9nxzRbw2CcvXbCLjcvHZg==} - - '@cucumber/cucumber@12.7.0': - resolution: {integrity: sha512-7A/9CJpJDxv1SQ7hAZU0zPn2yRxx6XMR+LO4T94Enm3cYNWsEEj+RGX38NLX4INT+H6w5raX3Csb/qs4vUBsOA==} - engines: {node: 20 || 22 || >=24} - hasBin: true - - '@cucumber/gherkin-streams@6.0.0': - resolution: {integrity: sha512-HLSHMmdDH0vCr7vsVEURcDA4WwnRLdjkhqr6a4HQ3i4RFK1wiDGPjBGVdGJLyuXuRdJpJbFc6QxHvT8pU4t6jw==} - hasBin: true - peerDependencies: - '@cucumber/gherkin': '>=22.0.0' - '@cucumber/message-streams': '>=4.0.0' - '@cucumber/messages': '>=17.1.1' - - '@cucumber/gherkin-utils@11.0.0': - resolution: {integrity: sha512-LJ+s4+TepHTgdKWDR4zbPyT7rQjmYIcukTwNbwNwgqr6i8Gjcmzf6NmtbYDA19m1ZFg6kWbFsmHnj37ZuX+kZA==} - hasBin: true - - '@cucumber/gherkin@38.0.0': - resolution: {integrity: sha512-duEXK+KDfQUzu3vsSzXjkxQ2tirF5PRsc1Xrts6THKHJO6mjw4RjM8RV+vliuDasmhhrmdLcOcM7d9nurNTJKw==} - - '@cucumber/html-formatter@23.0.0': - resolution: {integrity: sha512-WwcRzdM8Ixy4e53j+Frm3fKM5rNuIyWUfy4HajEN+Xk/YcjA6yW0ACGTFDReB++VDZz/iUtwYdTlPRY36NbqJg==} - peerDependencies: - '@cucumber/messages': '>=18' - - '@cucumber/junit-xml-formatter@0.9.0': - resolution: {integrity: sha512-WF+A7pBaXpKMD1i7K59Nk5519zj4extxY4+4nSgv5XLsGXHDf1gJnb84BkLUzevNtp2o2QzMG0vWLwSm8V5blw==} - peerDependencies: - '@cucumber/messages': '*' - - '@cucumber/message-streams@4.0.1': - resolution: {integrity: sha512-Kxap9uP5jD8tHUZVjTWgzxemi/0uOsbGjd4LBOSxcJoOCRbESFwemUzilJuzNTB8pcTQUh8D5oudUyxfkJOKmA==} - peerDependencies: - '@cucumber/messages': '>=17.1.1' - - '@cucumber/messages@32.0.1': - resolution: {integrity: sha512-1OSoW+GQvFUNAl6tdP2CTBexTXMNJF0094goVUcvugtQeXtJ0K8sCP0xbq7GGoiezs/eJAAOD03+zAPT64orHQ==} - - '@cucumber/pretty-formatter@1.0.1': - resolution: {integrity: sha512-A1lU4VVP0aUWdOTmpdzvXOyEYuPtBDI0xYwYJnmoMDplzxMdhcHk86lyyvYDoMoPzzq6OkOE3isuosvUU4X7IQ==} - peerDependencies: - '@cucumber/cucumber': '>=7.0.0' - '@cucumber/messages': '*' - - '@cucumber/query@14.7.0': - resolution: {integrity: sha512-fiqZ4gMEgYjmbuWproF/YeCdD5y+gD2BqgBIGbpihOsx6UlNsyzoDSfO+Tny0q65DxfK+pHo2UkPyEl7dO7wmQ==} - peerDependencies: - '@cucumber/messages': '*' - - '@cucumber/tag-expressions@9.1.0': - resolution: {integrity: sha512-bvHjcRFZ+J1TqIa9eFNO1wGHqwx4V9ZKV3hYgkuK/VahHx73uiP4rKV3JVrvWSMrwrFvJG6C8aEwnCWSvbyFdQ==} - - '@emnapi/core@1.9.1': - resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} - - '@emnapi/runtime@1.9.1': - resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} - - '@emnapi/wasi-threads@1.2.0': - resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} - - '@esbuild/aix-ppc64@0.27.4': - resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.27.4': - resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.27.4': - resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.27.4': - resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.27.4': - resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.27.4': - resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.27.4': - resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.27.4': - resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.27.4': - resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.27.4': - resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.27.4': - resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.27.4': - resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.27.4': - resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.27.4': - resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.27.4': - resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.27.4': - resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.27.4': - resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.27.4': - resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.27.4': - resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.27.4': - resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.27.4': - resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.27.4': - resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.27.4': - resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.27.4': - resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.27.4': - resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.27.4': - resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@napi-rs/wasm-runtime@1.1.1': - resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} - - '@oxc-project/runtime@0.121.0': - resolution: {integrity: sha512-p0bQukD8OEHxzY4T9OlANBbEFGnOnjo1CYi50HES7OD36UO2yPh6T+uOJKLtlg06eclxroipRCpQGMpeH8EJ/g==} - engines: {node: ^20.19.0 || >=22.12.0} - - '@oxc-project/types@0.122.0': - resolution: {integrity: sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==} - - '@oxfmt/binding-android-arm-eabi@0.42.0': - resolution: {integrity: sha512-dsqPTYsozeokRjlrt/b4E7Pj0z3eS3Eg74TWQuuKbjY4VttBmA88rB7d50Xrd+TZ986qdXCNeZRPEzZHAe+jow==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@oxfmt/binding-android-arm64@0.42.0': - resolution: {integrity: sha512-t+aAjHxcr5eOBphFHdg1ouQU9qmZZoRxnX7UOJSaTwSoKsb6TYezNKO0YbWytGXCECObRqNcUxPoPr0KaraAIg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@oxfmt/binding-darwin-arm64@0.42.0': - resolution: {integrity: sha512-ulpSEYMKg61C5bRMZinFHrKJYRoKGVbvMEXA5zM1puX3O9T6Q4XXDbft20yrDijpYWeuG59z3Nabt+npeTsM1A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@oxfmt/binding-darwin-x64@0.42.0': - resolution: {integrity: sha512-ttxLKhQYPdFiM8I/Ri37cvqChE4Xa562nNOsZFcv1CKTVLeEozXjKuYClNvxkXmNlcF55nzM80P+CQkdFBu+uQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@oxfmt/binding-freebsd-x64@0.42.0': - resolution: {integrity: sha512-Og7QS3yI3tdIKYZ58SXik0rADxIk2jmd+/YvuHRyKULWpG4V2fR5V4hvKm624Mc0cQET35waPXiCQWvjQEjwYQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@oxfmt/binding-linux-arm-gnueabihf@0.42.0': - resolution: {integrity: sha512-jwLOw/3CW4H6Vxcry4/buQHk7zm9Ne2YsidzTL1kpiMe4qqrRCwev3dkyWe2YkFmP+iZCQ7zku4KwjcLRoh8ew==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxfmt/binding-linux-arm-musleabihf@0.42.0': - resolution: {integrity: sha512-XwXu2vkMtiq2h7tfvN+WA/9/5/1IoGAVCFPiiQUvcAuG3efR97KNcRGM8BetmbYouFotQ2bDal3yyjUx6IPsTg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxfmt/binding-linux-arm64-gnu@0.42.0': - resolution: {integrity: sha512-ea7s/XUJoT7ENAtUQDudFe3nkSM3e3Qpz4nJFRdzO2wbgXEcjnchKLEsV3+t4ev3r8nWxIYr9NRjPWtnyIFJVA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-arm64-musl@0.42.0': - resolution: {integrity: sha512-+JA0YMlSdDqmacygGi2REp57c3fN+tzARD8nwsukx9pkCHK+6DkbAA9ojS4lNKsiBjIW8WWa0pBrBWhdZEqfuw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@oxfmt/binding-linux-ppc64-gnu@0.42.0': - resolution: {integrity: sha512-VfnET0j4Y5mdfCzh5gBt0NK28lgn5DKx+8WgSMLYYeSooHhohdbzwAStLki9pNuGy51y4I7IoW8bqwAaCMiJQg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-riscv64-gnu@0.42.0': - resolution: {integrity: sha512-gVlCbmBkB0fxBWbhBj9rcxezPydsQHf4MFKeHoTSPicOQ+8oGeTQgQ8EeesSybWeiFPVRx3bgdt4IJnH6nOjAA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-riscv64-musl@0.42.0': - resolution: {integrity: sha512-zN5OfstL0avgt/IgvRu0zjQzVh/EPkcLzs33E9LMAzpqlLWiPWeMDZyMGFlSRGOdDjuNmlZBCgj0pFnK5u32TQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@oxfmt/binding-linux-s390x-gnu@0.42.0': - resolution: {integrity: sha512-9X6+H2L0qMc2sCAgO9HS03bkGLMKvOFjmEdchaFlany3vNZOjnVui//D8k/xZAtQv2vaCs1reD5KAgPoIU4msA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-x64-gnu@0.42.0': - resolution: {integrity: sha512-BajxJ6KQvMMdpXGPWhBGyjb2Jvx4uec0w+wi6TJZ6Tv7+MzPwe0pO8g5h1U0jyFgoaF7mDl6yKPW3ykWcbUJRw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-x64-musl@0.42.0': - resolution: {integrity: sha512-0wV284I6vc5f0AqAhgAbHU2935B4bVpncPoe5n/WzVZY/KnHgqxC8iSFGeSyLWEgstFboIcWkOPck7tqbdHkzA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@oxfmt/binding-openharmony-arm64@0.42.0': - resolution: {integrity: sha512-p4BG6HpGnhfgHk1rzZfyR6zcWkE7iLrWxyehHfXUy4Qa5j3e0roglFOdP/Nj5cJJ58MA3isQ5dlfkW2nNEpolw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@oxfmt/binding-win32-arm64-msvc@0.42.0': - resolution: {integrity: sha512-mn//WV60A+IetORDxYieYGAoQso4KnVRRjORDewMcod4irlRe0OSC7YPhhwaexYNPQz/GCFk+v9iUcZ2W22yxQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@oxfmt/binding-win32-ia32-msvc@0.42.0': - resolution: {integrity: sha512-3gWltUrvuz4LPJXWivoAxZ28Of2O4N7OGuM5/X3ubPXCEV8hmgECLZzjz7UYvSDUS3grfdccQwmjynm+51EFpw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ia32] - os: [win32] - - '@oxfmt/binding-win32-x64-msvc@0.42.0': - resolution: {integrity: sha512-Wg4TMAfQRL9J9AZevJ/ZNy3uyyDztDYQtGr4P8UyyzIhLhFrdSmz1J/9JT+rv0fiCDLaFOBQnj3f3K3+a5PzDQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@oxlint-tsgolint/darwin-arm64@0.17.3': - resolution: {integrity: sha512-5aDl4mxXWs+Bj02pNrX6YY6v9KMZjLIytXoqolLEo0dfBNVeZUonZgJAa/w0aUmijwIRrBhxEzb42oLuUtfkGw==} - cpu: [arm64] - os: [darwin] - - '@oxlint-tsgolint/darwin-x64@0.17.3': - resolution: {integrity: sha512-gPBy4DS5ueCgXzko20XsNZzDe/Cxde056B+QuPLGvz05CGEAtmRfpImwnyY2lAXXjPL+SmnC/OYexu8zI12yHQ==} - cpu: [x64] - os: [darwin] - - '@oxlint-tsgolint/linux-arm64@0.17.3': - resolution: {integrity: sha512-+pkunvCfB6pB0G9qHVVXUao3nqzXQPo4O3DReIi+5nGa+bOU3J3Srgy+Zb8VyOL+WDsSMJ+U7+r09cKHWhz3hg==} - cpu: [arm64] - os: [linux] - - '@oxlint-tsgolint/linux-x64@0.17.3': - resolution: {integrity: sha512-/kW5oXtBThu4FjmgIBthdmMjWLzT3M1TEDQhxDu7hQU5xDeTd60CDXb2SSwKCbue9xu7MbiFoJu83LN0Z/d38g==} - cpu: [x64] - os: [linux] - - '@oxlint-tsgolint/win32-arm64@0.17.3': - resolution: {integrity: sha512-NMELRvbz4Ed4dxg8WiqZxtu3k4OJEp2B9KInZW+BMfqEqbwZdEJY83tbqz2hD1EjKO2akrqBQ0GpRUJEkd8kKw==} - cpu: [arm64] - os: [win32] - - '@oxlint-tsgolint/win32-x64@0.17.3': - resolution: {integrity: sha512-+pJ7r8J3SLPws5uoidVplZc8R/lpKyKPE6LoPGv9BME00Y1VjT6jWGx/dtUN8PWvcu3iTC6k+8u3ojFSJNmWTg==} - cpu: [x64] - os: [win32] - - '@oxlint/binding-android-arm-eabi@1.57.0': - resolution: {integrity: sha512-C7EiyfAJG4B70496eV543nKiq5cH0o/xIh/ufbjQz3SIvHhlDDsyn+mRFh+aW8KskTyUpyH2LGWL8p2oN6bl1A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@oxlint/binding-android-arm64@1.57.0': - resolution: {integrity: sha512-9i80AresjZ/FZf5xK8tKFbhQnijD4s1eOZw6/FHUwD59HEZbVLRc2C88ADYJfLZrF5XofWDiRX/Ja9KefCLy7w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@oxlint/binding-darwin-arm64@1.57.0': - resolution: {integrity: sha512-0eUfhRz5L2yKa9I8k3qpyl37XK3oBS5BvrgdVIx599WZK63P8sMbg+0s4IuxmIiZuBK68Ek+Z+gcKgeYf0otsg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@oxlint/binding-darwin-x64@1.57.0': - resolution: {integrity: sha512-UvrSuzBaYOue+QMAcuDITe0k/Vhj6KZGjfnI6x+NkxBTke/VoM7ZisaxgNY0LWuBkTnd1OmeQfEQdQ48fRjkQg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@oxlint/binding-freebsd-x64@1.57.0': - resolution: {integrity: sha512-wtQq0dCoiw4bUwlsNVDJJ3pxJA218fOezpgtLKrbQqUtQJcM9yP8z+I9fu14aHg0uyAxIY+99toL6uBa2r7nxA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@oxlint/binding-linux-arm-gnueabihf@1.57.0': - resolution: {integrity: sha512-qxFWl2BBBFcT4djKa+OtMdnLgoHEJXpqjyGwz8OhW35ImoCwR5qtAGqApNYce5260FQqoAHW8S8eZTjiX67Tsg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxlint/binding-linux-arm-musleabihf@1.57.0': - resolution: {integrity: sha512-SQoIsBU7J0bDW15/f0/RvxHfY3Y0+eB/caKBQtNFbuerTiA6JCYx9P1MrrFTwY2dTm/lMgTSgskvCEYk2AtG/Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxlint/binding-linux-arm64-gnu@1.57.0': - resolution: {integrity: sha512-jqxYd1W6WMeozsCmqe9Rzbu3SRrGTyGDAipRlRggetyYbUksJqJKvUNTQtZR/KFoJPb+grnSm5SHhdWrywv3RQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-arm64-musl@1.57.0': - resolution: {integrity: sha512-i66WyEPVEvq9bxRUCJ/MP5EBfnTDN3nhwEdFZFTO5MmLLvzngfWEG3NSdXQzTT3vk5B9i6C2XSIYBh+aG6uqyg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@oxlint/binding-linux-ppc64-gnu@1.57.0': - resolution: {integrity: sha512-oMZDCwz4NobclZU3pH+V1/upVlJZiZvne4jQP+zhJwt+lmio4XXr4qG47CehvrW1Lx2YZiIHuxM2D4YpkG3KVA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-riscv64-gnu@1.57.0': - resolution: {integrity: sha512-uoBnjJ3MMEBbfnWC1jSFr7/nSCkcQYa72NYoNtLl1imshDnWSolYCjzb8LVCwYCCfLJXD+0gBLD7fyC14c0+0g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-riscv64-musl@1.57.0': - resolution: {integrity: sha512-BdrwD7haPZ8a9KrZhKJRSj6jwCor+Z8tHFZ3PT89Y3Jq5v3LfMfEePeAmD0LOTWpiTmzSzdmyw9ijneapiVHKQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@oxlint/binding-linux-s390x-gnu@1.57.0': - resolution: {integrity: sha512-BNs+7ZNsRstVg2tpNxAXfMX/Iv5oZh204dVyb8Z37+/gCh+yZqNTlg6YwCLIMPSk5wLWIGOaQjT0GUOahKYImw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-x64-gnu@1.57.0': - resolution: {integrity: sha512-AghS18w+XcENcAX0+BQGLiqjpqpaxKJa4cWWP0OWNLacs27vHBxu7TYkv9LUSGe5w8lOJHeMxcYfZNOAPqw2bg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@oxlint/binding-linux-x64-musl@1.57.0': - resolution: {integrity: sha512-E/FV3GB8phu/Rpkhz5T96hAiJlGzn91qX5yj5gU754P5cmVGXY1Jw/VSjDSlZBCY3VHjsVLdzgdkJaomEmcNOg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@oxlint/binding-openharmony-arm64@1.57.0': - resolution: {integrity: sha512-xvZ2yZt0nUVfU14iuGv3V25jpr9pov5N0Wr28RXnHFxHCRxNDMtYPHV61gGLhN9IlXM96gI4pyYpLSJC5ClLCQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@oxlint/binding-win32-arm64-msvc@1.57.0': - resolution: {integrity: sha512-Z4D8Pd0AyHBKeazhdIXeUUy5sIS3Mo0veOlzlDECg6PhRRKgEsBJCCV1n+keUZtQ04OP+i7+itS3kOykUyNhDg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@oxlint/binding-win32-ia32-msvc@1.57.0': - resolution: {integrity: sha512-StOZ9nFMVKvevicbQfql6Pouu9pgbeQnu60Fvhz2S6yfMaii+wnueLnqQ5I1JPgNF0Syew4voBlAaHD13wH6tw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ia32] - os: [win32] - - '@oxlint/binding-win32-x64-msvc@1.57.0': - resolution: {integrity: sha512-6PuxhYgth8TuW0+ABPOIkGdBYw+qYGxgIdXPHSVpiCDm+hqTTWCmC739St1Xni0DJBt8HnSHTG67i1y6gr8qrA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@playwright/test@1.51.1': - resolution: {integrity: sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q==} - engines: {node: '>=18'} - hasBin: true - - '@polka/url@1.0.0-next.29': - resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - - '@rolldown/binding-android-arm64@1.0.0-rc.12': - resolution: {integrity: sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.0.0-rc.12': - resolution: {integrity: sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.0.0-rc.12': - resolution: {integrity: sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.0.0-rc.12': - resolution: {integrity: sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12': - resolution: {integrity: sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12': - resolution: {integrity: sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.12': - resolution: {integrity: sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12': - resolution: {integrity: sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12': - resolution: {integrity: sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.12': - resolution: {integrity: sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-musl@1.0.0-rc.12': - resolution: {integrity: sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.12': - resolution: {integrity: sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.0.0-rc.12': - resolution: {integrity: sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12': - resolution: {integrity: sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.12': - resolution: {integrity: sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.0-rc.12': - resolution: {integrity: sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@teppeis/multimaps@3.0.0': - resolution: {integrity: sha512-ID7fosbc50TbT0MK0EG12O+gAP3W3Aa/Pz4DaTtQtEvlc9Odaqi0de+xuZ7Li2GtK4HzEX7IuRWS/JmZLksR3Q==} - engines: {node: '>=14'} - - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} - - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/node@25.5.0': - resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==} - - '@types/normalize-package-data@2.4.4': - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - - '@voidzero-dev/vite-plus-core@0.1.14': - resolution: {integrity: sha512-CCWzdkfW0fo0cQNlIsYp5fOuH2IwKuPZEb2UY2Z8gXcp5pG74A82H2Pthj0heAuvYTAnfT7kEC6zM+RbiBgQbg==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - '@arethetypeswrong/core': ^0.18.1 - '@tsdown/css': 0.21.4 - '@tsdown/exe': 0.21.4 - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.0 - esbuild: ^0.27.0 - jiti: '>=1.21.0' - less: ^4.0.0 - publint: ^0.3.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - typescript: ^5.0.0 - unplugin-unused: ^0.5.0 - yaml: ^2.4.2 - peerDependenciesMeta: - '@arethetypeswrong/core': - optional: true - '@tsdown/css': - optional: true - '@tsdown/exe': - optional: true - '@types/node': - optional: true - '@vitejs/devtools': - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - publint: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - typescript: - optional: true - unplugin-unused: - optional: true - yaml: - optional: true - - '@voidzero-dev/vite-plus-darwin-arm64@0.1.14': - resolution: {integrity: sha512-q2ESUSbapwsxVRe/KevKATahNRraoX5nti3HT9S3266OHT5sMroBY14jaxTv74ekjQc9E6EPhyLGQWuWQuuBRw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@voidzero-dev/vite-plus-darwin-x64@0.1.14': - resolution: {integrity: sha512-UpcDZc9G99E/4HDRoobvYHxMvFOG5uv3RwEcq0HF70u4DsnEMl1z8RaJLeWV7a09LGwj9Q+YWC3Z4INWnTLs8g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.14': - resolution: {integrity: sha512-GIjn35RABUEDB9gHD26nRq7T72Te+Qy2+NIzogwEaUE728PvPkatF5gMCeF4sigCoc8c4qxDwsG+A2A2LYGnDg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@voidzero-dev/vite-plus-linux-arm64-musl@0.1.14': - resolution: {integrity: sha512-qo2RToGirG0XCcxZ2AEOuonLM256z6dNbJzDDIo5gWYA+cIKigFQJbkPyr25zsT1tsP2aY0OTxt2038XbVlRkQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@voidzero-dev/vite-plus-linux-x64-gnu@0.1.14': - resolution: {integrity: sha512-BsMWKZfdfGcYLxxLyaePpg6NW54xqzzcfq8sFUwKfwby0kgOKQ4WymUXyBvO9nnBb0ZPsJQrV0sx+Onac/LTaw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@voidzero-dev/vite-plus-linux-x64-musl@0.1.14': - resolution: {integrity: sha512-mOrEpj7ntW9RopGbcOYG/L0pOs0qHzUG4Vz7NXbuf4dbOSlY4JjyoMOIWxjKQORQht02Hzuf8YrMGNwa6AjVSQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@voidzero-dev/vite-plus-test@0.1.14': - resolution: {integrity: sha512-rjF+qpYD+5+THOJZ3gbE3+cxsk5sW7nJ0ODK7y6ZKeS4amREUMedEDYykzKBwR7OZDC/WwE90A0iLWCr6qAXhA==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} - peerDependencies: - '@edge-runtime/vm': '*' - '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/ui': 4.1.1 - happy-dom: '*' - jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@opentelemetry/api': - optional: true - '@types/node': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - '@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.14': - resolution: {integrity: sha512-7iC+Ig+8D/zACy0IJf7w/vQ7duTjux9Ttmm3KOBdVWH4dl3JihydA7+SQVMhz71a4WiqJ6nPidoG8D6hUP4MVQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@voidzero-dev/vite-plus-win32-x64-msvc@0.1.14': - resolution: {integrity: sha512-yRJ/8yAYFluNHx0Ej6Kevx65MIeM3wFKklnxosVZRlz2ZRL1Ea1Qh3tWATr3Ipk1ciRxBv8KJgp6zXqjxtZSoQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - ansi-regex@4.1.1: - resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} - engines: {node: '>=6'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - 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'} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - assertion-error-formatter@3.0.0: - resolution: {integrity: sha512-6YyAVLrEze0kQ7CmJfUgrLHb+Y7XghmL2Ie7ijVa2Y9ynP3LV+VDiwFk62Dn0qtqbmY0BT0ss6p1xxpiF2PYbQ==} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - - balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} - - brace-expansion@5.0.5: - resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} - engines: {node: 18 || 20 || >=22} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - cac@7.0.0: - resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} - engines: {node: '>=20.19.0'} - - capital-case@1.0.4: - resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - class-transformer@0.5.1: - resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} - - cli-table3@0.6.5: - resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} - engines: {node: 10.* || >= 12.*} - - 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==} - - commander@14.0.0: - resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} - engines: {node: '>=20'} - - commander@14.0.2: - resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} - engines: {node: '>=20'} - - commander@14.0.3: - resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} - engines: {node: '>=20'} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - - diff@4.0.4: - resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} - engines: {node: '>=0.3.1'} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - error-stack-parser@2.1.4: - resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} - - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - - esbuild@0.27.4: - resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} - engines: {node: '>=18'} - hasBin: true - - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - figures@3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - - find-up-simple@1.0.1: - resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} - engines: {node: '>=18'} - - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - get-tsconfig@4.13.7: - resolution: {integrity: sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==} - - glob@13.0.6: - resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} - engines: {node: 18 || 20 || >=22} - - global-dirs@3.0.1: - resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} - engines: {node: '>=10'} - - has-ansi@4.0.1: - resolution: {integrity: sha512-Qr4RtTm30xvEdqUXbSBVWDu+PrTokJOwe/FU+VdfJPk+MXAPoeOzKpRyrDTnZIJwAkQ4oBLTU53nu0HrkF/Z2A==} - engines: {node: '>=8'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - hosted-git-info@9.0.2: - resolution: {integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==} - engines: {node: ^20.17.0 || >=22.9.0} - - indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - - index-to-position@1.2.0: - resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} - engines: {node: '>=18'} - - ini@2.0.0: - resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} - engines: {node: '>=10'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-installed-globally@0.4.0: - resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} - engines: {node: '>=10'} - - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - knuth-shuffle-seeded@1.0.6: - resolution: {integrity: sha512-9pFH0SplrfyKyojCLxZfMcvkhf5hH0d+UwR9nTVJ/DDQJGuzcXjTwB7TP7sDfehSudlGGaOLblmEWqv04ERVWg==} - - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash.mergewith@4.6.2: - resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} - - lodash.sortby@4.7.0: - resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - - lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} - - lru-cache@11.2.7: - resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==} - engines: {node: 20 || >=22} - - luxon@3.7.2: - resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} - engines: {node: '>=12'} - - mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} - hasBin: true - - minimatch@10.2.4: - resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} - engines: {node: 18 || 20 || >=22} - - minipass@7.1.3: - resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} - engines: {node: '>=16 || 14 >=14.17'} - - mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - - mrmime@2.0.1: - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} - engines: {node: '>=10'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - - normalize-package-data@8.0.0: - resolution: {integrity: sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==} - engines: {node: ^20.17.0 || >=22.9.0} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - - oxfmt@0.42.0: - resolution: {integrity: sha512-QhejGErLSMReNuZ6vxgFHDyGoPbjTRNi6uGHjy0cvIjOQFqD6xmr/T+3L41ixR3NIgzcNiJ6ylQKpvShTgDfqg==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - oxlint-tsgolint@0.17.3: - resolution: {integrity: sha512-1eh4bcpOMw0e7+YYVxmhFc2mo/V6hJ2+zfukqf+GprvVn3y94b69M/xNrYLmx5A+VdYe0i/bJ2xOs6Hp/jRmRA==} - hasBin: true - - oxlint@1.57.0: - resolution: {integrity: sha512-DGFsuBX5MFZX9yiDdtKjTrYPq45CZ8Fft6qCltJITYZxfwYjVdGf/6wycGYTACloauwIPxUnYhBVeZbHvleGhw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - oxlint-tsgolint: '>=0.15.0' - peerDependenciesMeta: - oxlint-tsgolint: - optional: true - - pad-right@0.2.2: - resolution: {integrity: sha512-4cy8M95ioIGolCoMmm2cMntGR1lPLEbOMzOKu8bzjuJP6JpzEMQcDHmh7hHLYGgob+nKe1YHFMaG4V59HQa89g==} - engines: {node: '>=0.10.0'} - - parse-json@8.3.0: - resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} - engines: {node: '>=18'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-scurry@2.0.2: - resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} - engines: {node: 18 || 20 || >=22} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} - - pixelmatch@7.1.0: - resolution: {integrity: sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==} - hasBin: true - - playwright-core@1.51.1: - resolution: {integrity: sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==} - engines: {node: '>=18'} - hasBin: true - - playwright@1.51.1: - resolution: {integrity: sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==} - engines: {node: '>=18'} - hasBin: true - - pngjs@7.0.0: - resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} - engines: {node: '>=14.19.0'} - - postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} - engines: {node: ^10 || ^12 || >=14} - - progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - - property-expr@2.0.6: - resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} - - read-package-up@12.0.0: - resolution: {integrity: sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw==} - engines: {node: '>=20'} - - read-pkg@10.1.0: - resolution: {integrity: sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==} - engines: {node: '>=20'} - - reflect-metadata@0.2.2: - resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - - regexp-match-indices@1.0.2: - resolution: {integrity: sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==} - - regexp-tree@0.1.27: - resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} - hasBin: true - - repeat-string@1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - rolldown@1.0.0-rc.12: - resolution: {integrity: sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - seed-random@2.2.0: - resolution: {integrity: sha512-34EQV6AAHQGhoc0tn/96a9Fsi6v2xdqe/dMUwljGRaFOzR3EgRmECvD0O8vi8X+/uQ50LGHfkNu/Eue5TPKZkQ==} - - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - sirv@3.0.2: - resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} - engines: {node: '>=18'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - 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==} - - stackframe@1.3.4: - resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} - - std-env@4.0.0: - resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==} - - string-argv@0.3.1: - resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} - engines: {node: '>=0.6.19'} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - 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'} - - tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - tiny-case@1.0.3: - resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} - - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@1.0.4: - resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} - engines: {node: '>=18'} - - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - - tinypool@2.1.0: - resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} - engines: {node: ^20.0.0 || >=22.0.0} - - toposort@2.0.2: - resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} - - totalist@3.0.1: - resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} - engines: {node: '>=6'} - - ts-dedent@2.2.0: - resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} - engines: {node: '>=6.10'} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - tsx@4.21.0: - resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} - engines: {node: '>=18.0.0'} - hasBin: true - - type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - - type-fest@5.5.0: - resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==} - engines: {node: '>=20'} - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@7.18.2: - resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - - unicorn-magic@0.4.0: - resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} - engines: {node: '>=20'} - - upper-case-first@2.0.2: - resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} - - util-arity@1.1.0: - resolution: {integrity: sha512-kkyIsXKwemfSy8ZEoaIz06ApApnWsk5hQO0vLjZS6UkBiGiW++Jsyb8vSBoc0WKlffGoGs5yYy/j5pp8zckrFA==} - - validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - - vite-plus@0.1.14: - resolution: {integrity: sha512-p4pWlpZZNiEsHxPWNdeIU9iuPix3ydm3ficb0dXPggoyIkdotfXtvn2NPX9KwfiQImU72EVEs4+VYBZYNcUYrw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - vite@8.0.3: - resolution: {integrity: sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.0 - esbuild: ^0.27.0 - jiti: '>=1.21.0' - less: ^4.0.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - '@vitejs/devtools': - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - ws@8.20.0: - resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xmlbuilder@15.1.1: - resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} - engines: {node: '>=8.0'} - - yaml@2.8.3: - resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} - engines: {node: '>= 14.6'} - hasBin: true - - yup@1.7.1: - resolution: {integrity: sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==} - -snapshots: - - '@babel/code-frame@7.29.0': - dependencies: - '@babel/helper-validator-identifier': 7.28.5 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/helper-validator-identifier@7.28.5': {} - - '@colors/colors@1.5.0': - optional: true - - '@cucumber/ci-environment@13.0.0': {} - - '@cucumber/cucumber-expressions@19.0.0': - dependencies: - regexp-match-indices: 1.0.2 - - '@cucumber/cucumber@12.7.0': - dependencies: - '@cucumber/ci-environment': 13.0.0 - '@cucumber/cucumber-expressions': 19.0.0 - '@cucumber/gherkin': 38.0.0 - '@cucumber/gherkin-streams': 6.0.0(@cucumber/gherkin@38.0.0)(@cucumber/message-streams@4.0.1(@cucumber/messages@32.0.1))(@cucumber/messages@32.0.1) - '@cucumber/gherkin-utils': 11.0.0 - '@cucumber/html-formatter': 23.0.0(@cucumber/messages@32.0.1) - '@cucumber/junit-xml-formatter': 0.9.0(@cucumber/messages@32.0.1) - '@cucumber/message-streams': 4.0.1(@cucumber/messages@32.0.1) - '@cucumber/messages': 32.0.1 - '@cucumber/pretty-formatter': 1.0.1(@cucumber/cucumber@12.7.0)(@cucumber/messages@32.0.1) - '@cucumber/tag-expressions': 9.1.0 - assertion-error-formatter: 3.0.0 - capital-case: 1.0.4 - chalk: 4.1.2 - cli-table3: 0.6.5 - commander: 14.0.3 - debug: 4.4.3(supports-color@8.1.1) - error-stack-parser: 2.1.4 - figures: 3.2.0 - glob: 13.0.6 - has-ansi: 4.0.1 - indent-string: 4.0.0 - is-installed-globally: 0.4.0 - is-stream: 2.0.1 - knuth-shuffle-seeded: 1.0.6 - lodash.merge: 4.6.2 - lodash.mergewith: 4.6.2 - luxon: 3.7.2 - mime: 3.0.0 - mkdirp: 3.0.1 - mz: 2.7.0 - progress: 2.0.3 - read-package-up: 12.0.0 - semver: 7.7.4 - string-argv: 0.3.1 - supports-color: 8.1.1 - type-fest: 4.41.0 - util-arity: 1.1.0 - yaml: 2.8.3 - yup: 1.7.1 - - '@cucumber/gherkin-streams@6.0.0(@cucumber/gherkin@38.0.0)(@cucumber/message-streams@4.0.1(@cucumber/messages@32.0.1))(@cucumber/messages@32.0.1)': - dependencies: - '@cucumber/gherkin': 38.0.0 - '@cucumber/message-streams': 4.0.1(@cucumber/messages@32.0.1) - '@cucumber/messages': 32.0.1 - commander: 14.0.0 - source-map-support: 0.5.21 - - '@cucumber/gherkin-utils@11.0.0': - dependencies: - '@cucumber/gherkin': 38.0.0 - '@cucumber/messages': 32.0.1 - '@teppeis/multimaps': 3.0.0 - commander: 14.0.2 - source-map-support: 0.5.21 - - '@cucumber/gherkin@38.0.0': - dependencies: - '@cucumber/messages': 32.0.1 - - '@cucumber/html-formatter@23.0.0(@cucumber/messages@32.0.1)': - dependencies: - '@cucumber/messages': 32.0.1 - - '@cucumber/junit-xml-formatter@0.9.0(@cucumber/messages@32.0.1)': - dependencies: - '@cucumber/messages': 32.0.1 - '@cucumber/query': 14.7.0(@cucumber/messages@32.0.1) - '@teppeis/multimaps': 3.0.0 - luxon: 3.7.2 - xmlbuilder: 15.1.1 - - '@cucumber/message-streams@4.0.1(@cucumber/messages@32.0.1)': - dependencies: - '@cucumber/messages': 32.0.1 - - '@cucumber/messages@32.0.1': - dependencies: - class-transformer: 0.5.1 - reflect-metadata: 0.2.2 - - '@cucumber/pretty-formatter@1.0.1(@cucumber/cucumber@12.7.0)(@cucumber/messages@32.0.1)': - dependencies: - '@cucumber/cucumber': 12.7.0 - '@cucumber/messages': 32.0.1 - ansi-styles: 5.2.0 - cli-table3: 0.6.5 - figures: 3.2.0 - ts-dedent: 2.2.0 - - '@cucumber/query@14.7.0(@cucumber/messages@32.0.1)': - dependencies: - '@cucumber/messages': 32.0.1 - '@teppeis/multimaps': 3.0.0 - lodash.sortby: 4.7.0 - - '@cucumber/tag-expressions@9.1.0': {} - - '@emnapi/core@1.9.1': - dependencies: - '@emnapi/wasi-threads': 1.2.0 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.9.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.2.0': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild/aix-ppc64@0.27.4': - optional: true - - '@esbuild/android-arm64@0.27.4': - optional: true - - '@esbuild/android-arm@0.27.4': - optional: true - - '@esbuild/android-x64@0.27.4': - optional: true - - '@esbuild/darwin-arm64@0.27.4': - optional: true - - '@esbuild/darwin-x64@0.27.4': - optional: true - - '@esbuild/freebsd-arm64@0.27.4': - optional: true - - '@esbuild/freebsd-x64@0.27.4': - optional: true - - '@esbuild/linux-arm64@0.27.4': - optional: true - - '@esbuild/linux-arm@0.27.4': - optional: true - - '@esbuild/linux-ia32@0.27.4': - optional: true - - '@esbuild/linux-loong64@0.27.4': - optional: true - - '@esbuild/linux-mips64el@0.27.4': - optional: true - - '@esbuild/linux-ppc64@0.27.4': - optional: true - - '@esbuild/linux-riscv64@0.27.4': - optional: true - - '@esbuild/linux-s390x@0.27.4': - optional: true - - '@esbuild/linux-x64@0.27.4': - optional: true - - '@esbuild/netbsd-arm64@0.27.4': - optional: true - - '@esbuild/netbsd-x64@0.27.4': - optional: true - - '@esbuild/openbsd-arm64@0.27.4': - optional: true - - '@esbuild/openbsd-x64@0.27.4': - optional: true - - '@esbuild/openharmony-arm64@0.27.4': - optional: true - - '@esbuild/sunos-x64@0.27.4': - optional: true - - '@esbuild/win32-arm64@0.27.4': - optional: true - - '@esbuild/win32-ia32@0.27.4': - optional: true - - '@esbuild/win32-x64@0.27.4': - optional: true - - '@napi-rs/wasm-runtime@1.1.1': - dependencies: - '@emnapi/core': 1.9.1 - '@emnapi/runtime': 1.9.1 - '@tybys/wasm-util': 0.10.1 - optional: true - - '@oxc-project/runtime@0.121.0': {} - - '@oxc-project/types@0.122.0': {} - - '@oxfmt/binding-android-arm-eabi@0.42.0': - optional: true - - '@oxfmt/binding-android-arm64@0.42.0': - optional: true - - '@oxfmt/binding-darwin-arm64@0.42.0': - optional: true - - '@oxfmt/binding-darwin-x64@0.42.0': - optional: true - - '@oxfmt/binding-freebsd-x64@0.42.0': - optional: true - - '@oxfmt/binding-linux-arm-gnueabihf@0.42.0': - optional: true - - '@oxfmt/binding-linux-arm-musleabihf@0.42.0': - optional: true - - '@oxfmt/binding-linux-arm64-gnu@0.42.0': - optional: true - - '@oxfmt/binding-linux-arm64-musl@0.42.0': - optional: true - - '@oxfmt/binding-linux-ppc64-gnu@0.42.0': - optional: true - - '@oxfmt/binding-linux-riscv64-gnu@0.42.0': - optional: true - - '@oxfmt/binding-linux-riscv64-musl@0.42.0': - optional: true - - '@oxfmt/binding-linux-s390x-gnu@0.42.0': - optional: true - - '@oxfmt/binding-linux-x64-gnu@0.42.0': - optional: true - - '@oxfmt/binding-linux-x64-musl@0.42.0': - optional: true - - '@oxfmt/binding-openharmony-arm64@0.42.0': - optional: true - - '@oxfmt/binding-win32-arm64-msvc@0.42.0': - optional: true - - '@oxfmt/binding-win32-ia32-msvc@0.42.0': - optional: true - - '@oxfmt/binding-win32-x64-msvc@0.42.0': - optional: true - - '@oxlint-tsgolint/darwin-arm64@0.17.3': - optional: true - - '@oxlint-tsgolint/darwin-x64@0.17.3': - optional: true - - '@oxlint-tsgolint/linux-arm64@0.17.3': - optional: true - - '@oxlint-tsgolint/linux-x64@0.17.3': - optional: true - - '@oxlint-tsgolint/win32-arm64@0.17.3': - optional: true - - '@oxlint-tsgolint/win32-x64@0.17.3': - optional: true - - '@oxlint/binding-android-arm-eabi@1.57.0': - optional: true - - '@oxlint/binding-android-arm64@1.57.0': - optional: true - - '@oxlint/binding-darwin-arm64@1.57.0': - optional: true - - '@oxlint/binding-darwin-x64@1.57.0': - optional: true - - '@oxlint/binding-freebsd-x64@1.57.0': - optional: true - - '@oxlint/binding-linux-arm-gnueabihf@1.57.0': - optional: true - - '@oxlint/binding-linux-arm-musleabihf@1.57.0': - optional: true - - '@oxlint/binding-linux-arm64-gnu@1.57.0': - optional: true - - '@oxlint/binding-linux-arm64-musl@1.57.0': - optional: true - - '@oxlint/binding-linux-ppc64-gnu@1.57.0': - optional: true - - '@oxlint/binding-linux-riscv64-gnu@1.57.0': - optional: true - - '@oxlint/binding-linux-riscv64-musl@1.57.0': - optional: true - - '@oxlint/binding-linux-s390x-gnu@1.57.0': - optional: true - - '@oxlint/binding-linux-x64-gnu@1.57.0': - optional: true - - '@oxlint/binding-linux-x64-musl@1.57.0': - optional: true - - '@oxlint/binding-openharmony-arm64@1.57.0': - optional: true - - '@oxlint/binding-win32-arm64-msvc@1.57.0': - optional: true - - '@oxlint/binding-win32-ia32-msvc@1.57.0': - optional: true - - '@oxlint/binding-win32-x64-msvc@1.57.0': - optional: true - - '@playwright/test@1.51.1': - dependencies: - playwright: 1.51.1 - - '@polka/url@1.0.0-next.29': {} - - '@rolldown/binding-android-arm64@1.0.0-rc.12': - optional: true - - '@rolldown/binding-darwin-arm64@1.0.0-rc.12': - optional: true - - '@rolldown/binding-darwin-x64@1.0.0-rc.12': - optional: true - - '@rolldown/binding-freebsd-x64@1.0.0-rc.12': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.12': - optional: true - - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12': - optional: true - - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.12': - optional: true - - '@rolldown/binding-linux-x64-musl@1.0.0-rc.12': - optional: true - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.12': - optional: true - - '@rolldown/binding-wasm32-wasi@1.0.0-rc.12': - dependencies: - '@napi-rs/wasm-runtime': 1.1.1 - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.12': - optional: true - - '@rolldown/pluginutils@1.0.0-rc.12': {} - - '@standard-schema/spec@1.1.0': {} - - '@teppeis/multimaps@3.0.0': {} - - '@tybys/wasm-util@0.10.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@types/chai@5.2.3': - dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 - - '@types/deep-eql@4.0.2': {} - - '@types/node@25.5.0': - dependencies: - undici-types: 7.18.2 - - '@types/normalize-package-data@2.4.4': {} - - '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)': - dependencies: - '@oxc-project/runtime': 0.121.0 - '@oxc-project/types': 0.122.0 - lightningcss: 1.32.0 - postcss: 8.5.8 - optionalDependencies: - '@types/node': 25.5.0 - esbuild: 0.27.4 - fsevents: 2.3.3 - tsx: 4.21.0 - typescript: 5.9.3 - yaml: 2.8.3 - - '@voidzero-dev/vite-plus-darwin-arm64@0.1.14': - optional: true - - '@voidzero-dev/vite-plus-darwin-x64@0.1.14': - optional: true - - '@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.14': - optional: true - - '@voidzero-dev/vite-plus-linux-arm64-musl@0.1.14': - optional: true - - '@voidzero-dev/vite-plus-linux-x64-gnu@0.1.14': - optional: true - - '@voidzero-dev/vite-plus-linux-x64-musl@0.1.14': - optional: true - - '@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3)': - dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@voidzero-dev/vite-plus-core': 0.1.14(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) - es-module-lexer: 1.7.0 - obug: 2.1.1 - pixelmatch: 7.1.0 - pngjs: 7.0.0 - sirv: 3.0.2 - std-env: 4.0.0 - tinybench: 2.9.0 - tinyexec: 1.0.4 - tinyglobby: 0.2.15 - vite: 8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3) - ws: 8.20.0 - optionalDependencies: - '@types/node': 25.5.0 - transitivePeerDependencies: - - '@arethetypeswrong/core' - - '@tsdown/css' - - '@tsdown/exe' - - '@vitejs/devtools' - - bufferutil - - esbuild - - jiti - - less - - publint - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - typescript - - unplugin-unused - - utf-8-validate - - yaml - - '@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.14': - optional: true - - '@voidzero-dev/vite-plus-win32-x64-msvc@0.1.14': - optional: true - - ansi-regex@4.1.1: {} - - ansi-regex@5.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - - any-promise@1.3.0: {} - - assertion-error-formatter@3.0.0: - dependencies: - diff: 4.0.4 - pad-right: 0.2.2 - repeat-string: 1.6.1 - - assertion-error@2.0.1: {} - - balanced-match@4.0.4: {} - - brace-expansion@5.0.5: - dependencies: - balanced-match: 4.0.4 - - buffer-from@1.1.2: {} - - cac@7.0.0: {} - - capital-case@1.0.4: - dependencies: - no-case: 3.0.4 - tslib: 2.8.1 - upper-case-first: 2.0.2 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - class-transformer@0.5.1: {} - - cli-table3@0.6.5: - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - commander@14.0.0: {} - - commander@14.0.2: {} - - commander@14.0.3: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - debug@4.4.3(supports-color@8.1.1): - dependencies: - ms: 2.1.3 - optionalDependencies: - supports-color: 8.1.1 - - detect-libc@2.1.2: {} - - diff@4.0.4: {} - - emoji-regex@8.0.0: {} - - error-stack-parser@2.1.4: - dependencies: - stackframe: 1.3.4 - - es-module-lexer@1.7.0: {} - - esbuild@0.27.4: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.4 - '@esbuild/android-arm': 0.27.4 - '@esbuild/android-arm64': 0.27.4 - '@esbuild/android-x64': 0.27.4 - '@esbuild/darwin-arm64': 0.27.4 - '@esbuild/darwin-x64': 0.27.4 - '@esbuild/freebsd-arm64': 0.27.4 - '@esbuild/freebsd-x64': 0.27.4 - '@esbuild/linux-arm': 0.27.4 - '@esbuild/linux-arm64': 0.27.4 - '@esbuild/linux-ia32': 0.27.4 - '@esbuild/linux-loong64': 0.27.4 - '@esbuild/linux-mips64el': 0.27.4 - '@esbuild/linux-ppc64': 0.27.4 - '@esbuild/linux-riscv64': 0.27.4 - '@esbuild/linux-s390x': 0.27.4 - '@esbuild/linux-x64': 0.27.4 - '@esbuild/netbsd-arm64': 0.27.4 - '@esbuild/netbsd-x64': 0.27.4 - '@esbuild/openbsd-arm64': 0.27.4 - '@esbuild/openbsd-x64': 0.27.4 - '@esbuild/openharmony-arm64': 0.27.4 - '@esbuild/sunos-x64': 0.27.4 - '@esbuild/win32-arm64': 0.27.4 - '@esbuild/win32-ia32': 0.27.4 - '@esbuild/win32-x64': 0.27.4 - - escape-string-regexp@1.0.5: {} - - fdir@6.5.0(picomatch@4.0.4): - optionalDependencies: - picomatch: 4.0.4 - - figures@3.2.0: - dependencies: - escape-string-regexp: 1.0.5 - - find-up-simple@1.0.1: {} - - fsevents@2.3.2: - optional: true - - fsevents@2.3.3: - optional: true - - get-tsconfig@4.13.7: - dependencies: - resolve-pkg-maps: 1.0.0 - - glob@13.0.6: - dependencies: - minimatch: 10.2.4 - minipass: 7.1.3 - path-scurry: 2.0.2 - - global-dirs@3.0.1: - dependencies: - ini: 2.0.0 - - has-ansi@4.0.1: - dependencies: - ansi-regex: 4.1.1 - - has-flag@4.0.0: {} - - hosted-git-info@9.0.2: - dependencies: - lru-cache: 11.2.7 - - indent-string@4.0.0: {} - - index-to-position@1.2.0: {} - - ini@2.0.0: {} - - is-fullwidth-code-point@3.0.0: {} - - is-installed-globally@0.4.0: - dependencies: - global-dirs: 3.0.1 - is-path-inside: 3.0.3 - - is-path-inside@3.0.3: {} - - is-stream@2.0.1: {} - - isexe@2.0.0: {} - - js-tokens@4.0.0: {} - - knuth-shuffle-seeded@1.0.6: - dependencies: - seed-random: 2.2.0 - - lightningcss-android-arm64@1.32.0: - optional: true - - lightningcss-darwin-arm64@1.32.0: - optional: true - - lightningcss-darwin-x64@1.32.0: - optional: true - - lightningcss-freebsd-x64@1.32.0: - optional: true - - lightningcss-linux-arm-gnueabihf@1.32.0: - optional: true - - lightningcss-linux-arm64-gnu@1.32.0: - optional: true - - lightningcss-linux-arm64-musl@1.32.0: - optional: true - - lightningcss-linux-x64-gnu@1.32.0: - optional: true - - lightningcss-linux-x64-musl@1.32.0: - optional: true - - lightningcss-win32-arm64-msvc@1.32.0: - optional: true - - lightningcss-win32-x64-msvc@1.32.0: - optional: true - - lightningcss@1.32.0: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 - - lodash.merge@4.6.2: {} - - lodash.mergewith@4.6.2: {} - - lodash.sortby@4.7.0: {} - - lower-case@2.0.2: - dependencies: - tslib: 2.8.1 - - lru-cache@11.2.7: {} - - luxon@3.7.2: {} - - mime@3.0.0: {} - - minimatch@10.2.4: - dependencies: - brace-expansion: 5.0.5 - - minipass@7.1.3: {} - - mkdirp@3.0.1: {} - - mrmime@2.0.1: {} - - ms@2.1.3: {} - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - nanoid@3.3.11: {} - - no-case@3.0.4: - dependencies: - lower-case: 2.0.2 - tslib: 2.8.1 - - normalize-package-data@8.0.0: - dependencies: - hosted-git-info: 9.0.2 - semver: 7.7.4 - validate-npm-package-license: 3.0.4 - - object-assign@4.1.1: {} - - obug@2.1.1: {} - - oxfmt@0.42.0: - dependencies: - tinypool: 2.1.0 - optionalDependencies: - '@oxfmt/binding-android-arm-eabi': 0.42.0 - '@oxfmt/binding-android-arm64': 0.42.0 - '@oxfmt/binding-darwin-arm64': 0.42.0 - '@oxfmt/binding-darwin-x64': 0.42.0 - '@oxfmt/binding-freebsd-x64': 0.42.0 - '@oxfmt/binding-linux-arm-gnueabihf': 0.42.0 - '@oxfmt/binding-linux-arm-musleabihf': 0.42.0 - '@oxfmt/binding-linux-arm64-gnu': 0.42.0 - '@oxfmt/binding-linux-arm64-musl': 0.42.0 - '@oxfmt/binding-linux-ppc64-gnu': 0.42.0 - '@oxfmt/binding-linux-riscv64-gnu': 0.42.0 - '@oxfmt/binding-linux-riscv64-musl': 0.42.0 - '@oxfmt/binding-linux-s390x-gnu': 0.42.0 - '@oxfmt/binding-linux-x64-gnu': 0.42.0 - '@oxfmt/binding-linux-x64-musl': 0.42.0 - '@oxfmt/binding-openharmony-arm64': 0.42.0 - '@oxfmt/binding-win32-arm64-msvc': 0.42.0 - '@oxfmt/binding-win32-ia32-msvc': 0.42.0 - '@oxfmt/binding-win32-x64-msvc': 0.42.0 - - oxlint-tsgolint@0.17.3: - optionalDependencies: - '@oxlint-tsgolint/darwin-arm64': 0.17.3 - '@oxlint-tsgolint/darwin-x64': 0.17.3 - '@oxlint-tsgolint/linux-arm64': 0.17.3 - '@oxlint-tsgolint/linux-x64': 0.17.3 - '@oxlint-tsgolint/win32-arm64': 0.17.3 - '@oxlint-tsgolint/win32-x64': 0.17.3 - - oxlint@1.57.0(oxlint-tsgolint@0.17.3): - optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.57.0 - '@oxlint/binding-android-arm64': 1.57.0 - '@oxlint/binding-darwin-arm64': 1.57.0 - '@oxlint/binding-darwin-x64': 1.57.0 - '@oxlint/binding-freebsd-x64': 1.57.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.57.0 - '@oxlint/binding-linux-arm-musleabihf': 1.57.0 - '@oxlint/binding-linux-arm64-gnu': 1.57.0 - '@oxlint/binding-linux-arm64-musl': 1.57.0 - '@oxlint/binding-linux-ppc64-gnu': 1.57.0 - '@oxlint/binding-linux-riscv64-gnu': 1.57.0 - '@oxlint/binding-linux-riscv64-musl': 1.57.0 - '@oxlint/binding-linux-s390x-gnu': 1.57.0 - '@oxlint/binding-linux-x64-gnu': 1.57.0 - '@oxlint/binding-linux-x64-musl': 1.57.0 - '@oxlint/binding-openharmony-arm64': 1.57.0 - '@oxlint/binding-win32-arm64-msvc': 1.57.0 - '@oxlint/binding-win32-ia32-msvc': 1.57.0 - '@oxlint/binding-win32-x64-msvc': 1.57.0 - oxlint-tsgolint: 0.17.3 - - pad-right@0.2.2: - dependencies: - repeat-string: 1.6.1 - - parse-json@8.3.0: - dependencies: - '@babel/code-frame': 7.29.0 - index-to-position: 1.2.0 - type-fest: 4.41.0 - - path-key@3.1.1: {} - - path-scurry@2.0.2: - dependencies: - lru-cache: 11.2.7 - minipass: 7.1.3 - - picocolors@1.1.1: {} - - picomatch@4.0.4: {} - - pixelmatch@7.1.0: - dependencies: - pngjs: 7.0.0 - - playwright-core@1.51.1: {} - - playwright@1.51.1: - dependencies: - playwright-core: 1.51.1 - optionalDependencies: - fsevents: 2.3.2 - - pngjs@7.0.0: {} - - postcss@8.5.8: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - progress@2.0.3: {} - - property-expr@2.0.6: {} - - read-package-up@12.0.0: - dependencies: - find-up-simple: 1.0.1 - read-pkg: 10.1.0 - type-fest: 5.5.0 - - read-pkg@10.1.0: - dependencies: - '@types/normalize-package-data': 2.4.4 - normalize-package-data: 8.0.0 - parse-json: 8.3.0 - type-fest: 5.5.0 - unicorn-magic: 0.4.0 - - reflect-metadata@0.2.2: {} - - regexp-match-indices@1.0.2: - dependencies: - regexp-tree: 0.1.27 - - regexp-tree@0.1.27: {} - - repeat-string@1.6.1: {} - - resolve-pkg-maps@1.0.0: {} - - rolldown@1.0.0-rc.12: - dependencies: - '@oxc-project/types': 0.122.0 - '@rolldown/pluginutils': 1.0.0-rc.12 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.12 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.12 - '@rolldown/binding-darwin-x64': 1.0.0-rc.12 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.12 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.12 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.12 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.12 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.12 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.12 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.12 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.12 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.12 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.12 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.12 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.12 - - seed-random@2.2.0: {} - - semver@7.7.4: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - sirv@3.0.2: - dependencies: - '@polka/url': 1.0.0-next.29 - mrmime: 2.0.1 - totalist: 3.0.1 - - source-map-js@1.2.1: {} - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - 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: {} - - stackframe@1.3.4: {} - - std-env@4.0.0: {} - - string-argv@0.3.1: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 - - tagged-tag@1.0.0: {} - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - tiny-case@1.0.3: {} - - tinybench@2.9.0: {} - - tinyexec@1.0.4: {} - - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - - tinypool@2.1.0: {} - - toposort@2.0.2: {} - - totalist@3.0.1: {} - - ts-dedent@2.2.0: {} - - tslib@2.8.1: {} - - tsx@4.21.0: - dependencies: - esbuild: 0.27.4 - get-tsconfig: 4.13.7 - optionalDependencies: - fsevents: 2.3.3 - - type-fest@2.19.0: {} - - type-fest@4.41.0: {} - - type-fest@5.5.0: - dependencies: - tagged-tag: 1.0.0 - - typescript@5.9.3: {} - - undici-types@7.18.2: {} - - unicorn-magic@0.4.0: {} - - upper-case-first@2.0.2: - dependencies: - tslib: 2.8.1 - - util-arity@1.1.0: {} - - validate-npm-package-license@3.0.4: - dependencies: - spdx-correct: 3.2.0 - spdx-expression-parse: 3.0.1 - - vite-plus@0.1.14(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3): - dependencies: - '@oxc-project/types': 0.122.0 - '@voidzero-dev/vite-plus-core': 0.1.14(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) - '@voidzero-dev/vite-plus-test': 0.1.14(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3) - cac: 7.0.0 - cross-spawn: 7.0.6 - oxfmt: 0.42.0 - oxlint: 1.57.0(oxlint-tsgolint@0.17.3) - oxlint-tsgolint: 0.17.3 - picocolors: 1.1.1 - optionalDependencies: - '@voidzero-dev/vite-plus-darwin-arm64': 0.1.14 - '@voidzero-dev/vite-plus-darwin-x64': 0.1.14 - '@voidzero-dev/vite-plus-linux-arm64-gnu': 0.1.14 - '@voidzero-dev/vite-plus-linux-arm64-musl': 0.1.14 - '@voidzero-dev/vite-plus-linux-x64-gnu': 0.1.14 - '@voidzero-dev/vite-plus-linux-x64-musl': 0.1.14 - '@voidzero-dev/vite-plus-win32-arm64-msvc': 0.1.14 - '@voidzero-dev/vite-plus-win32-x64-msvc': 0.1.14 - transitivePeerDependencies: - - '@arethetypeswrong/core' - - '@edge-runtime/vm' - - '@opentelemetry/api' - - '@tsdown/css' - - '@tsdown/exe' - - '@types/node' - - '@vitejs/devtools' - - '@vitest/ui' - - bufferutil - - esbuild - - happy-dom - - jiti - - jsdom - - less - - publint - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - typescript - - unplugin-unused - - utf-8-validate - - vite - - yaml - - vite@8.0.3(@types/node@25.5.0)(esbuild@0.27.4)(tsx@4.21.0)(yaml@2.8.3): - dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.8 - rolldown: 1.0.0-rc.12 - tinyglobby: 0.2.15 - optionalDependencies: - '@types/node': 25.5.0 - esbuild: 0.27.4 - fsevents: 2.3.3 - tsx: 4.21.0 - yaml: 2.8.3 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - ws@8.20.0: {} - - xmlbuilder@15.1.1: {} - - yaml@2.8.3: {} - - yup@1.7.1: - dependencies: - property-expr: 2.0.6 - tiny-case: 1.0.3 - toposort: 2.0.2 - type-fest: 2.19.0 diff --git a/package.json b/package.json new file mode 100644 index 0000000000..07f1e16153 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "dify", + "private": true, + "engines": { + "node": "^22.22.1" + }, + "packageManager": "pnpm@10.33.0", + "devDependencies": { + "taze": "catalog:" + } +} diff --git a/web/pnpm-lock.yaml b/pnpm-lock.yaml similarity index 77% rename from web/pnpm-lock.yaml rename to pnpm-lock.yaml index cd1a8a8556..b6c234d8ad 100644 --- a/web/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,561 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +catalogs: + default: + '@amplitude/analytics-browser': + specifier: 2.38.0 + version: 2.38.0 + '@amplitude/plugin-session-replay-browser': + specifier: 1.27.5 + version: 1.27.5 + '@antfu/eslint-config': + specifier: 7.7.3 + version: 7.7.3 + '@base-ui/react': + specifier: 1.3.0 + version: 1.3.0 + '@chromatic-com/storybook': + specifier: 5.1.1 + version: 5.1.1 + '@cucumber/cucumber': + specifier: 12.7.0 + version: 12.7.0 + '@egoist/tailwindcss-icons': + specifier: 1.9.2 + version: 1.9.2 + '@emoji-mart/data': + specifier: 1.2.1 + version: 1.2.1 + '@eslint-react/eslint-plugin': + specifier: 3.0.0 + version: 3.0.0 + '@eslint/js': + specifier: ^10.0.1 + version: 10.0.1 + '@floating-ui/react': + specifier: 0.27.19 + version: 0.27.19 + '@formatjs/intl-localematcher': + specifier: 0.8.2 + version: 0.8.2 + '@headlessui/react': + specifier: 2.2.9 + version: 2.2.9 + '@heroicons/react': + specifier: 2.2.0 + version: 2.2.0 + '@hono/node-server': + specifier: 1.19.11 + version: 1.19.11 + '@iconify-json/heroicons': + specifier: 1.2.3 + version: 1.2.3 + '@iconify-json/ri': + specifier: 1.2.10 + version: 1.2.10 + '@lexical/link': + specifier: 0.42.0 + version: 0.42.0 + '@lexical/list': + specifier: 0.42.0 + version: 0.42.0 + '@lexical/react': + specifier: 0.42.0 + version: 0.42.0 + '@lexical/selection': + specifier: 0.42.0 + version: 0.42.0 + '@lexical/text': + specifier: 0.42.0 + version: 0.42.0 + '@lexical/utils': + specifier: 0.42.0 + version: 0.42.0 + '@mdx-js/loader': + specifier: 3.1.1 + version: 3.1.1 + '@mdx-js/react': + specifier: 3.1.1 + version: 3.1.1 + '@mdx-js/rollup': + specifier: 3.1.1 + version: 3.1.1 + '@monaco-editor/react': + specifier: 4.7.0 + version: 4.7.0 + '@next/eslint-plugin-next': + specifier: 16.2.1 + version: 16.2.1 + '@next/mdx': + specifier: 16.2.1 + version: 16.2.1 + '@orpc/client': + specifier: 1.13.13 + version: 1.13.13 + '@orpc/contract': + specifier: 1.13.13 + version: 1.13.13 + '@orpc/openapi-client': + specifier: 1.13.13 + version: 1.13.13 + '@orpc/tanstack-query': + specifier: 1.13.13 + version: 1.13.13 + '@playwright/test': + specifier: 1.58.2 + version: 1.58.2 + '@remixicon/react': + specifier: 4.9.0 + version: 4.9.0 + '@rgrove/parse-xml': + specifier: 4.2.0 + version: 4.2.0 + '@sentry/react': + specifier: 10.46.0 + version: 10.46.0 + '@storybook/addon-docs': + specifier: 10.3.3 + version: 10.3.3 + '@storybook/addon-links': + specifier: 10.3.3 + version: 10.3.3 + '@storybook/addon-onboarding': + specifier: 10.3.3 + version: 10.3.3 + '@storybook/addon-themes': + specifier: 10.3.3 + version: 10.3.3 + '@storybook/nextjs-vite': + specifier: 10.3.3 + version: 10.3.3 + '@storybook/react': + specifier: 10.3.3 + version: 10.3.3 + '@streamdown/math': + specifier: 1.0.2 + version: 1.0.2 + '@svgdotjs/svg.js': + specifier: 3.2.5 + version: 3.2.5 + '@t3-oss/env-nextjs': + specifier: 0.13.11 + version: 0.13.11 + '@tailwindcss/typography': + specifier: 0.5.19 + version: 0.5.19 + '@tanstack/eslint-plugin-query': + specifier: 5.95.2 + version: 5.95.2 + '@tanstack/react-devtools': + specifier: 0.10.0 + version: 0.10.0 + '@tanstack/react-form': + specifier: 1.28.5 + version: 1.28.5 + '@tanstack/react-form-devtools': + specifier: 0.2.19 + version: 0.2.19 + '@tanstack/react-query': + specifier: 5.95.2 + version: 5.95.2 + '@tanstack/react-query-devtools': + specifier: 5.95.2 + version: 5.95.2 + '@testing-library/dom': + specifier: 10.4.1 + version: 10.4.1 + '@testing-library/jest-dom': + specifier: 6.9.1 + version: 6.9.1 + '@testing-library/react': + specifier: 16.3.2 + version: 16.3.2 + '@testing-library/user-event': + specifier: 14.6.1 + version: 14.6.1 + '@tsslint/cli': + specifier: 3.0.2 + version: 3.0.2 + '@tsslint/compat-eslint': + specifier: 3.0.2 + version: 3.0.2 + '@tsslint/config': + specifier: 3.0.2 + version: 3.0.2 + '@types/js-cookie': + specifier: 3.0.6 + version: 3.0.6 + '@types/js-yaml': + specifier: 4.0.9 + version: 4.0.9 + '@types/negotiator': + specifier: 0.6.4 + version: 0.6.4 + '@types/node': + specifier: 25.5.0 + version: 25.5.0 + '@types/postcss-js': + specifier: 4.1.0 + version: 4.1.0 + '@types/qs': + specifier: 6.15.0 + version: 6.15.0 + '@types/react': + specifier: 19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: 19.2.3 + version: 19.2.3 + '@types/react-syntax-highlighter': + specifier: 15.5.13 + version: 15.5.13 + '@types/react-window': + specifier: 1.8.8 + version: 1.8.8 + '@types/sortablejs': + specifier: 1.15.9 + version: 1.15.9 + '@typescript-eslint/eslint-plugin': + specifier: ^8.57.2 + version: 8.57.2 + '@typescript-eslint/parser': + specifier: 8.57.2 + version: 8.57.2 + '@typescript/native-preview': + specifier: 7.0.0-dev.20260329.1 + version: 7.0.0-dev.20260329.1 + '@vitejs/plugin-react': + specifier: 6.0.1 + version: 6.0.1 + '@vitejs/plugin-rsc': + specifier: 0.5.21 + version: 0.5.21 + '@vitest/coverage-v8': + specifier: 4.1.2 + version: 4.1.2 + abcjs: + specifier: 6.6.2 + version: 6.6.2 + agentation: + specifier: 3.0.2 + version: 3.0.2 + ahooks: + specifier: 3.9.7 + version: 3.9.7 + autoprefixer: + specifier: 10.4.27 + version: 10.4.27 + class-variance-authority: + specifier: 0.7.1 + version: 0.7.1 + clsx: + specifier: 2.1.1 + version: 2.1.1 + cmdk: + specifier: 1.1.1 + version: 1.1.1 + code-inspector-plugin: + specifier: 1.4.5 + version: 1.4.5 + copy-to-clipboard: + specifier: 3.3.3 + version: 3.3.3 + cron-parser: + specifier: 5.5.0 + version: 5.5.0 + dayjs: + specifier: 1.11.20 + version: 1.11.20 + decimal.js: + specifier: 10.6.0 + version: 10.6.0 + dompurify: + specifier: 3.3.3 + version: 3.3.3 + echarts: + specifier: 6.0.0 + version: 6.0.0 + echarts-for-react: + specifier: 3.0.6 + version: 3.0.6 + elkjs: + specifier: 0.11.1 + version: 0.11.1 + embla-carousel-autoplay: + specifier: 8.6.0 + version: 8.6.0 + embla-carousel-react: + specifier: 8.6.0 + version: 8.6.0 + emoji-mart: + specifier: 5.6.0 + version: 5.6.0 + es-toolkit: + specifier: 1.45.1 + version: 1.45.1 + eslint: + specifier: 10.1.0 + version: 10.1.0 + eslint-markdown: + specifier: 0.6.0 + version: 0.6.0 + eslint-plugin-better-tailwindcss: + specifier: 4.3.2 + version: 4.3.2 + eslint-plugin-hyoban: + specifier: 0.14.1 + version: 0.14.1 + eslint-plugin-markdown-preferences: + specifier: 0.40.3 + version: 0.40.3 + eslint-plugin-no-barrel-files: + specifier: 1.2.2 + version: 1.2.2 + eslint-plugin-react-hooks: + specifier: 7.0.1 + version: 7.0.1 + eslint-plugin-react-refresh: + specifier: 0.5.2 + version: 0.5.2 + eslint-plugin-sonarjs: + specifier: 4.0.2 + version: 4.0.2 + eslint-plugin-storybook: + specifier: 10.3.3 + version: 10.3.3 + fast-deep-equal: + specifier: 3.1.3 + version: 3.1.3 + foxact: + specifier: 0.3.0 + version: 0.3.0 + happy-dom: + specifier: 20.8.9 + version: 20.8.9 + hono: + specifier: 4.12.9 + version: 4.12.9 + html-entities: + specifier: 2.6.0 + version: 2.6.0 + html-to-image: + specifier: 1.11.13 + version: 1.11.13 + husky: + specifier: 9.1.7 + version: 9.1.7 + i18next: + specifier: 25.10.10 + version: 25.10.10 + i18next-resources-to-backend: + specifier: 1.2.1 + version: 1.2.1 + iconify-import-svg: + specifier: 0.1.2 + version: 0.1.2 + immer: + specifier: 11.1.4 + version: 11.1.4 + jotai: + specifier: 2.19.0 + version: 2.19.0 + js-audio-recorder: + specifier: 1.0.7 + version: 1.0.7 + js-cookie: + specifier: 3.0.5 + version: 3.0.5 + js-yaml: + specifier: 4.1.1 + version: 4.1.1 + jsonschema: + specifier: 1.5.0 + version: 1.5.0 + katex: + specifier: 0.16.44 + version: 0.16.44 + knip: + specifier: 6.1.0 + version: 6.1.0 + ky: + specifier: 1.14.3 + version: 1.14.3 + lamejs: + specifier: 1.2.1 + version: 1.2.1 + lexical: + specifier: 0.42.0 + version: 0.42.0 + lint-staged: + specifier: 16.4.0 + version: 16.4.0 + mermaid: + specifier: 11.13.0 + version: 11.13.0 + mime: + specifier: 4.1.0 + version: 4.1.0 + mitt: + specifier: 3.0.1 + version: 3.0.1 + negotiator: + specifier: 1.0.0 + version: 1.0.0 + next: + specifier: 16.2.1 + version: 16.2.1 + next-themes: + specifier: 0.4.6 + version: 0.4.6 + nuqs: + specifier: 2.8.9 + version: 2.8.9 + pinyin-pro: + specifier: 3.28.0 + version: 3.28.0 + postcss: + specifier: 8.5.8 + version: 8.5.8 + postcss-js: + specifier: 5.1.0 + version: 5.1.0 + qrcode.react: + specifier: 4.2.0 + version: 4.2.0 + qs: + specifier: 6.15.0 + version: 6.15.0 + react: + specifier: 19.2.4 + version: 19.2.4 + react-18-input-autosize: + specifier: 3.0.0 + version: 3.0.0 + react-dom: + specifier: 19.2.4 + version: 19.2.4 + react-easy-crop: + specifier: 5.5.7 + version: 5.5.7 + react-hotkeys-hook: + specifier: 5.2.4 + version: 5.2.4 + react-i18next: + specifier: 16.6.6 + version: 16.6.6 + react-multi-email: + specifier: 1.0.25 + version: 1.0.25 + react-papaparse: + specifier: 4.4.0 + version: 4.4.0 + react-pdf-highlighter: + specifier: 8.0.0-rc.0 + version: 8.0.0-rc.0 + react-server-dom-webpack: + specifier: 19.2.4 + version: 19.2.4 + react-sortablejs: + specifier: 6.1.4 + version: 6.1.4 + react-syntax-highlighter: + specifier: 15.6.6 + version: 15.6.6 + react-textarea-autosize: + specifier: 8.5.9 + version: 8.5.9 + react-window: + specifier: 1.8.11 + version: 1.8.11 + reactflow: + specifier: 11.11.4 + version: 11.11.4 + remark-breaks: + specifier: 4.0.0 + version: 4.0.0 + remark-directive: + specifier: 4.0.0 + version: 4.0.0 + sass: + specifier: 1.98.0 + version: 1.98.0 + scheduler: + specifier: 0.27.0 + version: 0.27.0 + sharp: + specifier: 0.34.5 + version: 0.34.5 + sortablejs: + specifier: 1.15.7 + version: 1.15.7 + std-semver: + specifier: 1.0.8 + version: 1.0.8 + storybook: + specifier: 10.3.3 + version: 10.3.3 + streamdown: + specifier: 2.5.0 + version: 2.5.0 + string-ts: + specifier: 2.3.1 + version: 2.3.1 + tailwind-merge: + specifier: 2.6.1 + version: 2.6.1 + tailwindcss: + specifier: 3.4.19 + version: 3.4.19 + taze: + specifier: 19.10.0 + version: 19.10.0 + tldts: + specifier: 7.0.27 + version: 7.0.27 + tsup: + specifier: ^8.5.1 + version: 8.5.1 + tsx: + specifier: 4.21.0 + version: 4.21.0 + typescript: + specifier: 5.9.3 + version: 5.9.3 + uglify-js: + specifier: 3.19.3 + version: 3.19.3 + unist-util-visit: + specifier: 5.1.0 + version: 5.1.0 + use-context-selector: + specifier: 2.0.0 + version: 2.0.0 + uuid: + specifier: 13.0.0 + version: 13.0.0 + vinext: + specifier: 0.0.38 + version: 0.0.38 + vite-plugin-inspect: + specifier: 12.0.0-beta.1 + version: 12.0.0-beta.1 + vite-plus: + specifier: 0.1.14 + version: 0.1.14 + vitest-canvas-mock: + specifier: 1.1.4 + version: 1.1.4 + zod: + specifier: 4.3.6 + version: 4.3.6 + zundo: + specifier: 2.3.0 + version: 2.3.0 + zustand: + specifier: 5.0.12 + version: 5.0.12 + overrides: '@lexical/code': npm:lexical-code-no-prism@0.41.0 '@monaco-editor/loader': 1.7.0 @@ -15,12 +570,14 @@ overrides: array.prototype.flatmap: npm:@nolyfill/array.prototype.flatmap@^1.0.44 array.prototype.tosorted: npm:@nolyfill/array.prototype.tosorted@^1.0.44 assert: npm:@nolyfill/assert@^1.0.26 + axios: 1.14.0 brace-expansion@<2.0.2: 2.0.2 canvas: ^3.2.2 devalue@<5.3.2: 5.3.2 dompurify@>=3.1.3 <=3.3.1: 3.3.2 es-iterator-helpers: npm:@nolyfill/es-iterator-helpers@^1.0.21 esbuild@<0.27.2: 0.27.2 + flatted@<=3.4.1: 3.4.2 glob@>=10.2.0 <10.5.0: 11.1.0 hasown: npm:@nolyfill/hasown@^1.0.44 is-arguments: npm:@nolyfill/is-arguments@^1.0.44 @@ -55,8 +612,8 @@ overrides: tar@<=7.5.10: 7.5.11 typed-array-buffer: npm:@nolyfill/typed-array-buffer@^1.0.44 undici@>=7.0.0 <7.24.0: 7.24.0 - vite: npm:@voidzero-dev/vite-plus-core@0.1.13 - vitest: npm:@voidzero-dev/vite-plus-test@0.1.13 + vite: npm:@voidzero-dev/vite-plus-core@0.1.14 + vitest: npm:@voidzero-dev/vite-plus-test@0.1.14 which-typed-array: npm:@nolyfill/which-typed-array@^1.0.44 yaml@>=2.0.0 <2.8.3: 2.8.3 yauzl@<3.2.1: 3.2.1 @@ -64,554 +621,612 @@ overrides: importers: .: + devDependencies: + taze: + specifier: 'catalog:' + version: 19.10.0 + + e2e: + devDependencies: + '@cucumber/cucumber': + specifier: 'catalog:' + version: 12.7.0 + '@playwright/test': + specifier: 'catalog:' + version: 1.58.2 + '@types/node': + specifier: 'catalog:' + version: 25.5.0 + tsx: + specifier: 'catalog:' + version: 4.21.0 + typescript: + specifier: 'catalog:' + version: 5.9.3 + vite-plus: + specifier: 'catalog:' + version: 0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3) + + sdks/nodejs-client: + dependencies: + axios: + specifier: 1.14.0 + version: 1.14.0 + devDependencies: + '@eslint/js': + specifier: 'catalog:' + version: 10.0.1(eslint@10.1.0(jiti@2.6.1)) + '@types/node': + specifier: 'catalog:' + version: 25.5.0 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 8.57.2(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) + '@vitest/coverage-v8': + specifier: 'catalog:' + version: 4.1.2(@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3)) + eslint: + specifier: 'catalog:' + version: 10.1.0(jiti@2.6.1) + tsup: + specifier: 'catalog:' + version: 8.5.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) + typescript: + specifier: 'catalog:' + version: 5.9.3 + vitest: + specifier: npm:@voidzero-dev/vite-plus-test@0.1.14 + version: '@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3)' + + web: dependencies: '@amplitude/analytics-browser': - specifier: 2.37.0 - version: 2.37.0 + specifier: 'catalog:' + version: 2.38.0 '@amplitude/plugin-session-replay-browser': - specifier: 1.27.1 - version: 1.27.1(@amplitude/rrweb@2.0.0-alpha.36)(rollup@4.59.0) + specifier: 'catalog:' + version: 1.27.5(@amplitude/rrweb@2.0.0-alpha.37)(rollup@4.59.0) '@base-ui/react': - specifier: 1.3.0 + specifier: 'catalog:' version: 1.3.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@emoji-mart/data': - specifier: 1.2.1 + specifier: 'catalog:' version: 1.2.1 '@floating-ui/react': - specifier: 0.27.19 + specifier: 'catalog:' version: 0.27.19(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@formatjs/intl-localematcher': - specifier: 0.8.2 + specifier: 'catalog:' version: 0.8.2 '@headlessui/react': - specifier: 2.2.9 + specifier: 'catalog:' version: 2.2.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@heroicons/react': - specifier: 2.2.0 + specifier: 'catalog:' version: 2.2.0(react@19.2.4) '@lexical/code': specifier: npm:lexical-code-no-prism@0.41.0 version: lexical-code-no-prism@0.41.0(@lexical/utils@0.42.0)(lexical@0.42.0) '@lexical/link': - specifier: 0.42.0 + specifier: 'catalog:' version: 0.42.0 '@lexical/list': - specifier: 0.42.0 + specifier: 'catalog:' version: 0.42.0 '@lexical/react': - specifier: 0.42.0 + specifier: 'catalog:' version: 0.42.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(yjs@13.6.30) '@lexical/selection': - specifier: 0.42.0 + specifier: 'catalog:' version: 0.42.0 '@lexical/text': - specifier: 0.42.0 + specifier: 'catalog:' version: 0.42.0 '@lexical/utils': - specifier: 0.42.0 + specifier: 'catalog:' version: 0.42.0 '@monaco-editor/react': - specifier: 4.7.0 + specifier: 'catalog:' version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@orpc/client': - specifier: 1.13.9 - version: 1.13.9 + specifier: 'catalog:' + version: 1.13.13 '@orpc/contract': - specifier: 1.13.9 - version: 1.13.9 + specifier: 'catalog:' + version: 1.13.13 '@orpc/openapi-client': - specifier: 1.13.9 - version: 1.13.9 + specifier: 'catalog:' + version: 1.13.13 '@orpc/tanstack-query': - specifier: 1.13.9 - version: 1.13.9(@orpc/client@1.13.9)(@tanstack/query-core@5.95.0) + specifier: 'catalog:' + version: 1.13.13(@orpc/client@1.13.13)(@tanstack/query-core@5.95.2) '@remixicon/react': - specifier: 4.9.0 + specifier: 'catalog:' version: 4.9.0(react@19.2.4) '@sentry/react': - specifier: 10.45.0 - version: 10.45.0(react@19.2.4) + specifier: 'catalog:' + version: 10.46.0(react@19.2.4) '@streamdown/math': - specifier: 1.0.2 + specifier: 'catalog:' version: 1.0.2(react@19.2.4) '@svgdotjs/svg.js': - specifier: 3.2.5 + specifier: 'catalog:' version: 3.2.5 '@t3-oss/env-nextjs': - specifier: 0.13.11 - version: 0.13.11(typescript@5.9.3)(valibot@1.3.0(typescript@5.9.3))(zod@4.3.6) + specifier: 'catalog:' + version: 0.13.11(typescript@5.9.3)(valibot@1.3.1(typescript@5.9.3))(zod@4.3.6) '@tailwindcss/typography': - specifier: 0.5.19 + specifier: 'catalog:' version: 0.5.19(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)) '@tanstack/react-form': - specifier: 1.28.5 + specifier: 'catalog:' version: 1.28.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@tanstack/react-query': - specifier: 5.95.0 - version: 5.95.0(react@19.2.4) + specifier: 'catalog:' + version: 5.95.2(react@19.2.4) abcjs: - specifier: 6.6.2 + specifier: 'catalog:' version: 6.6.2 ahooks: - specifier: 3.9.6 - version: 3.9.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: 'catalog:' + version: 3.9.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) class-variance-authority: - specifier: 0.7.1 + specifier: 'catalog:' version: 0.7.1 clsx: - specifier: 2.1.1 + specifier: 'catalog:' version: 2.1.1 cmdk: - specifier: 1.1.1 + specifier: 'catalog:' version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) copy-to-clipboard: - specifier: 3.3.3 + specifier: 'catalog:' version: 3.3.3 cron-parser: - specifier: 5.5.0 + specifier: 'catalog:' version: 5.5.0 dayjs: - specifier: 1.11.20 + specifier: 'catalog:' version: 1.11.20 decimal.js: - specifier: 10.6.0 + specifier: 'catalog:' version: 10.6.0 dompurify: - specifier: 3.3.3 + specifier: 'catalog:' version: 3.3.3 echarts: - specifier: 6.0.0 + specifier: 'catalog:' version: 6.0.0 echarts-for-react: - specifier: 3.0.6 + specifier: 'catalog:' version: 3.0.6(echarts@6.0.0)(react@19.2.4) elkjs: - specifier: 0.11.1 + specifier: 'catalog:' version: 0.11.1 embla-carousel-autoplay: - specifier: 8.6.0 + specifier: 'catalog:' version: 8.6.0(embla-carousel@8.6.0) embla-carousel-react: - specifier: 8.6.0 + specifier: 'catalog:' version: 8.6.0(react@19.2.4) emoji-mart: - specifier: 5.6.0 + specifier: 'catalog:' version: 5.6.0 es-toolkit: - specifier: 1.45.1 + specifier: 'catalog:' version: 1.45.1 fast-deep-equal: - specifier: 3.1.3 + specifier: 'catalog:' version: 3.1.3 foxact: - specifier: 0.3.0 + specifier: 'catalog:' version: 0.3.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) html-entities: - specifier: 2.6.0 + specifier: 'catalog:' version: 2.6.0 html-to-image: - specifier: 1.11.13 + specifier: 'catalog:' version: 1.11.13 i18next: - specifier: 25.10.4 - version: 25.10.4(typescript@5.9.3) + specifier: 'catalog:' + version: 25.10.10(typescript@5.9.3) i18next-resources-to-backend: - specifier: 1.2.1 + specifier: 'catalog:' version: 1.2.1 immer: - specifier: 11.1.4 + specifier: 'catalog:' version: 11.1.4 jotai: - specifier: 2.18.1 - version: 2.18.1(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.14)(react@19.2.4) + specifier: 'catalog:' + version: 2.19.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.14)(react@19.2.4) js-audio-recorder: - specifier: 1.0.7 + specifier: 'catalog:' version: 1.0.7 js-cookie: - specifier: 3.0.5 + specifier: 'catalog:' version: 3.0.5 js-yaml: - specifier: 4.1.1 + specifier: 'catalog:' version: 4.1.1 jsonschema: - specifier: 1.5.0 + specifier: 'catalog:' version: 1.5.0 katex: - specifier: 0.16.40 - version: 0.16.40 + specifier: 'catalog:' + version: 0.16.44 ky: - specifier: 1.14.3 + specifier: 'catalog:' version: 1.14.3 lamejs: - specifier: 1.2.1 + specifier: 'catalog:' version: 1.2.1 lexical: - specifier: 0.42.0 + specifier: 'catalog:' version: 0.42.0 mermaid: - specifier: 11.13.0 + specifier: 'catalog:' version: 11.13.0 mime: - specifier: 4.1.0 + specifier: 'catalog:' version: 4.1.0 mitt: - specifier: 3.0.1 + specifier: 'catalog:' version: 3.0.1 negotiator: - specifier: 1.0.0 + specifier: 'catalog:' version: 1.0.0 next: - specifier: 16.2.1 - version: 16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) + specifier: 'catalog:' + version: 16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) next-themes: - specifier: 0.4.6 + specifier: 'catalog:' version: 0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) nuqs: - specifier: 2.8.9 - version: 2.8.9(next@16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react@19.2.4) + specifier: 'catalog:' + version: 2.8.9(next@16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react@19.2.4) pinyin-pro: - specifier: 3.28.0 + specifier: 'catalog:' version: 3.28.0 qrcode.react: - specifier: 4.2.0 + specifier: 'catalog:' version: 4.2.0(react@19.2.4) qs: - specifier: 6.15.0 + specifier: 'catalog:' version: 6.15.0 react: - specifier: 19.2.4 + specifier: 'catalog:' version: 19.2.4 react-18-input-autosize: - specifier: 3.0.0 + specifier: 'catalog:' version: 3.0.0(react@19.2.4) react-dom: - specifier: 19.2.4 + specifier: 'catalog:' version: 19.2.4(react@19.2.4) react-easy-crop: - specifier: 5.5.6 - version: 5.5.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: 'catalog:' + version: 5.5.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-hotkeys-hook: - specifier: 5.2.4 + specifier: 'catalog:' version: 5.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-i18next: - specifier: 16.6.1 - version: 16.6.1(i18next@25.10.4(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + specifier: 'catalog:' + version: 16.6.6(i18next@25.10.10(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) react-multi-email: - specifier: 1.0.25 + specifier: 'catalog:' version: 1.0.25(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-papaparse: - specifier: 4.4.0 + specifier: 'catalog:' version: 4.4.0 react-pdf-highlighter: - specifier: 8.0.0-rc.0 + specifier: 'catalog:' version: 8.0.0-rc.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-sortablejs: - specifier: 6.1.4 + specifier: 'catalog:' version: 6.1.4(@types/sortablejs@1.15.9)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sortablejs@1.15.7) react-syntax-highlighter: - specifier: 15.6.6 + specifier: 'catalog:' version: 15.6.6(react@19.2.4) react-textarea-autosize: - specifier: 8.5.9 + specifier: 'catalog:' version: 8.5.9(@types/react@19.2.14)(react@19.2.4) react-window: - specifier: 1.8.11 + specifier: 'catalog:' version: 1.8.11(react-dom@19.2.4(react@19.2.4))(react@19.2.4) reactflow: - specifier: 11.11.4 + specifier: 'catalog:' version: 11.11.4(@types/react@19.2.14)(immer@11.1.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) remark-breaks: - specifier: 4.0.0 + specifier: 'catalog:' version: 4.0.0 remark-directive: - specifier: 4.0.0 + specifier: 'catalog:' version: 4.0.0 scheduler: - specifier: 0.27.0 + specifier: 'catalog:' version: 0.27.0 sharp: - specifier: 0.34.5 + specifier: 'catalog:' version: 0.34.5 sortablejs: - specifier: 1.15.7 + specifier: 'catalog:' version: 1.15.7 std-semver: - specifier: 1.0.8 + specifier: 'catalog:' version: 1.0.8 streamdown: - specifier: 2.5.0 + specifier: 'catalog:' version: 2.5.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) string-ts: - specifier: 2.3.1 + specifier: 'catalog:' version: 2.3.1 tailwind-merge: - specifier: 2.6.1 + specifier: 'catalog:' version: 2.6.1 tldts: - specifier: 7.0.27 + specifier: 'catalog:' version: 7.0.27 unist-util-visit: - specifier: 5.1.0 + specifier: 'catalog:' version: 5.1.0 use-context-selector: - specifier: 2.0.0 + specifier: 'catalog:' version: 2.0.0(react@19.2.4)(scheduler@0.27.0) uuid: - specifier: 13.0.0 + specifier: 'catalog:' version: 13.0.0 zod: - specifier: 4.3.6 + specifier: 'catalog:' version: 4.3.6 zundo: - specifier: 2.3.0 + specifier: 'catalog:' version: 2.3.0(zustand@5.0.12(@types/react@19.2.14)(immer@11.1.4)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))) zustand: - specifier: 5.0.12 + specifier: 'catalog:' version: 5.0.12(@types/react@19.2.14)(immer@11.1.4)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) devDependencies: '@antfu/eslint-config': - specifier: 7.7.3 - version: 7.7.3(@eslint-react/eslint-plugin@3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.2.1)(@typescript-eslint/rule-tester@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3))(@typescript-eslint/utils@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(@vue/compiler-sfc@3.5.30)(eslint-plugin-react-hooks@7.0.1(eslint@10.1.0(jiti@1.21.7)))(eslint-plugin-react-refresh@0.5.2(eslint@10.1.0(jiti@1.21.7)))(eslint@10.1.0(jiti@1.21.7))(oxlint@1.56.0(oxlint-tsgolint@0.17.1))(typescript@5.9.3) + specifier: 'catalog:' + version: 7.7.3(@eslint-react/eslint-plugin@3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.2.1)(@typescript-eslint/rule-tester@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.2(typescript@5.9.3))(@typescript-eslint/utils@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(@vue/compiler-sfc@3.5.31)(eslint-plugin-react-hooks@7.0.1(eslint@10.1.0(jiti@1.21.7)))(eslint-plugin-react-refresh@0.5.2(eslint@10.1.0(jiti@1.21.7)))(eslint@10.1.0(jiti@1.21.7))(oxlint@1.57.0(oxlint-tsgolint@0.17.3))(typescript@5.9.3) '@chromatic-com/storybook': - specifier: 5.0.2 - version: 5.0.2(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + specifier: 'catalog:' + version: 5.1.1(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@egoist/tailwindcss-icons': - specifier: 1.9.2 + specifier: 'catalog:' version: 1.9.2(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3)) '@eslint-react/eslint-plugin': - specifier: 3.0.0 + specifier: 'catalog:' version: 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@hono/node-server': - specifier: 1.19.11 - version: 1.19.11(hono@4.12.8) + specifier: 'catalog:' + version: 1.19.11(hono@4.12.9) '@iconify-json/heroicons': - specifier: 1.2.3 + specifier: 'catalog:' version: 1.2.3 '@iconify-json/ri': - specifier: 1.2.10 + specifier: 'catalog:' version: 1.2.10 '@mdx-js/loader': - specifier: 3.1.1 + specifier: 'catalog:' version: 3.1.1(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) '@mdx-js/react': - specifier: 3.1.1 + specifier: 'catalog:' version: 3.1.1(@types/react@19.2.14)(react@19.2.4) '@mdx-js/rollup': - specifier: 3.1.1 + specifier: 'catalog:' version: 3.1.1(rollup@4.59.0) '@next/eslint-plugin-next': - specifier: 16.2.1 + specifier: 'catalog:' version: 16.2.1 '@next/mdx': - specifier: 16.2.1 + specifier: 'catalog:' version: 16.2.1(@mdx-js/loader@3.1.1(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4)) '@rgrove/parse-xml': - specifier: 4.2.0 + specifier: 'catalog:' version: 4.2.0 '@storybook/addon-docs': - specifier: 10.3.1 - version: 10.3.1(@types/react@19.2.14)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) + specifier: 'catalog:' + version: 10.3.3(@types/react@19.2.14)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) '@storybook/addon-links': - specifier: 10.3.1 - version: 10.3.1(react@19.2.4)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + specifier: 'catalog:' + version: 10.3.3(react@19.2.4)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@storybook/addon-onboarding': - specifier: 10.3.1 - version: 10.3.1(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + specifier: 'catalog:' + version: 10.3.3(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@storybook/addon-themes': - specifier: 10.3.1 - version: 10.3.1(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + specifier: 'catalog:' + version: 10.3.3(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@storybook/nextjs-vite': - specifier: 10.3.1 - version: 10.3.1(@babel/core@7.29.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(next@16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) + specifier: 'catalog:' + version: 10.3.3(@babel/core@7.29.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(next@16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) '@storybook/react': - specifier: 10.3.1 - version: 10.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + specifier: 'catalog:' + version: 10.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) '@tanstack/eslint-plugin-query': - specifier: 5.95.0 - version: 5.95.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + specifier: 'catalog:' + version: 5.95.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@tanstack/react-devtools': - specifier: 0.10.0 + specifier: 'catalog:' version: 0.10.0(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.11) '@tanstack/react-form-devtools': - specifier: 0.2.19 + specifier: 'catalog:' version: 0.2.19(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11) '@tanstack/react-query-devtools': - specifier: 5.95.0 - version: 5.95.0(@tanstack/react-query@5.95.0(react@19.2.4))(react@19.2.4) + specifier: 'catalog:' + version: 5.95.2(@tanstack/react-query@5.95.2(react@19.2.4))(react@19.2.4) '@testing-library/dom': - specifier: 10.4.1 + specifier: 'catalog:' version: 10.4.1 '@testing-library/jest-dom': - specifier: 6.9.1 + specifier: 'catalog:' version: 6.9.1 '@testing-library/react': - specifier: 16.3.2 + specifier: 'catalog:' version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@testing-library/user-event': - specifier: 14.6.1 + specifier: 'catalog:' version: 14.6.1(@testing-library/dom@10.4.1) '@tsslint/cli': - specifier: 3.0.2 + specifier: 'catalog:' version: 3.0.2(@tsslint/compat-eslint@3.0.2(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3) '@tsslint/compat-eslint': - specifier: 3.0.2 + specifier: 'catalog:' version: 3.0.2(jiti@1.21.7)(typescript@5.9.3) '@tsslint/config': - specifier: 3.0.2 + specifier: 'catalog:' version: 3.0.2(@tsslint/compat-eslint@3.0.2(jiti@1.21.7)(typescript@5.9.3))(typescript@5.9.3) '@types/js-cookie': - specifier: 3.0.6 + specifier: 'catalog:' version: 3.0.6 '@types/js-yaml': - specifier: 4.0.9 + specifier: 'catalog:' version: 4.0.9 '@types/negotiator': - specifier: 0.6.4 + specifier: 'catalog:' version: 0.6.4 '@types/node': - specifier: 25.5.0 + specifier: 'catalog:' version: 25.5.0 '@types/postcss-js': - specifier: 4.1.0 + specifier: 'catalog:' version: 4.1.0 '@types/qs': - specifier: 6.15.0 + specifier: 'catalog:' version: 6.15.0 '@types/react': - specifier: 19.2.14 + specifier: 'catalog:' version: 19.2.14 '@types/react-dom': - specifier: 19.2.3 + specifier: 'catalog:' version: 19.2.3(@types/react@19.2.14) '@types/react-syntax-highlighter': - specifier: 15.5.13 + specifier: 'catalog:' version: 15.5.13 '@types/react-window': - specifier: 1.8.8 + specifier: 'catalog:' version: 1.8.8 '@types/sortablejs': - specifier: 1.15.9 + specifier: 'catalog:' version: 1.15.9 '@typescript-eslint/parser': - specifier: 8.57.1 - version: 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + specifier: 'catalog:' + version: 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@typescript/native-preview': - specifier: 7.0.0-dev.20260322.1 - version: 7.0.0-dev.20260322.1 + specifier: 'catalog:' + version: 7.0.0-dev.20260329.1 '@vitejs/plugin-react': - specifier: 6.0.1 - version: 6.0.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) + specifier: 'catalog:' + version: 6.0.1(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) '@vitejs/plugin-rsc': - specifier: 0.5.21 - version: 0.5.21(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)))(react@19.2.4) + specifier: 'catalog:' + version: 0.5.21(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)))(react@19.2.4) '@vitest/coverage-v8': - specifier: 4.1.0 - version: 4.1.0(@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) + specifier: 'catalog:' + version: 4.1.2(@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) agentation: - specifier: 2.3.3 - version: 2.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: 'catalog:' + version: 3.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) autoprefixer: - specifier: 10.4.27 + specifier: 'catalog:' version: 10.4.27(postcss@8.5.8) code-inspector-plugin: - specifier: 1.4.5 + specifier: 'catalog:' version: 1.4.5 eslint: - specifier: 10.1.0 + specifier: 'catalog:' version: 10.1.0(jiti@1.21.7) eslint-markdown: - specifier: 0.6.0 + specifier: 'catalog:' version: 0.6.0(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-better-tailwindcss: - specifier: 4.3.2 - version: 4.3.2(eslint@10.1.0(jiti@1.21.7))(oxlint@1.56.0(oxlint-tsgolint@0.17.1))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))(typescript@5.9.3) + specifier: 'catalog:' + version: 4.3.2(eslint@10.1.0(jiti@1.21.7))(oxlint@1.57.0(oxlint-tsgolint@0.17.3))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))(typescript@5.9.3) eslint-plugin-hyoban: - specifier: 0.14.1 + specifier: 'catalog:' version: 0.14.1(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-markdown-preferences: - specifier: 0.40.3 + specifier: 'catalog:' version: 0.40.3(@eslint/markdown@7.5.1)(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-no-barrel-files: - specifier: 1.2.2 + specifier: 'catalog:' version: 1.2.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint-plugin-react-hooks: - specifier: 7.0.1 + specifier: 'catalog:' version: 7.0.1(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-react-refresh: - specifier: 0.5.2 + specifier: 'catalog:' version: 0.5.2(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-sonarjs: - specifier: 4.0.2 + specifier: 'catalog:' version: 4.0.2(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-storybook: - specifier: 10.3.1 - version: 10.3.1(eslint@10.1.0(jiti@1.21.7))(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + specifier: 'catalog:' + version: 10.3.3(eslint@10.1.0(jiti@1.21.7))(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) happy-dom: - specifier: 20.8.9 + specifier: 'catalog:' version: 20.8.9 hono: - specifier: 4.12.8 - version: 4.12.8 + specifier: 'catalog:' + version: 4.12.9 husky: - specifier: 9.1.7 + specifier: 'catalog:' version: 9.1.7 iconify-import-svg: - specifier: 0.1.2 + specifier: 'catalog:' version: 0.1.2 knip: - specifier: 6.0.2 - version: 6.0.2 + specifier: 'catalog:' + version: 6.1.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) lint-staged: - specifier: 16.4.0 + specifier: 'catalog:' version: 16.4.0 postcss: - specifier: 8.5.8 + specifier: 'catalog:' version: 8.5.8 postcss-js: - specifier: 5.1.0 + specifier: 'catalog:' version: 5.1.0(postcss@8.5.8) react-server-dom-webpack: - specifier: 19.2.4 + specifier: 'catalog:' version: 19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) sass: - specifier: 1.98.0 + specifier: 'catalog:' version: 1.98.0 storybook: - specifier: 10.3.1 - version: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + specifier: 'catalog:' + version: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tailwindcss: - specifier: 3.4.19 + specifier: 'catalog:' version: 3.4.19(tsx@4.21.0)(yaml@2.8.3) - taze: - specifier: 19.10.0 - version: 19.10.0 tsx: - specifier: 4.21.0 + specifier: 'catalog:' version: 4.21.0 typescript: - specifier: 5.9.3 + specifier: 'catalog:' version: 5.9.3 uglify-js: - specifier: 3.19.3 + specifier: 'catalog:' version: 3.19.3 vinext: - specifier: https://pkg.pr.new/vinext@b6a2cac - version: https://pkg.pr.new/vinext@b6a2cac(33c71b051bfc49f90bf5d8b6a8976975) + specifier: 'catalog:' + version: 0.0.38(f5786d681f520e26604259e094ebaa46) vite: - specifier: npm:@voidzero-dev/vite-plus-core@0.1.13 - version: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + specifier: npm:@voidzero-dev/vite-plus-core@0.1.14 + version: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' vite-plugin-inspect: - specifier: 11.3.3 - version: 11.3.3(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) + specifier: 'catalog:' + version: 12.0.0-beta.1(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3)(ws@8.20.0) vite-plus: - specifier: 0.1.13 - version: 0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) + specifier: 'catalog:' + version: 0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) vitest: - specifier: npm:@voidzero-dev/vite-plus-test@0.1.13 - version: '@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + specifier: npm:@voidzero-dev/vite-plus-test@0.1.14 + version: '@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' vitest-canvas-mock: - specifier: 1.1.3 - version: 1.1.3(@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) + specifier: 'catalog:' + version: 1.1.4(@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) packages: @@ -622,17 +1237,17 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@amplitude/analytics-browser@2.37.0': - resolution: {integrity: sha512-/BWDneHRfq6+9bcPQC09Ep79SEj7aRJLZ1jJrPHtxA9KZJUz2au2COlJc1ReCaNzCcrA1xXv/MQ0Fv7TwoBglg==} + '@amplitude/analytics-browser@2.38.0': + resolution: {integrity: sha512-MhqyEkr1gGAR4s4GSSflDhFVheIx9Nv3FfElQu9NlNrXB2Hh3BEOyVgdK7hgfi6NJwFyfw30+t5lym+njtA8hA==} - '@amplitude/analytics-client-common@2.4.39': - resolution: {integrity: sha512-DFzi2/D2eu7EBCyslk86lToQa+qo1AmKgvZQVDDqkLG37/meTRcBAZiL0FAdTX21AYwpC/Ym4FWowD04foiBIQ==} + '@amplitude/analytics-client-common@2.4.41': + resolution: {integrity: sha512-+GbvtvhsUROotPBwfAxbrqovKePhC0oQKXtxjbeNQleOHjBjsAs5jEOCHpJenCKtaRpucg/FuK3NVOS09MfW7Q==} '@amplitude/analytics-connector@1.6.4': resolution: {integrity: sha512-SpIv0IQMNIq6SH3UqFGiaZyGSc7PBZwRdq7lvP0pBxW8i4Ny+8zwI0pV+VMfMHQwWY3wdIbWw5WQphNjpdq1/Q==} - '@amplitude/analytics-core@2.43.0': - resolution: {integrity: sha512-rcDqi4cmI9Ro7hN5wjAuTm92IdN2i0lhIDAj+JOd9BP3SRMrhhiw2lzcScj3owig8CiV9X7EHPTuZe6XCTfIgQ==} + '@amplitude/analytics-core@2.44.0': + resolution: {integrity: sha512-z9QuTxLqEQ8KIeAT6Vmy6K48rP9TUmjnb4GwUMYoV/fxu3B9ClTaN18zqXQMmDw9HwUiIreHiVbwTb7OQRN5aA==} '@amplitude/analytics-types@2.11.1': resolution: {integrity: sha512-wFEgb0t99ly2uJKm5oZ28Lti0Kh5RecR5XBkwfUpDzn84IoCIZ8GJTsMw/nThu8FZFc7xFDA4UAt76zhZKrs9A==} @@ -640,29 +1255,29 @@ packages: '@amplitude/experiment-core@0.7.2': resolution: {integrity: sha512-Wc2NWvgQ+bLJLeF0A9wBSPIaw0XuqqgkPKsoNFQrmS7r5Djd56um75In05tqmVntPJZRvGKU46pAp8o5tdf4mA==} - '@amplitude/plugin-autocapture-browser@1.24.1': - resolution: {integrity: sha512-cvjOFew2MFNBDTbk3+H7WNi3D0Jdp476m6faCaVhY99M5zqRCHDMRS7dC4HczvL9zYXlAcW9jAWucwES2m3TiQ==} + '@amplitude/plugin-autocapture-browser@1.25.0': + resolution: {integrity: sha512-YuWsz8XmJuKu3NlMxkvlhLey/5tGCeOwwfsROHficR0yDWO9gNG0WtHl7A0Pw1PUc9iaXjqfG2AjYumAtiq16Q==} - '@amplitude/plugin-custom-enrichment-browser@0.1.0': - resolution: {integrity: sha512-y3VmqZvCP1Z3jNgo/mtKVHON9L0P2SyqkMmUsbbFuLu1+TKIkicotnVq/lzlLU1TrW68mkInOM+We8JngasZBA==} + '@amplitude/plugin-custom-enrichment-browser@0.1.2': + resolution: {integrity: sha512-ZX9BKqs1E1OI7l7QCGu9JnB/1kqLN+zqIePgM2tuEhZNFQJaw4NhAMUaMRqvNnaCkHlmpVRISzSj/4D3tWMRtA==} - '@amplitude/plugin-network-capture-browser@1.9.9': - resolution: {integrity: sha512-SJIOQN04Mk9vCsnVd9QRcIvkMV7XSGZIKfbaKNQY5O3ueV33Kc8opm7YjPg2sWcxdzTcJijbCkOI0wCwOaRolg==} + '@amplitude/plugin-network-capture-browser@1.9.11': + resolution: {integrity: sha512-49o3zYnKUmRdrxgAEcr1iHnXR1um40e1icO0hzugSq04k19hs27zcl3zpEk9geO+nNKwO744ryE1q93gqVbHrQ==} - '@amplitude/plugin-page-url-enrichment-browser@0.7.0': - resolution: {integrity: sha512-MkM7TDq24k7ilUDNZISqjDSkVfmDJxWcnUagwYEXjLILhno5hGm7wdgFvVXXzKlZQHEogBxkbnq7wZXS9/YsMw==} + '@amplitude/plugin-page-url-enrichment-browser@0.7.3': + resolution: {integrity: sha512-3UZq/zKg4lcsRgziWAPSEeaUsNsbyjjxmsAE9kSDi/hIj5RaWnwWhY6TGhv45UAReugTA4vVZyFRg9btf3c/Fg==} - '@amplitude/plugin-page-view-tracking-browser@2.9.1': - resolution: {integrity: sha512-jkxz2lkJDAfsjj7mpbPUZx9N3qJssC3uYyv8Nk73z+p+v0wjBikWdOoKuNQkcuP09701zRdXp9ziU8+qwkGusw==} + '@amplitude/plugin-page-view-tracking-browser@2.9.4': + resolution: {integrity: sha512-J16zmEadnzNpkHSmzpTiQN2q9pGJ/4SkHONA9O8KxUsMU/MYTDgof3rAYY/w5B5rmvdxfMRCjqWtvnkizzgZ6w==} - '@amplitude/plugin-session-replay-browser@1.27.1': - resolution: {integrity: sha512-IEkAU7O3LbL23piMD7Lu0ej9wT/LQdQsyY1okTW5y2Nov8ZCmqLhZPLk6s9vKCUxGukDi7IL6gqXpURTLYj5rQ==} + '@amplitude/plugin-session-replay-browser@1.27.5': + resolution: {integrity: sha512-tf0Ty1nNF8OJ5QQ5scEqdGfzdgIaqkRf2MSzQfHbGcTIoYuVmAKuCgn3yMLk62MKnwgG3IsTIugMdRRv7l85PA==} - '@amplitude/plugin-web-vitals-browser@1.1.24': - resolution: {integrity: sha512-7AaytUK78RKdyDsblYJCKYan1lQi3Qzsp1WHItHJ+RSXPccmi4mCcvNtx0e8T9LmNJlUnsmYeEGR/6FaWvyvFg==} + '@amplitude/plugin-web-vitals-browser@1.1.26': + resolution: {integrity: sha512-wiD4vy+f2fepr+8Lnn26TYYjDEnWsmlGhJog99x+xfbZ/D+stGdaCIOz5AOjU1TpTRvxvamEu2XuOh+8EZOCSA==} - '@amplitude/rrdom@2.0.0-alpha.36': - resolution: {integrity: sha512-8jNhYEzjp6aaZON7qY/IpZIVbl8SUojb8kxD58StknlvnjKeGV7nHheXbkIz+T1LSVbWsdh+noIWuqhyFWzvgg==} + '@amplitude/rrdom@2.0.0-alpha.37': + resolution: {integrity: sha512-u4dSnBtlbJ8oU5P/Ywl2RLqvjqWbkl4ScMUbvQA7in4pWcx+0NRN+VVjLZXQcd8Fn7E/rcxjeUh7e7HfwvdasQ==} '@amplitude/rrweb-packer@2.0.0-alpha.36': resolution: {integrity: sha512-kqKg6OGoxHZvG4jwyO4kIjLdf8MkL6JcY5iLB09PQNP7O36ysnrH+ecJfa4V1Rld99kX25Pefkw4bzKmmFAqcg==} @@ -675,20 +1290,26 @@ packages: '@amplitude/rrweb-record@2.0.0-alpha.36': resolution: {integrity: sha512-zSHvmG5NUG4jNgWNVM7Oj3+rJPagv+TiHlnSiJ1X0WWLIg1GbUnOoTqpincZS5QupqTxQchNQaUg9MNu0MM3sQ==} - '@amplitude/rrweb-snapshot@2.0.0-alpha.36': - resolution: {integrity: sha512-vUvTXkNcu+cN736tykQDUVWERetFz1hyzgS0Yib5qSeWJwbse/4BaiWaZ7c5WevbbtcjLbDJqYKySJM92H5SxQ==} + '@amplitude/rrweb-snapshot@2.0.0-alpha.37': + resolution: {integrity: sha512-OPW2r8ESAguq+1R+z+WxGyzZzkMtojZ49Lpp6NrataNFyjdKaNXehDuLoNlEQkkUZGyDBiA7RSYvUw+JPSmmSQ==} '@amplitude/rrweb-types@2.0.0-alpha.36': resolution: {integrity: sha512-Bd2r3Bs0XIJt5fgPRWVl8bhvA9FCjJn8vQlDTO8ffPxilGPIzUXLQ06+xoLYkK9v+PDKJnCapOTL4A2LilDmgA==} + '@amplitude/rrweb-types@2.0.0-alpha.37': + resolution: {integrity: sha512-LW9wQ85umaAW/qlemTrUC408WVoBx99hvFCjsNRnxAyUmRemWyYY7+o8xPyeUexoWGqizPMkkNnPEO8t1NFjtw==} + '@amplitude/rrweb-utils@2.0.0-alpha.36': resolution: {integrity: sha512-w5RGROLU1Kyrq9j+trxcvvfkTp05MEKJ70Ig+YvHyZsE0nElh1PCF8PHAjV0/kji68+KqB03c0hoyaV99CDaDw==} - '@amplitude/rrweb@2.0.0-alpha.36': - resolution: {integrity: sha512-8vhPOk4fvszfxYZTk37EObW3n7uwEgO//funRSMt/QiBWtgQ8jhpFV9FcOAYdgde0Yw1uIM8oUbWZfy/XrexNw==} + '@amplitude/rrweb-utils@2.0.0-alpha.37': + resolution: {integrity: sha512-40YvPj24ietFQ3BTLfvFRPriRqdNOp3DzGiPU+WDOZkI3KjInQrEsibaqNBSXzJ+kMWrm8/eEwcQ0FkLk7Achw==} - '@amplitude/session-replay-browser@1.34.1': - resolution: {integrity: sha512-oQ9Pi/vcEhcRxmMIDMOZopt9vSaGYB4X64kp8idKut2Or8/DBhdztSjujwvkYvU48jNfqmT7oxIY5sCLYdiM6w==} + '@amplitude/rrweb@2.0.0-alpha.37': + resolution: {integrity: sha512-jJkSpPYiVgOZB422pb2jOJJn3pvb5E5f9vKK8CEmUlk2mVAl6kPQzW98mb05M65OJFj5nn9tSe9h5r5+Cl93ag==} + + '@amplitude/session-replay-browser@1.35.0': + resolution: {integrity: sha512-aGqu807oC8UIMmP+g1jBYsgN+/VeR/ThtK6fpxuZCugEogx7EZ9sXDEeudUmyvkQQfWmD+nLmrhYPX8FpROT5w==} '@amplitude/targeting@0.2.0': resolution: {integrity: sha512-/50ywTrC4hfcfJVBbh5DFbqMPPfaIOivZeb5Gb+OGM03QrA+lsUqdvtnKLNuWtceD4H6QQ2KFzPJ5aAJLyzVDA==} @@ -768,17 +1389,6 @@ packages: '@antfu/utils@8.1.1': resolution: {integrity: sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==} - '@asamuzakjp/css-color@5.1.1': - resolution: {integrity: sha512-iGWN8E45Ws0XWx3D44Q1t6vX2LqhCKcwfmwBYCDsFrYFS6m4q/Ks61L2veETaLv+ckDC6+dTETJoaAAb7VjLiw==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - - '@asamuzakjp/dom-selector@7.0.4': - resolution: {integrity: sha512-jXR6x4AcT3eIrS2fSNAwJpwirOkGcd+E7F7CP3zjdTqz9B/2huHOL8YJZBgekKwLML+u7qB/6P1LXQuMScsx0w==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - - '@asamuzakjp/nwsapi@2.3.9': - resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} - '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -878,10 +1488,6 @@ packages: '@braintree/sanitize-url@7.1.2': resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} - '@bramus/specificity@2.4.2': - resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} - hasBin: true - '@chevrotain/cst-dts-gen@11.1.2': resolution: {integrity: sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==} @@ -897,8 +1503,8 @@ packages: '@chevrotain/utils@11.1.2': resolution: {integrity: sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==} - '@chromatic-com/storybook@5.0.2': - resolution: {integrity: sha512-uLd5gyvcz8q83GI0rYWjml45ryO3ZJwZLretLEZvWFJ3UlFk5C5Km9cwRcKZgZp0F3zYwbb8nEe6PJdgA1eKxg==} + '@chromatic-com/storybook@5.1.1': + resolution: {integrity: sha512-BPoAXHM71XgeCK2u0jKr9i8apeQMm/Z9IWGyndA2FMijfQG9m8ox45DdWh/pxFkK5ClhGgirv5QwMhFIeHmThg==} engines: {node: '>=20.0.0', yarn: '>=1.22.18'} peerDependencies: storybook: ^0.0.0-0 || ^10.1.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 || ^10.4.0-0 @@ -933,41 +1539,67 @@ packages: '@code-inspector/webpack@1.4.5': resolution: {integrity: sha512-lwUv+X1FNSUWz+FKcUsE2dT2pg6VFRRXKt16hg/m+Lwtdet2adfi6BFLZmNz3OPIEGbRB5Kjx6bfaghZhbDCCg==} - '@csstools/color-helpers@6.0.2': - resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==} - engines: {node: '>=20.19.0'} + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} - '@csstools/css-calc@3.1.1': - resolution: {integrity: sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==} - engines: {node: '>=20.19.0'} + '@cucumber/ci-environment@13.0.0': + resolution: {integrity: sha512-cs+3NzfNkGbcmHPddjEv4TKFiBpZRQ6WJEEufB9mw+ExS22V/4R/zpDSEG+fsJ/iSNCd6A2sATdY8PFOyY3YnA==} + + '@cucumber/cucumber-expressions@19.0.0': + resolution: {integrity: sha512-4FKoOQh2Uf6F6/Ln+1OxuK8LkTg6PyAqekhf2Ix8zqV2M54sH+m7XNJNLhOFOAW/t9nxzRbw2CcvXbCLjcvHZg==} + + '@cucumber/cucumber@12.7.0': + resolution: {integrity: sha512-7A/9CJpJDxv1SQ7hAZU0zPn2yRxx6XMR+LO4T94Enm3cYNWsEEj+RGX38NLX4INT+H6w5raX3Csb/qs4vUBsOA==} + engines: {node: 20 || 22 || >=24} + hasBin: true + + '@cucumber/gherkin-streams@6.0.0': + resolution: {integrity: sha512-HLSHMmdDH0vCr7vsVEURcDA4WwnRLdjkhqr6a4HQ3i4RFK1wiDGPjBGVdGJLyuXuRdJpJbFc6QxHvT8pU4t6jw==} + hasBin: true peerDependencies: - '@csstools/css-parser-algorithms': ^4.0.0 - '@csstools/css-tokenizer': ^4.0.0 + '@cucumber/gherkin': '>=22.0.0' + '@cucumber/message-streams': '>=4.0.0' + '@cucumber/messages': '>=17.1.1' - '@csstools/css-color-parser@4.0.2': - resolution: {integrity: sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==} - engines: {node: '>=20.19.0'} + '@cucumber/gherkin-utils@11.0.0': + resolution: {integrity: sha512-LJ+s4+TepHTgdKWDR4zbPyT7rQjmYIcukTwNbwNwgqr6i8Gjcmzf6NmtbYDA19m1ZFg6kWbFsmHnj37ZuX+kZA==} + hasBin: true + + '@cucumber/gherkin@38.0.0': + resolution: {integrity: sha512-duEXK+KDfQUzu3vsSzXjkxQ2tirF5PRsc1Xrts6THKHJO6mjw4RjM8RV+vliuDasmhhrmdLcOcM7d9nurNTJKw==} + + '@cucumber/html-formatter@23.0.0': + resolution: {integrity: sha512-WwcRzdM8Ixy4e53j+Frm3fKM5rNuIyWUfy4HajEN+Xk/YcjA6yW0ACGTFDReB++VDZz/iUtwYdTlPRY36NbqJg==} peerDependencies: - '@csstools/css-parser-algorithms': ^4.0.0 - '@csstools/css-tokenizer': ^4.0.0 + '@cucumber/messages': '>=18' - '@csstools/css-parser-algorithms@4.0.0': - resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} - engines: {node: '>=20.19.0'} + '@cucumber/junit-xml-formatter@0.9.0': + resolution: {integrity: sha512-WF+A7pBaXpKMD1i7K59Nk5519zj4extxY4+4nSgv5XLsGXHDf1gJnb84BkLUzevNtp2o2QzMG0vWLwSm8V5blw==} peerDependencies: - '@csstools/css-tokenizer': ^4.0.0 + '@cucumber/messages': '*' - '@csstools/css-syntax-patches-for-csstree@1.1.2': - resolution: {integrity: sha512-5GkLzz4prTIpoyeUiIu3iV6CSG3Plo7xRVOFPKI7FVEJ3mZ0A8SwK0XU3Gl7xAkiQ+mDyam+NNp875/C5y+jSA==} + '@cucumber/message-streams@4.0.1': + resolution: {integrity: sha512-Kxap9uP5jD8tHUZVjTWgzxemi/0uOsbGjd4LBOSxcJoOCRbESFwemUzilJuzNTB8pcTQUh8D5oudUyxfkJOKmA==} peerDependencies: - css-tree: ^3.2.1 - peerDependenciesMeta: - css-tree: - optional: true + '@cucumber/messages': '>=17.1.1' - '@csstools/css-tokenizer@4.0.0': - resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} - engines: {node: '>=20.19.0'} + '@cucumber/messages@32.0.1': + resolution: {integrity: sha512-1OSoW+GQvFUNAl6tdP2CTBexTXMNJF0094goVUcvugtQeXtJ0K8sCP0xbq7GGoiezs/eJAAOD03+zAPT64orHQ==} + + '@cucumber/pretty-formatter@1.0.1': + resolution: {integrity: sha512-A1lU4VVP0aUWdOTmpdzvXOyEYuPtBDI0xYwYJnmoMDplzxMdhcHk86lyyvYDoMoPzzq6OkOE3isuosvUU4X7IQ==} + peerDependencies: + '@cucumber/cucumber': '>=7.0.0' + '@cucumber/messages': '*' + + '@cucumber/query@14.7.0': + resolution: {integrity: sha512-fiqZ4gMEgYjmbuWproF/YeCdD5y+gD2BqgBIGbpihOsx6UlNsyzoDSfO+Tny0q65DxfK+pHo2UkPyEl7dO7wmQ==} + peerDependencies: + '@cucumber/messages': '*' + + '@cucumber/tag-expressions@9.1.0': + resolution: {integrity: sha512-bvHjcRFZ+J1TqIa9eFNO1wGHqwx4V9ZKV3hYgkuK/VahHx73uiP4rKV3JVrvWSMrwrFvJG6C8aEwnCWSvbyFdQ==} '@e18e/eslint-plugin@0.2.0': resolution: {integrity: sha512-mXgODVwhuDjTJ+UT+XSvmMmCidtGKfrV5nMIv1UtpWex2pYLsIM3RSpT8HWIMAebS9qANbXPKlSX4BE7ZvuCgA==} @@ -985,11 +1617,11 @@ packages: peerDependencies: tailwindcss: '*' - '@emnapi/core@1.9.0': - resolution: {integrity: sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==} + '@emnapi/core@1.9.1': + resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} - '@emnapi/runtime@1.9.0': - resolution: {integrity: sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==} + '@emnapi/runtime@1.9.1': + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} '@emnapi/wasi-threads@1.2.0': resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} @@ -1261,6 +1893,15 @@ packages: resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@10.0.1': + resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + peerDependencies: + eslint: ^10.0.0 + peerDependenciesMeta: + eslint: + optional: true + '@eslint/js@9.27.0': resolution: {integrity: sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1289,15 +1930,6 @@ packages: resolution: {integrity: sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@exodus/bytes@1.15.0': - resolution: {integrity: sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - peerDependencies: - '@noble/hashes': ^1.8.0 || ^2.0.0 - peerDependenciesMeta: - '@noble/hashes': - optional: true - '@floating-ui/core@1.7.5': resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} @@ -1680,8 +2312,11 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@napi-rs/wasm-runtime@1.1.1': - resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + '@napi-rs/wasm-runtime@1.1.2': + resolution: {integrity: sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 '@neoconfetti/react@1.0.0': resolution: {integrity: sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==} @@ -1770,6 +2405,10 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@nolyfill/hasown@1.0.44': + resolution: {integrity: sha512-GA/21lkTr2PAQuT6jGnhLuBD5IFd/AEhBXJ/tf33+/bVxPxg+5ejKx9jGQGnyV/P0eSmdup5E+s8b2HL6lOrwQ==} + engines: {node: '>=12.4.0'} + '@nolyfill/is-core-module@1.0.39': resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} engines: {node: '>=12.4.0'} @@ -1782,175 +2421,178 @@ packages: resolution: {integrity: sha512-y3SvzjuY1ygnzWA4Krwx/WaJAsTMP11DN+e21A8Fa8PW1oDtVB5NSRW7LWurAiS2oKRkuCgcjTYMkBuBkcPCRg==} engines: {node: '>=12.4.0'} - '@orpc/client@1.13.9': - resolution: {integrity: sha512-RmD2HDgmGgF6zgHHdybE4zH6QJoHjC+/C3n56yLf+fmWbiZtwnOUETgGCroY6S8aK2fpy6hJ3wZaJUjfWVuGHg==} + '@orpc/client@1.13.13': + resolution: {integrity: sha512-jagx/Sa+9K4HEC5lBrUlMSrmR/06hvZctWh93/sKZc8GBk4zM0+71oT1kXQVw1oRYFV2XAq3xy3m6NdM6gfKYA==} - '@orpc/contract@1.13.9': - resolution: {integrity: sha512-0zxMyF82pxE8DwHzarCsCtOHQK96PE23qubMMBkxkP0XTtLJ7f8aYhrG8F16pNApypmTHiRlQlqNX8VXNViMqQ==} + '@orpc/contract@1.13.13': + resolution: {integrity: sha512-md6iyrYkePBSJNs1VnVEEnAUORMDPHIf3JGRSHxyssIcNakev/iOjP0HvpH0Sx0MlTBhihAJo6uFL8Vpth58Nw==} - '@orpc/openapi-client@1.13.9': - resolution: {integrity: sha512-zvNrc7wgF/INKeewH2ih48U/q9tG7rLZCnmMrb5/1jdZgYYOBAEuILlDAejeQwGdRce6W18GTBjLKIEdP3WwqA==} + '@orpc/openapi-client@1.13.13': + resolution: {integrity: sha512-k8od+bD7MqysKPPybAkxgfaNIaNseFPXtbidWkZAdCZ5w34SnDc7QPZJ0PQbyt9n9B+jOXSADNwQSTWSuGpjyA==} - '@orpc/shared@1.13.9': - resolution: {integrity: sha512-gpMY2e9jDsSyikh4DjBCO2Cs0wGj2I6xo2juIcmogYK5ecsTGO/U5huIftQn+2NUMk1cItwmykJBwc4pqHWVHw==} + '@orpc/shared@1.13.13': + resolution: {integrity: sha512-kNpYOBjHvmgKHla6munWOaEeA0utEfAvoiZpXjiRjjt1RxTibdwQvVHgxRIBNMXfQsb+ON3Q/wDkoaUhvvSnIw==} peerDependencies: '@opentelemetry/api': '>=1.9.0' peerDependenciesMeta: '@opentelemetry/api': optional: true - '@orpc/standard-server-fetch@1.13.9': - resolution: {integrity: sha512-/dJmHO+EVONyvmX3CFZkRjlRHeBfq0+6nnpFIVueGo4fNUbtQc+qurKEtpQqPxL/b7GSehskNH21XKLE0IE0gQ==} + '@orpc/standard-server-fetch@1.13.13': + resolution: {integrity: sha512-Lffy26+WtCQkwOUacsrdyeJF1GNzrhm75O3LXKVFXqmSdyVVdyI6zuqLn/YKGODU2L9IqGxZ2CwsV2tE298SSA==} - '@orpc/standard-server-peer@1.13.9': - resolution: {integrity: sha512-r8hSykxNIKwXSMuLYWBxQx1c3DU8b6nU8V76DZhtwC5g1SLYIzw+dzT/EgHplOfmsFeyodiEDXXX1k/twRLuzw==} + '@orpc/standard-server-peer@1.13.13': + resolution: {integrity: sha512-FeWAbXfnZDPYQRajM0hD6GJvHeC3DZILngAjdcLHy5zt3riu6nL2lLPSWDv5yNWWscmYU+CfKmXWd0Z01BOeWA==} - '@orpc/standard-server@1.13.9': - resolution: {integrity: sha512-dwsky7CScgOaDBa7CBF85aPGk/3UoB4fJjitVghb/sZD0Nt+CGIeiPHMsjEgxw5rJwgawMWLI5KxFH9euAJlWw==} + '@orpc/standard-server@1.13.13': + resolution: {integrity: sha512-9pgS8XvauuRQElkyuD8F3om+nN0KBEnTkhblDHCBzkZERjWkmfirJmshQrWHoFaDTk+nnXHIaY6d7TBTxXdPRw==} - '@orpc/tanstack-query@1.13.9': - resolution: {integrity: sha512-gOVJkCT9JGfu0e0TlTY3YUueXP2+Kzp6TcgfL2U3yXcYdTLv+jTrNOVJdtAAbeweUIU6dBEtatlhAQ7OgHWbsw==} + '@orpc/tanstack-query@1.13.13': + resolution: {integrity: sha512-6+Cheaiu+RDPdszdeRKoBINrF8MQp64zSeZB+L3gqgF43zlYDhLOgELZMzYa6U3U6bLk4rmIeubpk+i1kACfRg==} peerDependencies: - '@orpc/client': 1.13.9 + '@orpc/client': 1.13.13 '@tanstack/query-core': '>=5.80.2' '@ota-meshi/ast-token-store@0.3.0': resolution: {integrity: sha512-XRO0zi2NIUKq2lUk3T1ecFSld1fMWRKE6naRFGkgkdeosx7IslyUKNv5Dcb5PJTja9tHJoFu0v/7yEpAkrkrTg==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@oxc-parser/binding-android-arm-eabi@0.120.0': - resolution: {integrity: sha512-WU3qtINx802wOl8RxAF1v0VvmC2O4D9M8Sv486nLeQ7iPHVmncYZrtBhB4SYyX+XZxj2PNnCcN+PW21jHgiOxg==} + '@oxc-parser/binding-android-arm-eabi@0.121.0': + resolution: {integrity: sha512-n07FQcySwOlzap424/PLMtOkbS7xOu8nsJduKL8P3COGHKgKoDYXwoAHCbChfgFpHnviehrLWIPX0lKGtbEk/A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxc-parser/binding-android-arm64@0.120.0': - resolution: {integrity: sha512-SEf80EHdhlbjZEgzeWm0ZA/br4GKMenDW3QB/gtyeTV1gStvvZeFi40ioHDZvds2m4Z9J1bUAUL8yn1/+A6iGg==} + '@oxc-parser/binding-android-arm64@0.121.0': + resolution: {integrity: sha512-/Dd1xIXboYAicw+twT2utxPD7bL8qh7d3ej0qvaYIMj3/EgIrGR+tSnjCUkiCT6g6uTC0neSS4JY8LxhdSU/sA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-parser/binding-darwin-arm64@0.120.0': - resolution: {integrity: sha512-xVrrbCai8R8CUIBu3CjryutQnEYhZqs1maIqDvtUCFZb8vY33H7uh9mHpL3a0JBIKoBUKjPH8+rzyAeXnS2d6A==} + '@oxc-parser/binding-darwin-arm64@0.121.0': + resolution: {integrity: sha512-A0jNEvv7QMtCO1yk205t3DWU9sWUjQ2KNF0hSVO5W9R9r/R1BIvzG01UQAfmtC0dQm7sCrs5puixurKSfr2bRQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.120.0': - resolution: {integrity: sha512-xyHBbnJ6mydnQUH7MAcafOkkrNzQC6T+LXgDH/3InEq2BWl/g424IMRiJVSpVqGjB+p2bd0h0WRR8iIwzjU7rw==} + '@oxc-parser/binding-darwin-x64@0.121.0': + resolution: {integrity: sha512-SsHzipdxTKUs3I9EOAPmnIimEeJOemqRlRDOp9LIj+96wtxZejF51gNibmoGq8KoqbT1ssAI5po/E3J+vEtXGA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.120.0': - resolution: {integrity: sha512-UMnVRllquXUYTeNfFKmxTTEdZ/ix1nLl0ducDzMSREoWYGVIHnOOxoKMWlCOvRr9Wk/HZqo2rh1jeumbPGPV9A==} + '@oxc-parser/binding-freebsd-x64@0.121.0': + resolution: {integrity: sha512-v1APOTkCp+RWOIDAHRoaeW/UoaHF15a60E8eUL6kUQXh+i4K7PBwq2Wi7jm8p0ymID5/m/oC1w3W31Z/+r7HQw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.120.0': - resolution: {integrity: sha512-tkvn2CQ7QdcsMnpfiX3fd3wA3EFsWKYlcQzq9cFw/xc89Al7W6Y4O0FgLVkVQpo0Tnq/qtE1XfkJOnRRA9S/NA==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.121.0': + resolution: {integrity: sha512-PmqPQuqHZyFVWA4ycr0eu4VnTMmq9laOHZd+8R359w6kzuNZPvmmunmNJ8ybkm769A0nCoVp3TJ6dUz7B3FYIQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.120.0': - resolution: {integrity: sha512-WN5y135Ic42gQDk9grbwY9++fDhqf8knN6fnP+0WALlAUh4odY/BDK1nfTJRSfpJD9P3r1BwU0m3pW2DU89whQ==} + '@oxc-parser/binding-linux-arm-musleabihf@0.121.0': + resolution: {integrity: sha512-vF24htj+MOH+Q7y9A8NuC6pUZu8t/C2Fr/kDOi2OcNf28oogr2xadBPXAbml802E8wRAVfbta6YLDQTearz+jw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.120.0': - resolution: {integrity: sha512-1GgQBCcXvFMw99EPdMy+4NZ3aYyXsxjf9kbUUg8HuAy3ZBXzOry5KfFEzT9nqmgZI1cuetvApkiJBZLAPo8uaw==} + '@oxc-parser/binding-linux-arm64-gnu@0.121.0': + resolution: {integrity: sha512-wjH8cIG2Lu/3d64iZpbYr73hREMgKAfu7fqpXjgM2S16y2zhTfDIp8EQjxO8vlDtKP5Rc7waZW72lh8nZtWrpA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-arm64-musl@0.120.0': - resolution: {integrity: sha512-gmMQ70gsPdDBgpcErvJEoWNBr7bJooSLlvOBVBSGfOzlP5NvJ3bFvnUeZZ9d+dPrqSngtonf7nyzWUTUj/U+lw==} + '@oxc-parser/binding-linux-arm64-musl@0.121.0': + resolution: {integrity: sha512-qT663J/W8yQFw3dtscbEi9LKJevr20V7uWs2MPGTnvNZ3rm8anhhE16gXGpxDOHeg9raySaSHKhd4IGa3YZvuw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-ppc64-gnu@0.120.0': - resolution: {integrity: sha512-T/kZuU0ajop0xhzVMwH5r3srC9Nqup5HaIo+3uFjIN5uPxa0LvSxC1ZqP4aQGJVW5G0z8/nCkjIfSMS91P/wzw==} + '@oxc-parser/binding-linux-ppc64-gnu@0.121.0': + resolution: {integrity: sha512-mYNe4NhVvDBbPkAP8JaVS8lC1dsoJZWH5WCjpw5E+sjhk1R08wt3NnXYUzum7tIiWPfgQxbCMcoxgeemFASbRw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-gnu@0.120.0': - resolution: {integrity: sha512-vn21KXLAXzaI3N5CZWlBr1iWeXLl9QFIMor7S1hUjUGTeUuWCoE6JZB040/ZNDwf+JXPX8Ao9KbmJq9FMC2iGw==} + '@oxc-parser/binding-linux-riscv64-gnu@0.121.0': + resolution: {integrity: sha512-+QiFoGxhAbaI/amqX567784cDyyuZIpinBrJNxUzb+/L2aBRX67mN6Jv40pqduHf15yYByI+K5gUEygCuv0z9w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-musl@0.120.0': - resolution: {integrity: sha512-SUbUxlar007LTGmSLGIC5x/WJvwhdX+PwNzFJ9f/nOzZOrCFbOT4ikt7pJIRg1tXVsEfzk5mWpGO1NFiSs4PIw==} + '@oxc-parser/binding-linux-riscv64-musl@0.121.0': + resolution: {integrity: sha512-9ykEgyTa5JD/Uhv2sttbKnCfl2PieUfOjyxJC/oDL2UO0qtXOtjPLl7H8Kaj5G7p3hIvFgu3YWvAxvE0sqY+hQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-s390x-gnu@0.120.0': - resolution: {integrity: sha512-hYiPJTxyfJY2+lMBFk3p2bo0R9GN+TtpPFlRqVchL1qvLG+pznstramHNvJlw9AjaoRUHwp9IKR7UZQnRPGjgQ==} + '@oxc-parser/binding-linux-s390x-gnu@0.121.0': + resolution: {integrity: sha512-DB1EW5VHZdc1lIRjOI3bW/wV6R6y0xlfvdVrqj6kKi7Ayu2U3UqUBdq9KviVkcUGd5Oq+dROqvUEEFRXGAM7EQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-gnu@0.120.0': - resolution: {integrity: sha512-q+5jSVZkprJCIy3dzJpApat0InJaoxQLsJuD6DkX8hrUS61z2lHQ1Fe9L2+TYbKHXCLWbL0zXe7ovkIdopBGMQ==} + '@oxc-parser/binding-linux-x64-gnu@0.121.0': + resolution: {integrity: sha512-s4lfobX9p4kPTclvMiH3gcQUd88VlnkMTF6n2MTMDAyX5FPNRhhRSFZK05Ykhf8Zy5NibV4PbGR6DnK7FGNN6A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-musl@0.120.0': - resolution: {integrity: sha512-D9QDDZNnH24e7X4ftSa6ar/2hCavETfW3uk0zgcMIrZNy459O5deTbWrjGzZiVrSWigGtlQwzs2McBP0QsfV1w==} + '@oxc-parser/binding-linux-x64-musl@0.121.0': + resolution: {integrity: sha512-P9KlyTpuBuMi3NRGpJO8MicuGZfOoqZVRP1WjOecwx8yk4L/+mrCRNc5egSi0byhuReblBF2oVoDSMgV9Bj4Hw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-parser/binding-openharmony-arm64@0.120.0': - resolution: {integrity: sha512-TBU8ZwOUWAOUWVfmI16CYWbvh4uQb9zHnGBHsw5Cp2JUVG044OIY1CSHODLifqzQIMTXvDvLzcL89GGdUIqNrA==} + '@oxc-parser/binding-openharmony-arm64@0.121.0': + resolution: {integrity: sha512-R+4jrWOfF2OAPPhj3Eb3U5CaKNAH9/btMveMULIrcNW/hjfysFQlF8wE0GaVBr81dWz8JLgQlsxwctoL78JwXw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxc-parser/binding-wasm32-wasi@0.120.0': - resolution: {integrity: sha512-WG/FOZgDJCpJnuF3ToG/K28rcOmSY7FmFmfBKYb2fmLyhDzPpUldFGV7/Fz4ru0Iz/v4KPmf8xVgO8N3lO4KHA==} + '@oxc-parser/binding-wasm32-wasi@0.121.0': + resolution: {integrity: sha512-5TFISkPTymKvsmIlKasPVTPuWxzCcrT8pM+p77+mtQbIZDd1UC8zww4CJcRI46kolmgrEX6QpKO8AvWMVZ+ifw==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@oxc-parser/binding-win32-arm64-msvc@0.120.0': - resolution: {integrity: sha512-1T0HKGcsz/BKo77t7+89L8Qvu4f9DoleKWHp3C5sJEcbCjDOLx3m9m722bWZTY+hANlUEs+yjlK+lBFsA+vrVQ==} + '@oxc-parser/binding-win32-arm64-msvc@0.121.0': + resolution: {integrity: sha512-V0pxh4mql4XTt3aiEtRNUeBAUFOw5jzZNxPABLaOKAWrVzSr9+XUaB095lY7jqMf5t8vkfh8NManGB28zanYKw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-ia32-msvc@0.120.0': - resolution: {integrity: sha512-L7vfLzbOXsjBXV0rv/6Y3Jd9BRjPeCivINZAqrSyAOZN3moCopDN+Psq9ZrGNZtJzP8946MtlRFZ0Als0wBCOw==} + '@oxc-parser/binding-win32-ia32-msvc@0.121.0': + resolution: {integrity: sha512-4Ob1qvYMPnlF2N9rdmKdkQFdrq16QVcQwBsO8yiPZXof0fHKFF+LmQV501XFbi7lHyrKm8rlJRfQ/M8bZZPVLw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.120.0': - resolution: {integrity: sha512-ys+upfqNtSu58huAhJMBKl3XCkGzyVFBlMlGPzHeFKgpFF/OdgNs1MMf8oaJIbgMH8ZxgGF7qfue39eJohmKIg==} + '@oxc-parser/binding-win32-x64-msvc@0.121.0': + resolution: {integrity: sha512-BOp1KCzdboB1tPqoCPXgntgFs0jjeSyOXHzgxVFR7B/qfr3F8r4YDacHkTOUNXtDgM8YwKnkf3rE5gwALYX7NA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@oxc-project/runtime@0.120.0': - resolution: {integrity: sha512-7fvACzS46TkHuzA+Tag8ac40qfwURXRTdc4AtyItF59AoNPOO/QjPMqPyvJH8CaUdGu0ntWDX1CCUNyLMxxX5g==} + '@oxc-project/runtime@0.121.0': + resolution: {integrity: sha512-p0bQukD8OEHxzY4T9OlANBbEFGnOnjo1CYi50HES7OD36UO2yPh6T+uOJKLtlg06eclxroipRCpQGMpeH8EJ/g==} engines: {node: ^20.19.0 || >=22.12.0} - '@oxc-project/types@0.120.0': - resolution: {integrity: sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==} + '@oxc-project/types@0.121.0': + resolution: {integrity: sha512-CGtOARQb9tyv7ECgdAlFxi0Fv7lmzvmlm2rpD/RdijOO9rfk/JvB1CjT8EnoD+tjna/IYgKKw3IV7objRb+aYw==} + + '@oxc-project/types@0.122.0': + resolution: {integrity: sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==} '@oxc-resolver/binding-android-arm-eabi@11.19.1': resolution: {integrity: sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==} @@ -2060,276 +2702,276 @@ packages: cpu: [x64] os: [win32] - '@oxfmt/binding-android-arm-eabi@0.41.0': - resolution: {integrity: sha512-REfrqeMKGkfMP+m/ScX4f5jJBSmVNYcpoDF8vP8f8eYPDuPGZmzp56NIUsYmx3h7f6NzC6cE3gqh8GDWrJHCKw==} + '@oxfmt/binding-android-arm-eabi@0.42.0': + resolution: {integrity: sha512-dsqPTYsozeokRjlrt/b4E7Pj0z3eS3Eg74TWQuuKbjY4VttBmA88rB7d50Xrd+TZ986qdXCNeZRPEzZHAe+jow==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxfmt/binding-android-arm64@0.41.0': - resolution: {integrity: sha512-s0b1dxNgb2KomspFV2LfogC2XtSJB42POXF4bMCLJyvQmAGos4ZtjGPfQreToQEaY0FQFjz3030ggI36rF1q5g==} + '@oxfmt/binding-android-arm64@0.42.0': + resolution: {integrity: sha512-t+aAjHxcr5eOBphFHdg1ouQU9qmZZoRxnX7UOJSaTwSoKsb6TYezNKO0YbWytGXCECObRqNcUxPoPr0KaraAIg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxfmt/binding-darwin-arm64@0.41.0': - resolution: {integrity: sha512-EGXGualADbv/ZmamE7/2DbsrYmjoPlAmHEpTL4vapLF4EfVD6fr8/uQDFnPJkUBjiSWFJZtFNsGeN1B6V3owmA==} + '@oxfmt/binding-darwin-arm64@0.42.0': + resolution: {integrity: sha512-ulpSEYMKg61C5bRMZinFHrKJYRoKGVbvMEXA5zM1puX3O9T6Q4XXDbft20yrDijpYWeuG59z3Nabt+npeTsM1A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxfmt/binding-darwin-x64@0.41.0': - resolution: {integrity: sha512-WxySJEvdQQYMmyvISH3qDpTvoS0ebnIP63IMxLLWowJyPp/AAH0hdWtlo+iGNK5y3eVfa5jZguwNaQkDKWpGSw==} + '@oxfmt/binding-darwin-x64@0.42.0': + resolution: {integrity: sha512-ttxLKhQYPdFiM8I/Ri37cvqChE4Xa562nNOsZFcv1CKTVLeEozXjKuYClNvxkXmNlcF55nzM80P+CQkdFBu+uQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxfmt/binding-freebsd-x64@0.41.0': - resolution: {integrity: sha512-Y2kzMkv3U3oyuYaR4wTfGjOTYTXiFC/hXmG0yVASKkbh02BJkvD98Ij8bIevr45hNZ0DmZEgqiXF+9buD4yMYQ==} + '@oxfmt/binding-freebsd-x64@0.42.0': + resolution: {integrity: sha512-Og7QS3yI3tdIKYZ58SXik0rADxIk2jmd+/YvuHRyKULWpG4V2fR5V4hvKm624Mc0cQET35waPXiCQWvjQEjwYQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxfmt/binding-linux-arm-gnueabihf@0.41.0': - resolution: {integrity: sha512-ptazDjdUyhket01IjPTT6ULS1KFuBfTUU97osTP96X5y/0oso+AgAaJzuH81oP0+XXyrWIHbRzozSAuQm4p48g==} + '@oxfmt/binding-linux-arm-gnueabihf@0.42.0': + resolution: {integrity: sha512-jwLOw/3CW4H6Vxcry4/buQHk7zm9Ne2YsidzTL1kpiMe4qqrRCwev3dkyWe2YkFmP+iZCQ7zku4KwjcLRoh8ew==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm-musleabihf@0.41.0': - resolution: {integrity: sha512-UkoL2OKxFD+56bPEBcdGn+4juTW4HRv/T6w1dIDLnvKKWr6DbarB/mtHXlADKlFiJubJz8pRkttOR7qjYR6lTA==} + '@oxfmt/binding-linux-arm-musleabihf@0.42.0': + resolution: {integrity: sha512-XwXu2vkMtiq2h7tfvN+WA/9/5/1IoGAVCFPiiQUvcAuG3efR97KNcRGM8BetmbYouFotQ2bDal3yyjUx6IPsTg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm64-gnu@0.41.0': - resolution: {integrity: sha512-gofu0PuumSOHYczD8p62CPY4UF6ee+rSLZJdUXkpwxg6pILiwSDBIouPskjF/5nF3A7QZTz2O9KFNkNxxFN9tA==} + '@oxfmt/binding-linux-arm64-gnu@0.42.0': + resolution: {integrity: sha512-ea7s/XUJoT7ENAtUQDudFe3nkSM3e3Qpz4nJFRdzO2wbgXEcjnchKLEsV3+t4ev3r8nWxIYr9NRjPWtnyIFJVA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-arm64-musl@0.41.0': - resolution: {integrity: sha512-VfVZxL0+6RU86T8F8vKiDBa+iHsr8PAjQmKGBzSCAX70b6x+UOMFl+2dNihmKmUwqkCazCPfYjt6SuAPOeQJ3g==} + '@oxfmt/binding-linux-arm64-musl@0.42.0': + resolution: {integrity: sha512-+JA0YMlSdDqmacygGi2REp57c3fN+tzARD8nwsukx9pkCHK+6DkbAA9ojS4lNKsiBjIW8WWa0pBrBWhdZEqfuw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxfmt/binding-linux-ppc64-gnu@0.41.0': - resolution: {integrity: sha512-bwzokz2eGvdfJbc0i+zXMJ4BBjQPqg13jyWpEEZDOrBCQ91r8KeY2Mi2kUeuMTZNFXju+jcAbAbpyJxRGla0eg==} + '@oxfmt/binding-linux-ppc64-gnu@0.42.0': + resolution: {integrity: sha512-VfnET0j4Y5mdfCzh5gBt0NK28lgn5DKx+8WgSMLYYeSooHhohdbzwAStLki9pNuGy51y4I7IoW8bqwAaCMiJQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-riscv64-gnu@0.41.0': - resolution: {integrity: sha512-POLM//PCH9uqDeNDwWL3b3DkMmI3oI2cU6hwc2lnztD1o7dzrQs3R9nq555BZ6wI7t2lyhT9CS+CRaz5X0XqLA==} + '@oxfmt/binding-linux-riscv64-gnu@0.42.0': + resolution: {integrity: sha512-gVlCbmBkB0fxBWbhBj9rcxezPydsQHf4MFKeHoTSPicOQ+8oGeTQgQ8EeesSybWeiFPVRx3bgdt4IJnH6nOjAA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-riscv64-musl@0.41.0': - resolution: {integrity: sha512-NNK7PzhFqLUwx/G12Xtm6scGv7UITvyGdAR5Y+TlqsG+essnuRWR4jRNODWRjzLZod0T3SayRbnkSIWMBov33w==} + '@oxfmt/binding-linux-riscv64-musl@0.42.0': + resolution: {integrity: sha512-zN5OfstL0avgt/IgvRu0zjQzVh/EPkcLzs33E9LMAzpqlLWiPWeMDZyMGFlSRGOdDjuNmlZBCgj0pFnK5u32TQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxfmt/binding-linux-s390x-gnu@0.41.0': - resolution: {integrity: sha512-qVf/zDC5cN9eKe4qI/O/m445er1IRl6swsSl7jHkqmOSVfknwCe5JXitYjZca+V/cNJSU/xPlC5EFMabMMFDpw==} + '@oxfmt/binding-linux-s390x-gnu@0.42.0': + resolution: {integrity: sha512-9X6+H2L0qMc2sCAgO9HS03bkGLMKvOFjmEdchaFlany3vNZOjnVui//D8k/xZAtQv2vaCs1reD5KAgPoIU4msA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-x64-gnu@0.41.0': - resolution: {integrity: sha512-ojxYWu7vUb6ysYqVCPHuAPVZHAI40gfZ0PDtZAMwVmh2f0V8ExpPIKoAKr7/8sNbAXJBBpZhs2coypIo2jJX4w==} + '@oxfmt/binding-linux-x64-gnu@0.42.0': + resolution: {integrity: sha512-BajxJ6KQvMMdpXGPWhBGyjb2Jvx4uec0w+wi6TJZ6Tv7+MzPwe0pO8g5h1U0jyFgoaF7mDl6yKPW3ykWcbUJRw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-x64-musl@0.41.0': - resolution: {integrity: sha512-O2exZLBxoCMIv2vlvcbkdedazJPTdG0VSup+0QUCfYQtx751zCZNboX2ZUOiQ/gDTdhtXvSiot0h6GEGkOyalA==} + '@oxfmt/binding-linux-x64-musl@0.42.0': + resolution: {integrity: sha512-0wV284I6vc5f0AqAhgAbHU2935B4bVpncPoe5n/WzVZY/KnHgqxC8iSFGeSyLWEgstFboIcWkOPck7tqbdHkzA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxfmt/binding-openharmony-arm64@0.41.0': - resolution: {integrity: sha512-N+31/VoL+z+NNBt8viy3I4NaIdPbiYeOnB884LKqvXldaE2dRztdPv3q5ipfZYv0RwFp7JfqS4I27K/DSHCakg==} + '@oxfmt/binding-openharmony-arm64@0.42.0': + resolution: {integrity: sha512-p4BG6HpGnhfgHk1rzZfyR6zcWkE7iLrWxyehHfXUy4Qa5j3e0roglFOdP/Nj5cJJ58MA3isQ5dlfkW2nNEpolw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxfmt/binding-win32-arm64-msvc@0.41.0': - resolution: {integrity: sha512-Z7NAtu/RN8kjCQ1y5oDD0nTAeRswh3GJ93qwcW51srmidP7XPBmZbLlwERu1W5veCevQJtPS9xmkpcDTYsGIwQ==} + '@oxfmt/binding-win32-arm64-msvc@0.42.0': + resolution: {integrity: sha512-mn//WV60A+IetORDxYieYGAoQso4KnVRRjORDewMcod4irlRe0OSC7YPhhwaexYNPQz/GCFk+v9iUcZ2W22yxQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxfmt/binding-win32-ia32-msvc@0.41.0': - resolution: {integrity: sha512-uNxxP3l4bJ6VyzIeRqCmBU2Q0SkCFgIhvx9/9dJ9V8t/v+jP1IBsuaLwCXGR8JPHtkj4tFp+RHtUmU2ZYAUpMA==} + '@oxfmt/binding-win32-ia32-msvc@0.42.0': + resolution: {integrity: sha512-3gWltUrvuz4LPJXWivoAxZ28Of2O4N7OGuM5/X3ubPXCEV8hmgECLZzjz7UYvSDUS3grfdccQwmjynm+51EFpw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxfmt/binding-win32-x64-msvc@0.41.0': - resolution: {integrity: sha512-49ZSpbZ1noozyPapE8SUOSm3IN0Ze4b5nkO+4+7fq6oEYQQJFhE0saj5k/Gg4oewVPdjn0L3ZFeWk2Vehjcw7A==} + '@oxfmt/binding-win32-x64-msvc@0.42.0': + resolution: {integrity: sha512-Wg4TMAfQRL9J9AZevJ/ZNy3uyyDztDYQtGr4P8UyyzIhLhFrdSmz1J/9JT+rv0fiCDLaFOBQnj3f3K3+a5PzDQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@oxlint-tsgolint/darwin-arm64@0.17.1': - resolution: {integrity: sha512-JNWNwyvSDcUQSBlQRl10XrCeNcN66TMvDw3gIDQeop5SNa1F7wFhsEx4zitYb7fGHwGh9095tsNttmuCaNXCbw==} + '@oxlint-tsgolint/darwin-arm64@0.17.3': + resolution: {integrity: sha512-5aDl4mxXWs+Bj02pNrX6YY6v9KMZjLIytXoqolLEo0dfBNVeZUonZgJAa/w0aUmijwIRrBhxEzb42oLuUtfkGw==} cpu: [arm64] os: [darwin] - '@oxlint-tsgolint/darwin-x64@0.17.1': - resolution: {integrity: sha512-SluNf6CW88pgGPqQUGC5GoK5qESWo2ct1PRDbza3vbf9SK2npx3igvylGQIgE9qYYOcjgnVdLOJ0+q0gItgUmQ==} + '@oxlint-tsgolint/darwin-x64@0.17.3': + resolution: {integrity: sha512-gPBy4DS5ueCgXzko20XsNZzDe/Cxde056B+QuPLGvz05CGEAtmRfpImwnyY2lAXXjPL+SmnC/OYexu8zI12yHQ==} cpu: [x64] os: [darwin] - '@oxlint-tsgolint/linux-arm64@0.17.1': - resolution: {integrity: sha512-BJxQ7/cdo2dNdGIBs2PIR6BaPA7cPfe+r1HE/uY+K7g2ygip+0LHB3GUO9GaNDZuWpsnDyjLYYowEGrVK8dokA==} + '@oxlint-tsgolint/linux-arm64@0.17.3': + resolution: {integrity: sha512-+pkunvCfB6pB0G9qHVVXUao3nqzXQPo4O3DReIi+5nGa+bOU3J3Srgy+Zb8VyOL+WDsSMJ+U7+r09cKHWhz3hg==} cpu: [arm64] os: [linux] - '@oxlint-tsgolint/linux-x64@0.17.1': - resolution: {integrity: sha512-s6UjmuaJbZ4zz/wJKdEw/s5mc0t41rgwxQJCSHPuzMumMK6ylrB7nydhDf8ObTtzhTIZdAS/2S/uayJmDcGbxw==} + '@oxlint-tsgolint/linux-x64@0.17.3': + resolution: {integrity: sha512-/kW5oXtBThu4FjmgIBthdmMjWLzT3M1TEDQhxDu7hQU5xDeTd60CDXb2SSwKCbue9xu7MbiFoJu83LN0Z/d38g==} cpu: [x64] os: [linux] - '@oxlint-tsgolint/win32-arm64@0.17.1': - resolution: {integrity: sha512-EO/Oj0ixHX+UQdu9hM7YUzibZI888MvPUo/DF8lSxFBt4JNEt8qGkwJEbCYjB/1LhUNmPHzSw2Tr9dCFVfW9nw==} + '@oxlint-tsgolint/win32-arm64@0.17.3': + resolution: {integrity: sha512-NMELRvbz4Ed4dxg8WiqZxtu3k4OJEp2B9KInZW+BMfqEqbwZdEJY83tbqz2hD1EjKO2akrqBQ0GpRUJEkd8kKw==} cpu: [arm64] os: [win32] - '@oxlint-tsgolint/win32-x64@0.17.1': - resolution: {integrity: sha512-jhv7XktAJ1sMRSb//yDYTauFSZ06H81i2SLEBPaSUKxSKoPMK8p1ACUJlnmwZX2MgapRLEj1Ml22B6+HiM2YIA==} + '@oxlint-tsgolint/win32-x64@0.17.3': + resolution: {integrity: sha512-+pJ7r8J3SLPws5uoidVplZc8R/lpKyKPE6LoPGv9BME00Y1VjT6jWGx/dtUN8PWvcu3iTC6k+8u3ojFSJNmWTg==} cpu: [x64] os: [win32] - '@oxlint/binding-android-arm-eabi@1.56.0': - resolution: {integrity: sha512-IyfYPthZyiSKwAv/dLjeO18SaK8MxLI9Yss2JrRDyweQAkuL3LhEy7pwIwI7uA3KQc1Vdn20kdmj3q0oUIQL6A==} + '@oxlint/binding-android-arm-eabi@1.57.0': + resolution: {integrity: sha512-C7EiyfAJG4B70496eV543nKiq5cH0o/xIh/ufbjQz3SIvHhlDDsyn+mRFh+aW8KskTyUpyH2LGWL8p2oN6bl1A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxlint/binding-android-arm64@1.56.0': - resolution: {integrity: sha512-Ga5zYrzH6vc/VFxhn6MmyUnYEfy9vRpwTIks99mY3j6Nz30yYpIkWryI0QKPCgvGUtDSXVLEaMum5nA+WrNOSg==} + '@oxlint/binding-android-arm64@1.57.0': + resolution: {integrity: sha512-9i80AresjZ/FZf5xK8tKFbhQnijD4s1eOZw6/FHUwD59HEZbVLRc2C88ADYJfLZrF5XofWDiRX/Ja9KefCLy7w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxlint/binding-darwin-arm64@1.56.0': - resolution: {integrity: sha512-ogmbdJysnw/D4bDcpf1sPLpFThZ48lYp4aKYm10Z/6Nh1SON6NtnNhTNOlhEY296tDFItsZUz+2tgcSYqh8Eyw==} + '@oxlint/binding-darwin-arm64@1.57.0': + resolution: {integrity: sha512-0eUfhRz5L2yKa9I8k3qpyl37XK3oBS5BvrgdVIx599WZK63P8sMbg+0s4IuxmIiZuBK68Ek+Z+gcKgeYf0otsg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-x64@1.56.0': - resolution: {integrity: sha512-x8QE1h+RAtQ2g+3KPsP6Fk/tdz6zJQUv5c7fTrJxXV3GHOo+Ry5p/PsogU4U+iUZg0rj6hS+E4xi+mnwwlDCWQ==} + '@oxlint/binding-darwin-x64@1.57.0': + resolution: {integrity: sha512-UvrSuzBaYOue+QMAcuDITe0k/Vhj6KZGjfnI6x+NkxBTke/VoM7ZisaxgNY0LWuBkTnd1OmeQfEQdQ48fRjkQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxlint/binding-freebsd-x64@1.56.0': - resolution: {integrity: sha512-6G+WMZvwJpMvY7my+/SHEjb7BTk/PFbePqLpmVmUJRIsJMy/UlyYqjpuh0RCgYYkPLcnXm1rUM04kbTk8yS1Yg==} + '@oxlint/binding-freebsd-x64@1.57.0': + resolution: {integrity: sha512-wtQq0dCoiw4bUwlsNVDJJ3pxJA218fOezpgtLKrbQqUtQJcM9yP8z+I9fu14aHg0uyAxIY+99toL6uBa2r7nxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxlint/binding-linux-arm-gnueabihf@1.56.0': - resolution: {integrity: sha512-YYHBsk/sl7fYwQOok+6W5lBPeUEvisznV/HZD2IfZmF3Bns6cPC3Z0vCtSEOaAWTjYWN3jVsdu55jMxKlsdlhg==} + '@oxlint/binding-linux-arm-gnueabihf@1.57.0': + resolution: {integrity: sha512-qxFWl2BBBFcT4djKa+OtMdnLgoHEJXpqjyGwz8OhW35ImoCwR5qtAGqApNYce5260FQqoAHW8S8eZTjiX67Tsg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.56.0': - resolution: {integrity: sha512-+AZK8rOUr78y8WT6XkDb04IbMRqauNV+vgT6f8ZLOH8wnpQ9i7Nol0XLxAu+Cq7Sb+J9wC0j6Km5hG8rj47/yQ==} + '@oxlint/binding-linux-arm-musleabihf@1.57.0': + resolution: {integrity: sha512-SQoIsBU7J0bDW15/f0/RvxHfY3Y0+eB/caKBQtNFbuerTiA6JCYx9P1MrrFTwY2dTm/lMgTSgskvCEYk2AtG/Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm64-gnu@1.56.0': - resolution: {integrity: sha512-urse2SnugwJRojUkGSSeH2LPMaje5Q50yQtvtL9HFckiyeqXzoFwOAZqD5TR29R2lq7UHidfFDM9EGcchcbb8A==} + '@oxlint/binding-linux-arm64-gnu@1.57.0': + resolution: {integrity: sha512-jqxYd1W6WMeozsCmqe9Rzbu3SRrGTyGDAipRlRggetyYbUksJqJKvUNTQtZR/KFoJPb+grnSm5SHhdWrywv3RQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-arm64-musl@1.56.0': - resolution: {integrity: sha512-rkTZkBfJ4TYLjansjSzL6mgZOdN5IvUnSq3oNJSLwBcNvy3dlgQtpHPrRxrCEbbcp7oQ6If0tkNaqfOsphYZ9g==} + '@oxlint/binding-linux-arm64-musl@1.57.0': + resolution: {integrity: sha512-i66WyEPVEvq9bxRUCJ/MP5EBfnTDN3nhwEdFZFTO5MmLLvzngfWEG3NSdXQzTT3vk5B9i6C2XSIYBh+aG6uqyg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxlint/binding-linux-ppc64-gnu@1.56.0': - resolution: {integrity: sha512-uqL1kMH3u69/e1CH2EJhP3CP28jw2ExLsku4o8RVAZ7fySo9zOyI2fy9pVlTAp4voBLVgzndXi3SgtdyCTa2aA==} + '@oxlint/binding-linux-ppc64-gnu@1.57.0': + resolution: {integrity: sha512-oMZDCwz4NobclZU3pH+V1/upVlJZiZvne4jQP+zhJwt+lmio4XXr4qG47CehvrW1Lx2YZiIHuxM2D4YpkG3KVA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-gnu@1.56.0': - resolution: {integrity: sha512-j0CcMBOgV6KsRaBdsebIeiy7hCjEvq2KdEsiULf2LZqAq0v1M1lWjelhCV57LxsqaIGChXFuFJ0RiFrSRHPhSg==} + '@oxlint/binding-linux-riscv64-gnu@1.57.0': + resolution: {integrity: sha512-uoBnjJ3MMEBbfnWC1jSFr7/nSCkcQYa72NYoNtLl1imshDnWSolYCjzb8LVCwYCCfLJXD+0gBLD7fyC14c0+0g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-musl@1.56.0': - resolution: {integrity: sha512-7VDOiL8cDG3DQ/CY3yKjbV1c4YPvc4vH8qW09Vv+5ukq3l/Kcyr6XGCd5NvxUmxqDb2vjMpM+eW/4JrEEsUetA==} + '@oxlint/binding-linux-riscv64-musl@1.57.0': + resolution: {integrity: sha512-BdrwD7haPZ8a9KrZhKJRSj6jwCor+Z8tHFZ3PT89Y3Jq5v3LfMfEePeAmD0LOTWpiTmzSzdmyw9ijneapiVHKQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxlint/binding-linux-s390x-gnu@1.56.0': - resolution: {integrity: sha512-JGRpX0M+ikD3WpwJ7vKcHKV6Kg0dT52BW2Eu2BupXotYeqGXBrbY+QPkAyKO6MNgKozyTNaRh3r7g+VWgyAQYQ==} + '@oxlint/binding-linux-s390x-gnu@1.57.0': + resolution: {integrity: sha512-BNs+7ZNsRstVg2tpNxAXfMX/Iv5oZh204dVyb8Z37+/gCh+yZqNTlg6YwCLIMPSk5wLWIGOaQjT0GUOahKYImw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-gnu@1.56.0': - resolution: {integrity: sha512-dNaICPvtmuxFP/VbqdofrLqdS3bM/AKJN3LMJD52si44ea7Be1cBk6NpfIahaysG9Uo+L98QKddU9CD5L8UHnQ==} + '@oxlint/binding-linux-x64-gnu@1.57.0': + resolution: {integrity: sha512-AghS18w+XcENcAX0+BQGLiqjpqpaxKJa4cWWP0OWNLacs27vHBxu7TYkv9LUSGe5w8lOJHeMxcYfZNOAPqw2bg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-musl@1.56.0': - resolution: {integrity: sha512-pF1vOtM+GuXmbklM1hV8WMsn6tCNPvkUzklj/Ej98JhlanbmA2RB1BILgOpwSuCTRTIYx2MXssmEyQQ90QF5aA==} + '@oxlint/binding-linux-x64-musl@1.57.0': + resolution: {integrity: sha512-E/FV3GB8phu/Rpkhz5T96hAiJlGzn91qX5yj5gU754P5cmVGXY1Jw/VSjDSlZBCY3VHjsVLdzgdkJaomEmcNOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxlint/binding-openharmony-arm64@1.56.0': - resolution: {integrity: sha512-bp8NQ4RE6fDIFLa4bdBiOA+TAvkNkg+rslR+AvvjlLTYXLy9/uKAYLQudaQouWihLD/hgkrXIKKzXi5IXOewwg==} + '@oxlint/binding-openharmony-arm64@1.57.0': + resolution: {integrity: sha512-xvZ2yZt0nUVfU14iuGv3V25jpr9pov5N0Wr28RXnHFxHCRxNDMtYPHV61gGLhN9IlXM96gI4pyYpLSJC5ClLCQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxlint/binding-win32-arm64-msvc@1.56.0': - resolution: {integrity: sha512-PxT4OJDfMOQBzo3OlzFb9gkoSD+n8qSBxyVq2wQSZIHFQYGEqIRTo9M0ZStvZm5fdhMqaVYpOnJvH2hUMEDk/g==} + '@oxlint/binding-win32-arm64-msvc@1.57.0': + resolution: {integrity: sha512-Z4D8Pd0AyHBKeazhdIXeUUy5sIS3Mo0veOlzlDECg6PhRRKgEsBJCCV1n+keUZtQ04OP+i7+itS3kOykUyNhDg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.56.0': - resolution: {integrity: sha512-PTRy6sIEPqy2x8PTP1baBNReN/BNEFmde0L+mYeHmjXE1Vlcc9+I5nsqENsB2yAm5wLkzPoTNCMY/7AnabT4/A==} + '@oxlint/binding-win32-ia32-msvc@1.57.0': + resolution: {integrity: sha512-StOZ9nFMVKvevicbQfql6Pouu9pgbeQnu60Fvhz2S6yfMaii+wnueLnqQ5I1JPgNF0Syew4voBlAaHD13wH6tw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.56.0': - resolution: {integrity: sha512-ZHa0clocjLmIDr+1LwoWtxRcoYniAvERotvwKUYKhH41NVfl0Y4LNbyQkwMZzwDvKklKGvGZ5+DAG58/Ik47tQ==} + '@oxlint/binding-win32-x64-msvc@1.57.0': + resolution: {integrity: sha512-6PuxhYgth8TuW0+ABPOIkGdBYw+qYGxgIdXPHSVpiCDm+hqTTWCmC739St1Xni0DJBt8HnSHTG67i1y6gr8qrA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -2426,6 +3068,11 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@playwright/test@1.58.2': + resolution: {integrity: sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==} + engines: {node: '>=18'} + hasBin: true + '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} @@ -2714,6 +3361,104 @@ packages: resolution: {integrity: sha512-UuBOt7BOsKVOkFXRe4Ypd/lADuNIfqJXv8GvHqtXaTYXPPKkj2nS2zPllVsrtRjcomDhIJVBnZwfmlI222WH8g==} engines: {node: '>=14.0.0'} + '@rolldown/binding-android-arm64@1.0.0-rc.12': + resolution: {integrity: sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-rc.12': + resolution: {integrity: sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-rc.12': + resolution: {integrity: sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-rc.12': + resolution: {integrity: sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12': + resolution: {integrity: sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.12': + resolution: {integrity: sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.12': + resolution: {integrity: sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.12': + resolution: {integrity: sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.12': + resolution: {integrity: sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.12': + resolution: {integrity: sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12': + resolution: {integrity: sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.12': + resolution: {integrity: sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-rc.12': + resolution: {integrity: sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==} + '@rolldown/pluginutils@1.0.0-rc.5': resolution: {integrity: sha512-RxlLX/DPoarZ9PtxVrQgZhPoor987YtKQqCo5zkjX+0S0yLJ7Vv515Wk6+xtTL67VONKJKxETWZwuZjss2idYw==} @@ -2876,32 +3621,32 @@ packages: cpu: [x64] os: [win32] - '@sentry-internal/browser-utils@10.45.0': - resolution: {integrity: sha512-ZPZpeIarXKScvquGx2AfNKcYiVNDA4wegMmjyGVsTA2JPmP0TrJoO3UybJS6KGDeee8V3I3EfD/ruauMm7jOFQ==} + '@sentry-internal/browser-utils@10.46.0': + resolution: {integrity: sha512-WB1gBT9G13V02ekZ6NpUhoI1aGHV2eNfjEPthkU2bGBvFpQKnstwzjg7waIRGR7cu+YSW2Q6UI6aQLgBeOPD1g==} engines: {node: '>=18'} - '@sentry-internal/feedback@10.45.0': - resolution: {integrity: sha512-vCSurazFVq7RUeYiM5X326jA5gOVrWYD6lYX2fbjBOMcyCEhDnveNxMT62zKkZDyNT/jyD194nz/cjntBUkyWA==} + '@sentry-internal/feedback@10.46.0': + resolution: {integrity: sha512-c4pI/z9nZCQXe9GYEw/hE/YTY9AxGBp8/wgKI+T8zylrN35SGHaXv63szzE1WbI8lacBY8lBF7rstq9bQVCaHw==} engines: {node: '>=18'} - '@sentry-internal/replay-canvas@10.45.0': - resolution: {integrity: sha512-nvq/AocdZTuD7y0KSiWi3gVaY0s5HOFy86mC/v1kDZmT/jsBAzN5LDkk/f1FvsWma1peqQmpUqxvhC+YIW294Q==} + '@sentry-internal/replay-canvas@10.46.0': + resolution: {integrity: sha512-ub314MWUsekVCuoH0/HJbbimlI24SkV745UW2pj9xRbxOAEf1wjkmIzxKrMDbTgJGuEunug02XZVdJFJUzOcDw==} engines: {node: '>=18'} - '@sentry-internal/replay@10.45.0': - resolution: {integrity: sha512-vjosRoGA1bzhVAEO1oce+CsRdd70quzBeo7WvYqpcUnoLe/Rv8qpOMqWX3j26z7XfFHMExWQNQeLxmtYOArvlw==} + '@sentry-internal/replay@10.46.0': + resolution: {integrity: sha512-JBsWeXG6bRbxBFK8GzWymWGOB9QE7Kl57BeF3jzgdHTuHSWZ2mRnAmb1K05T4LU+gVygk6yW0KmdC8Py9Qzg9A==} engines: {node: '>=18'} - '@sentry/browser@10.45.0': - resolution: {integrity: sha512-e/a8UMiQhqqv706McSIcG6XK+AoQf9INthi2pD+giZfNRTzXTdqHzUT5OIO5hg8Am6eF63nDJc+vrYNPhzs51Q==} + '@sentry/browser@10.46.0': + resolution: {integrity: sha512-80DmGlTk5Z2/OxVOzLNxwolMyouuAYKqG8KUcoyintZqHbF6kO1RulI610HmyUt3OagKeBCqt9S7w0VIfCRL+Q==} engines: {node: '>=18'} - '@sentry/core@10.45.0': - resolution: {integrity: sha512-s69UXxvefeQxuZ5nY7/THtTrIEvJxNVCp3ns4kwoCw1qMpgpvn/296WCKVmM7MiwnaAdzEKnAvLAwaxZc2nM7Q==} + '@sentry/core@10.46.0': + resolution: {integrity: sha512-N3fj4zqBQOhXliS1Ne9euqIKuciHCGOJfPGQLwBoW9DNz03jF+NB8+dUKtrJ79YLoftjVgf8nbgwtADK7NR+2Q==} engines: {node: '>=18'} - '@sentry/react@10.45.0': - resolution: {integrity: sha512-jLezuxi4BUIU3raKyAPR5xMbQG/nhwnWmKo5p11NCbLmWzkS+lxoyDTUB4B8TAKZLfdtdkKLOn1S0tFc8vbUHw==} + '@sentry/react@10.46.0': + resolution: {integrity: sha512-Rb1S+9OuUPVwsz7GWnQ6Kgf3azbsseUymIegg3JZHNcW/fM1nPpaljzTBnuineia113DH0pgMBcdrrZDLaosFQ==} engines: {node: '>=18'} peerDependencies: react: ^16.14.0 || 17.x || 18.x || 19.x @@ -2951,42 +3696,42 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@storybook/addon-docs@10.3.1': - resolution: {integrity: sha512-0FBhfMEg96QUmhdtks3rchktEEWF2hKcEsr3XluybBoBi4xAIw1vm+RJtL9Jm45ppTdg28LF7U+OeMx5LwkMzQ==} + '@storybook/addon-docs@10.3.3': + resolution: {integrity: sha512-trJQTpOtuOEuNv1Rn8X2Sopp5hSPpb0u0soEJ71BZAbxe4d2Y1d/1MYcxBdRKwncum6sCTsnxTpqQ/qvSJKlTQ==} peerDependencies: - storybook: ^10.3.1 + storybook: ^10.3.3 - '@storybook/addon-links@10.3.1': - resolution: {integrity: sha512-ooV8FU9PhcmSwpkSETZW6SYzVwQ0ui3DEp8gx5Kzf0JXAkESwxnzQVikxzHCLaP6KgYPb9gajN6jhin2KUGrhw==} + '@storybook/addon-links@10.3.3': + resolution: {integrity: sha512-tazBHlB+YbU62bde5DWsq0lnxZjcAsPB3YRUpN2hSMfAySsudRingyWrgu5KeOxXhJvKJj0ohjQvGcMx/wgQUA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.3.1 + storybook: ^10.3.3 peerDependenciesMeta: react: optional: true - '@storybook/addon-onboarding@10.3.1': - resolution: {integrity: sha512-fXhkG0dPvsuwlOmK2eOmc0CYJXUeWV8hZWlnthkqGKrzUyqXx0YmM3VdnKwk0/OnOCp1zykDoMtnjnDqWW4saQ==} + '@storybook/addon-onboarding@10.3.3': + resolution: {integrity: sha512-HZiHfXdcLc29WkYFW+1VAMtJCeAZOOLRYPvs97woJUcZqW8yfWEJ9MWH+j++736SFAv2aqZWNmP47OdBJ/kMkw==} peerDependencies: - storybook: ^10.3.1 + storybook: ^10.3.3 - '@storybook/addon-themes@10.3.1': - resolution: {integrity: sha512-Y4ZCof3C+nsXvfhDmUvxt1klnZ6SPh1tLuDWo4eE8MUG1jQ2tixiIQX6Ups8fqfYCN8RgjcDDHnIyNZRZlgB2Q==} + '@storybook/addon-themes@10.3.3': + resolution: {integrity: sha512-6PgH1o7yNnWRVj4lAT1DNcX/eZXKgzjhfmzgWh3oFpPfDDvUzpFxx+MClM5f/ZieIbyQscxEuq8li7+e/F5VEQ==} peerDependencies: - storybook: ^10.3.1 + storybook: ^10.3.3 - '@storybook/builder-vite@10.3.1': - resolution: {integrity: sha512-8X3Mv6VxVaVHip51ZuTAjQv7jI3K4GxpgW0ZAhaLi8atSTHezu7hQOuISC1cHAwhMV0GhGHtCCKi33G9EGx5hw==} + '@storybook/builder-vite@10.3.3': + resolution: {integrity: sha512-awspKCTZvXyeV3KabL0id62mFbxR5u/5yyGQultwCiSb2/yVgBfip2MAqLyS850pvTiB6QFVM9deOyd2/G/bEA==} peerDependencies: - storybook: ^10.3.1 + storybook: ^10.3.3 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - '@storybook/csf-plugin@10.3.1': - resolution: {integrity: sha512-P1WUSoyueV+ULpNeip4eIjjDvOXDBQI4gaq/s1PdAg1Szz/0GhDPu/CXuwukgkmyHaJP3aVR3pHPvSfeLfMCrA==} + '@storybook/csf-plugin@10.3.3': + resolution: {integrity: sha512-Utlh7zubm+4iOzBBfzLW4F4vD99UBtl2Do4edlzK2F7krQIcFvR2ontjAE8S1FQVLZAC3WHalCOS+Ch8zf3knA==} peerDependencies: esbuild: 0.27.2 rollup: 4.59.0 - storybook: ^10.3.1 + storybook: ^10.3.3 vite: '*' webpack: '*' peerDependenciesMeta: @@ -3008,40 +3753,40 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@storybook/nextjs-vite@10.3.1': - resolution: {integrity: sha512-//xqijMeZGYSagUMmuRZVW4pHYWqiQozEil2NM6HUseqc3bReFNqPpDAThCVGKAckIulVIIUZbF/4Lh9OYplOA==} + '@storybook/nextjs-vite@10.3.3': + resolution: {integrity: sha512-/OzOo0dSd0eFIAF9ft+ptwaXHa5Xj01cw3NXEtmPdODZXl0eiPmTvWYIJeP26UEPzI2FFSm4fK64ZZJluKpGOA==} peerDependencies: next: ^14.1.0 || ^15.0.0 || ^16.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.3.1 + storybook: ^10.3.3 typescript: '*' vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - '@storybook/react-dom-shim@10.3.1': - resolution: {integrity: sha512-X337d639Bw9ej8vIi29bxgRsHcrFHhux1gMSmDifYjBRhTUXE3/OeDtoEl6ZV5Pgc5BAabUF5L2cl0mb428BYQ==} + '@storybook/react-dom-shim@10.3.3': + resolution: {integrity: sha512-lkhuh4G3UTreU9M3Iz5Dt32c6U+l/4XuvqLtbe1sDHENZH6aPj7y0b5FwnfHyvuTvYRhtbo29xZrF5Bp9kCC0w==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.3.1 + storybook: ^10.3.3 - '@storybook/react-vite@10.3.1': - resolution: {integrity: sha512-6ATC5oZKXtNFdyLR1DyJY9s6qDltFL/Dfew6loJK4bBqd5a46+wpNJebMBhBxdhHa9FDJS5tv2noNSO5kXc+Sw==} + '@storybook/react-vite@10.3.3': + resolution: {integrity: sha512-qHdlBe1hjqFAGXa8JL7bWTLbP/gDqXbWDm+SYCB646NHh5yvVDkZLwigP5Y+UL7M2ASfqFtosnroUK9tcCM2dw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.3.1 + storybook: ^10.3.3 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - '@storybook/react@10.3.1': - resolution: {integrity: sha512-DoiOwfVG8VVIxA9JD3wz5lE30RTxwOnSHJJv4qdlCCiPIJWBGjxug9bqFxUZlqDkkbUzFLGDOBxYDp05Y66dbQ==} + '@storybook/react@10.3.3': + resolution: {integrity: sha512-cGG5TbR8Tdx9zwlpsWyBEfWrejm5iWdYF26EwIhwuKq9GFUTAVrQzo0Rs7Tqc3ZyVhRS/YfsRiWSEH+zmq2JiQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.3.1 + storybook: ^10.3.3 typescript: '>= 4.9.x' peerDependenciesMeta: typescript: @@ -3064,8 +3809,8 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@swc/helpers@0.5.19': - resolution: {integrity: sha512-QamiFeIK3txNjgUTNppE6MiG3p7TdninpZu0E0PbqVh1a9FNLT2FRhisaa4NcaX52XVhA5l7Pk58Ft7Sqi/2sA==} + '@swc/helpers@0.5.20': + resolution: {integrity: sha512-2egEBHUMasdypIzrprsu8g+OEVd7Vp2MM3a2eVlM/cyFYto0nGz5BX5BTgh/ShZZI9ed+ozEq+Ngt+rgmUs8tw==} '@t3-oss/env-core@0.13.11': resolution: {integrity: sha512-sM7GYY+KL7H/Hl0BE0inWfk3nRHZOLhmVn7sHGxaZt9FAR6KqREXAE+6TqKfiavfXmpRxO/OZ2QgKRd+oiBYRQ==} @@ -3154,8 +3899,8 @@ packages: peerDependencies: solid-js: 1.9.11 - '@tanstack/eslint-plugin-query@5.95.0': - resolution: {integrity: sha512-XvEfgHyZoeGYGt0uOFwEbgkNMrRxoPt8Gy44cu3OwYFw6CU8uPAaUUiDJCqeyvYNNkuhnR4gWRn6vu5fcFSTUQ==} + '@tanstack/eslint-plugin-query@5.95.2': + resolution: {integrity: sha512-EYUFRaqjBep4EHMPpZR12sXP7Kr5qv9iDIlq93NfbhHwhITaW6Txu3ROO6dLFz5r84T8p+oZXBG77pa2Wuok7A==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ^5.4.0 @@ -3175,11 +3920,11 @@ packages: resolution: {integrity: sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w==} engines: {node: '>=18'} - '@tanstack/query-core@5.95.0': - resolution: {integrity: sha512-H1/CWCe8tGL3YIVeo770Z6kPbt0B3M1d/iQXIIK1qlFiFt6G2neYdkHgLapOC8uMYNt9DmHjmGukEKgdMk1P+A==} + '@tanstack/query-core@5.95.2': + resolution: {integrity: sha512-o4T8vZHZET4Bib3jZ/tCW9/7080urD4c+0/AUaYVpIqOsr7y0reBc1oX3ttNaSW5mYyvZHctiQ/UOP2PfdmFEQ==} - '@tanstack/query-devtools@5.95.0': - resolution: {integrity: sha512-i8IzjIsZSE9y9XGndeVYeUusrZpKyhOnOPIzWKao8iAVzmk8ZesPe5URt02aLwC5A0Rg72N+vgqolXXCXm4fFg==} + '@tanstack/query-devtools@5.95.2': + resolution: {integrity: sha512-QfaoqBn9uAZ+ICkA8brd1EHj+qBF6glCFgt94U8XP5BT6ppSsDBI8IJ00BU+cAGjQzp6wcKJL2EmRYvxy0TWIg==} '@tanstack/react-devtools@0.10.0': resolution: {integrity: sha512-cUMzOQb1IHmkb8MsD0TrxHT8EL92Rx3G0Huq+IFkWeoaZPGlIiaIcGTpS5VvQDeI4BVUT+ZGt6CQTpx8oSTECg==} @@ -3204,19 +3949,19 @@ packages: '@tanstack/react-start': optional: true - '@tanstack/react-query-devtools@5.95.0': - resolution: {integrity: sha512-w4lYQTuyGM6l8C32UDIvxeodCrOwbw0JGSK6sQXYlF24CJnTcNmCxvfvrW2L3f3NObyvEQYcGTfjOr0Vw8jaWA==} + '@tanstack/react-query-devtools@5.95.2': + resolution: {integrity: sha512-AFQFmbznVkbtfpx8VJ2DylW17wWagQel/qLstVLkYmNRo2CmJt3SNej5hvl6EnEeljJIdC3BTB+W7HZtpsH+3g==} peerDependencies: - '@tanstack/react-query': ^5.95.0 + '@tanstack/react-query': ^5.95.2 react: ^18 || ^19 - '@tanstack/react-query@5.95.0': - resolution: {integrity: sha512-EMP8B+BK9zvnAemT8M/y3z/WO0NjZ7fIUY3T3wnHYK6AA3qK/k33i7tPgCXCejhX0cd4I6bJIXN2GmjrHjDBzg==} + '@tanstack/react-query@5.95.2': + resolution: {integrity: sha512-/wGkvLj/st5Ud1Q76KF1uFxScV7WeqN1slQx5280ycwAyYkIPGaRZAEgHxe3bjirSd5Zpwkj6zNcR4cqYni/ZA==} peerDependencies: react: ^18 || ^19 - '@tanstack/react-store@0.9.2': - resolution: {integrity: sha512-Vt5usJE5sHG/cMechQfmwvwne6ktGCELe89Lmvoxe3LKRoFrhPa8OCKWs0NliG8HTJElEIj7PLtaBQIcux5pAQ==} + '@tanstack/react-store@0.9.3': + resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3227,12 +3972,16 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/store@0.9.2': - resolution: {integrity: sha512-K013lUJEFJK2ofFQ/hZKJUmCnpcV00ebLyOyFOWQvyQHUOZp/iYO84BM6aOGiV81JzwbX0APTVmW8YI7yiG5oA==} + '@tanstack/store@0.9.3': + resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==} '@tanstack/virtual-core@3.13.23': resolution: {integrity: sha512-zSz2Z2HNyLjCplANTDyl3BcdQJc2k1+yyFoKhNRmCr7V7dY8o8q5m8uFTI1/Pg1kL+Hgrz6u3Xo6eFUB7l66cg==} + '@teppeis/multimaps@3.0.0': + resolution: {integrity: sha512-ID7fosbc50TbT0MK0EG12O+gAP3W3Aa/Pz4DaTtQtEvlc9Odaqi0de+xuZ7Li2GtK4HzEX7IuRWS/JmZLksR3Q==} + engines: {node: '>=14'} + '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -3409,8 +4158,8 @@ packages: '@types/d3@7.4.3': resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -3469,6 +4218,9 @@ packages: '@types/node@25.5.0': resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==} + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/papaparse@5.5.2': resolution: {integrity: sha512-gFnFp/JMzLHCwRf7tQHrNnfhN4eYBVYYI897CGX4MY1tzY9l2aLkVyx2IlKZ/SAqDbB3I1AOZW5gTMGGsqWliA==} @@ -3519,108 +4271,108 @@ packages: '@types/zen-observable@0.8.3': resolution: {integrity: sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==} - '@typescript-eslint/eslint-plugin@8.57.1': - resolution: {integrity: sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==} + '@typescript-eslint/eslint-plugin@8.57.2': + resolution: {integrity: sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.57.1 + '@typescript-eslint/parser': ^8.57.2 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.57.1': - resolution: {integrity: sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==} + '@typescript-eslint/parser@8.57.2': + resolution: {integrity: sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.57.1': - resolution: {integrity: sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==} + '@typescript-eslint/project-service@8.57.2': + resolution: {integrity: sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/rule-tester@8.57.1': - resolution: {integrity: sha512-gk0q0rLa7a1uEB0iD2t1GZELK1z6HfudiKYeSVhjQ5gW5FdL0OcZ+8f09Lg7NbmHSBF3V+S9BDuw0qoCFkHR+w==} + '@typescript-eslint/rule-tester@8.57.2': + resolution: {integrity: sha512-cb5m0irr1449waTuYzGi4KD3SGUH3khL4ta/o9lzShvT7gnIwR5qVhU0VM0p966kCrtFId8hwmkvz1fOElsxTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - '@typescript-eslint/scope-manager@8.57.1': - resolution: {integrity: sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==} + '@typescript-eslint/scope-manager@8.57.2': + resolution: {integrity: sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.57.1': - resolution: {integrity: sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==} + '@typescript-eslint/tsconfig-utils@8.57.2': + resolution: {integrity: sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.57.1': - resolution: {integrity: sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==} + '@typescript-eslint/type-utils@8.57.2': + resolution: {integrity: sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.57.1': - resolution: {integrity: sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==} + '@typescript-eslint/types@8.57.2': + resolution: {integrity: sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.57.1': - resolution: {integrity: sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==} + '@typescript-eslint/typescript-estree@8.57.2': + resolution: {integrity: sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.57.1': - resolution: {integrity: sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==} + '@typescript-eslint/utils@8.57.2': + resolution: {integrity: sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.57.1': - resolution: {integrity: sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==} + '@typescript-eslint/visitor-keys@8.57.2': + resolution: {integrity: sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260322.1': - resolution: {integrity: sha512-5wSilxwLGX5fMKJgsUkCBwOfW9GMG3WF5j77CVBOdFI7miFaR3JQaPzTA+uyHDMNIIeSDo1KtV77GT48Y/d0Xg==} + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260329.1': + resolution: {integrity: sha512-zS1thDk7luD82nXVwvMd97F7FgxAE6jGtSmnHeXdaQ+6hJQcQLOVkfUdaehhdodqKDapWA2jEURxQAYjDGvv3g==} cpu: [arm64] os: [darwin] - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260322.1': - resolution: {integrity: sha512-G806SrfxkYNAgZ9Xk53+OvbmIg9iD5hjaiD2QhDQL2aZjzy10D4MhcdaZEOoMfw0OI/PoJPYOiPD+9/x2kw3Lg==} + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260329.1': + resolution: {integrity: sha512-3IJ2qmpjQ1OXpZNUhJRjF1+SbDuqGC14Ug8DjWJlPBp06isi1fcJph90f5qW//FxEsNnJPYRcNwpP0A2RbTASg==} cpu: [x64] os: [darwin] - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260322.1': - resolution: {integrity: sha512-+FyomEEt3K8TBO//n3Ijr61SDM2F7cxZCVqGt+Wk3rLcOCQ2i+8+p64gdsZCmImy3CyP0hBnxPydEbyNkZLtvg==} + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260329.1': + resolution: {integrity: sha512-gQb6SjB5JlUKDaDuz6mv/m+/OBWVDlcjHINFOykBZZYZtgxBx6nEDjLrT8TiJRjmHEG6hSbv+yisUL9IThWycA==} cpu: [arm64] os: [linux] - '@typescript/native-preview-linux-arm@7.0.0-dev.20260322.1': - resolution: {integrity: sha512-0a12pp19ELiNHMqTglfQQQNMsxvtzpjAa4qf12oMJoGyy+UnguKEmaaaCHdp75KvBXGDzlssfDAdiy+NirN19A==} + '@typescript/native-preview-linux-arm@7.0.0-dev.20260329.1': + resolution: {integrity: sha512-WKSSJrH611DFFAg6YCkgbnkdy0a4RRpzvDpNXtPzLTbMYC5oJdq3Dpvncx5nrJvGh4J4yvzXoMxraGPyygqGLw==} cpu: [arm] os: [linux] - '@typescript/native-preview-linux-x64@7.0.0-dev.20260322.1': - resolution: {integrity: sha512-MviQe5x4WqQGv/Vhu4hcv2A0qTW/BTaZPbOLYCtvhuovNFO6D++ZmJAbHvA0h/bJEaNTgxKZdZPHMpCfSEKfjA==} + '@typescript/native-preview-linux-x64@7.0.0-dev.20260329.1': + resolution: {integrity: sha512-kg4r+ssxoEWruBynUg9bFMdcMpo5NupzAPqNBlV8uWbmYGZjaPLonFWAi9ZZMiVJY/x5ZQ9GBl6xskwLdd3PJQ==} cpu: [x64] os: [linux] - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260322.1': - resolution: {integrity: sha512-ibnMaXDJPSgMXKC61NHiFlww/xjAEINgc1mcn2ntTfuGHwduU4P9Bi038TxXg95Wmu3v6xIPIorXXsBOdE+p3Q==} + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260329.1': + resolution: {integrity: sha512-Qi4lddVxl5MG7Tk67gYhCFnoqqLGd4TvaI8RN4qHFjt3GV8s6c+0cQGsJXJnVgMx27qbyDTdsyAa2pvb42rYcQ==} cpu: [arm64] os: [win32] - '@typescript/native-preview-win32-x64@7.0.0-dev.20260322.1': - resolution: {integrity: sha512-O+r1RToWBbGkK7NXC7DpraLObSWyxvSqRiSfr/BlZ351Cdq1q3121zCGzVtqERGeRtVoEMRrzS5ITOd6On/pCw==} + '@typescript/native-preview-win32-x64@7.0.0-dev.20260329.1': + resolution: {integrity: sha512-+k5+usuB8HZ6Xc+enLdb95ZJd25bQqsnI1zXxfRCHP+RS9mxs70Mi9ezQz3lKOLZFFXShSH7iW9iulm8KwVzCQ==} cpu: [x64] os: [win32] - '@typescript/native-preview@7.0.0-dev.20260322.1': - resolution: {integrity: sha512-CmzQTKvesYHmz3g92G+XPDis25ocvHqa/gK8m98w+bML99KJLEWQKVlvkLrYA85JiJEK+XBIiz+6lCgUqRkWXA==} + '@typescript/native-preview@7.0.0-dev.20260329.1': + resolution: {integrity: sha512-v5lJ0TgSt2m9yVk2xoj9+NH/gTDeWTLaWGPx6MJsUKOYd6bmCJhHbMcWmb8d/zlfhE9ffpixUKYj62CdYfriqA==} hasBin: true '@ungap/structured-clone@1.3.0': @@ -3651,6 +4403,19 @@ packages: resolution: {integrity: sha512-hBcWIOppZV14bi+eAmCZj8Elj8hVSUZJTpf1lgGBhVD85pervzQ1poM/qYfFUlPraYSZYP+ASg6To5BwYmUSGQ==} engines: {node: '>=16'} + '@vitejs/devtools-kit@0.1.11': + resolution: {integrity: sha512-ZmBr54Nk8IwdbNCBNtOkQ3WcskWcL55ndfiB0UM8eTZ0ZoNwzPTCHiHgk/RnbhviXiB0kTowyTTYp4RfqGEWUQ==} + peerDependencies: + vite: '*' + + '@vitejs/devtools-rpc@0.1.11': + resolution: {integrity: sha512-APo34qbV05bNJB//Jmn4QLDrCU1CQuFvYbQdqvvyCKjxwWuoHhGobqzgoRS5V23tn8Sbliz7/Fyhfh+7C0LtKA==} + peerDependencies: + ws: '*' + peerDependenciesMeta: + ws: + optional: true + '@vitejs/plugin-react@6.0.1': resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3675,23 +4440,26 @@ packages: react-server-dom-webpack: optional: true - '@vitest/coverage-v8@4.1.0': - resolution: {integrity: sha512-nDWulKeik2bL2Va/Wl4x7DLuTKAXa906iRFooIRPR+huHkcvp9QDkPQ2RJdmjOFrqOqvNfoSQLF68deE3xC3CQ==} + '@vitest/coverage-v8@4.1.2': + resolution: {integrity: sha512-sPK//PHO+kAkScb8XITeB1bf7fsk85Km7+rt4eeuRR3VS1/crD47cmV5wicisJmjNdfeokTZwjMk4Mj2d58Mgg==} peerDependencies: - '@vitest/browser': 4.1.0 - vitest: 4.1.0 + '@vitest/browser': 4.1.2 + vitest: 4.1.2 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/eslint-plugin@1.6.12': - resolution: {integrity: sha512-4kI47BJNFE+EQ5bmPbHzBF+ibNzx2Fj0Jo9xhWsTPxMddlHwIWl6YAxagefh461hrwx/W0QwBZpxGS404kBXyg==} + '@vitest/eslint-plugin@1.6.13': + resolution: {integrity: sha512-ui7JGWBoQpS5NKKW0FDb1eTuFEZ5EupEv2Psemuyfba7DfA5K52SeDLelt6P4pQJJ/4UGkker/BgMk/KrjH3WQ==} engines: {node: '>=18'} peerDependencies: + '@typescript-eslint/eslint-plugin': '*' eslint: '>=8.57.0' typescript: '>=5.0.0' vitest: '*' peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true typescript: optional: true vitest: @@ -3703,8 +4471,8 @@ packages: '@vitest/pretty-format@3.2.4': resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - '@vitest/pretty-format@4.1.0': - resolution: {integrity: sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==} + '@vitest/pretty-format@4.1.2': + resolution: {integrity: sha512-dwQga8aejqeuB+TvXCMzSQemvV9hNEtDDpgUKDzOmNQayl2OG241PSWeJwKRH3CiC+sESrmoFd49rfnq7T4RnA==} '@vitest/spy@3.2.4': resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} @@ -3712,11 +4480,11 @@ packages: '@vitest/utils@3.2.4': resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - '@vitest/utils@4.1.0': - resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==} + '@vitest/utils@4.1.2': + resolution: {integrity: sha512-xw2/TiX82lQHA06cgbqRKFb5lCAy3axQ4H4SoUFhUsg+wztiet+co86IAMDtF6Vm1hc7J6j09oh/rgDn+JdKIQ==} - '@voidzero-dev/vite-plus-core@0.1.13': - resolution: {integrity: sha512-72dAIYgGrrmh4ap5Tbvzo0EYCrmVRoPQjz3NERpZ34CWCjFB8+WAyBkxG631Jz9/qC1TR/ZThjOKbdYXQ5z9Aw==} + '@voidzero-dev/vite-plus-core@0.1.14': + resolution: {integrity: sha512-CCWzdkfW0fo0cQNlIsYp5fOuH2IwKuPZEb2UY2Z8gXcp5pG74A82H2Pthj0heAuvYTAnfT7kEC6zM+RbiBgQbg==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: '@arethetypeswrong/core': ^0.18.1 @@ -3775,43 +4543,57 @@ packages: yaml: optional: true - '@voidzero-dev/vite-plus-darwin-arm64@0.1.13': - resolution: {integrity: sha512-GgQ5dW1VR/Vuc8cRDsdpLMdly2rHiq8ihNKIh1eu8hR85bDjDxE4DSXeadCDMWC0bHTjQiR1HqApzjoPYsVF/w==} + '@voidzero-dev/vite-plus-darwin-arm64@0.1.14': + resolution: {integrity: sha512-q2ESUSbapwsxVRe/KevKATahNRraoX5nti3HT9S3266OHT5sMroBY14jaxTv74ekjQc9E6EPhyLGQWuWQuuBRw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@voidzero-dev/vite-plus-darwin-x64@0.1.13': - resolution: {integrity: sha512-X4ZXbjIhNg5jxEkPVn7kJZEVIvNiOCWztrY67nHD94yqsWLy2Hs7yo+DhrpEQihsnlZ1hRRtwDirdCncvEulUg==} + '@voidzero-dev/vite-plus-darwin-x64@0.1.14': + resolution: {integrity: sha512-UpcDZc9G99E/4HDRoobvYHxMvFOG5uv3RwEcq0HF70u4DsnEMl1z8RaJLeWV7a09LGwj9Q+YWC3Z4INWnTLs8g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.13': - resolution: {integrity: sha512-oPtwztuF1cierDWA68beais5mwm6dXsmOOvccn6ZHjNpKXig84LvgIoY4bMazA3Z0SE9nWqxmP0kePiO5SoiuA==} + '@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.14': + resolution: {integrity: sha512-GIjn35RABUEDB9gHD26nRq7T72Te+Qy2+NIzogwEaUE728PvPkatF5gMCeF4sigCoc8c4qxDwsG+A2A2LYGnDg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@voidzero-dev/vite-plus-linux-x64-gnu@0.1.13': - resolution: {integrity: sha512-RgNHwTXrnYjt60K0g083VxOjaJNXHvZXViBQd/oC7RUwGUvxuHkraq/4mWaI69Pffx2KpyykxgCrtmhWq5Tgjg==} + '@voidzero-dev/vite-plus-linux-arm64-musl@0.1.14': + resolution: {integrity: sha512-qo2RToGirG0XCcxZ2AEOuonLM256z6dNbJzDDIo5gWYA+cIKigFQJbkPyr25zsT1tsP2aY0OTxt2038XbVlRkQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@voidzero-dev/vite-plus-linux-x64-gnu@0.1.14': + resolution: {integrity: sha512-BsMWKZfdfGcYLxxLyaePpg6NW54xqzzcfq8sFUwKfwby0kgOKQ4WymUXyBvO9nnBb0ZPsJQrV0sx+Onac/LTaw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@voidzero-dev/vite-plus-test@0.1.13': - resolution: {integrity: sha512-P3n9adJZsaIUGlgbzyT2YvlA1yr2lCYhNjrZsiLAKMVyQzk2D++ptTre3SnYf9j1TQeMP1VonRXGjtZhTf8wHg==} + '@voidzero-dev/vite-plus-linux-x64-musl@0.1.14': + resolution: {integrity: sha512-mOrEpj7ntW9RopGbcOYG/L0pOs0qHzUG4Vz7NXbuf4dbOSlY4JjyoMOIWxjKQORQht02Hzuf8YrMGNwa6AjVSQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@voidzero-dev/vite-plus-test@0.1.14': + resolution: {integrity: sha512-rjF+qpYD+5+THOJZ3gbE3+cxsk5sW7nJ0ODK7y6ZKeS4amREUMedEDYykzKBwR7OZDC/WwE90A0iLWCr6qAXhA==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/ui': 4.1.0 + '@vitest/ui': 4.1.1 happy-dom: '*' jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -3826,14 +4608,14 @@ packages: jsdom: optional: true - '@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.13': - resolution: {integrity: sha512-+oygKTgglu0HkA4y9kFs8/BbHFsvShkHuL+8bK++Zek3x2ArKHRjCMgcYUXyj6nYufMIL2ba/Und7aHUK2ZGiQ==} + '@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.14': + resolution: {integrity: sha512-7iC+Ig+8D/zACy0IJf7w/vQ7duTjux9Ttmm3KOBdVWH4dl3JihydA7+SQVMhz71a4WiqJ6nPidoG8D6hUP4MVQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@voidzero-dev/vite-plus-win32-x64-msvc@0.1.13': - resolution: {integrity: sha512-+7zTnX/HqYCaBKmSLHjmCXQBRSSIJ6EFry55+4C0R4AMyayfn9w3LL0/NuVeCNkG69u3FnkRuwkqdWpzxztoHQ==} + '@voidzero-dev/vite-plus-win32-x64-msvc@0.1.14': + resolution: {integrity: sha512-yRJ/8yAYFluNHx0Ej6Kevx65MIeM3wFKklnxosVZRlz2ZRL1Ea1Qh3tWATr3Ipk1ciRxBv8KJgp6zXqjxtZSoQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -3850,20 +4632,20 @@ packages: '@volar/typescript@2.4.28': resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} - '@vue/compiler-core@3.5.30': - resolution: {integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==} + '@vue/compiler-core@3.5.31': + resolution: {integrity: sha512-k/ueL14aNIEy5Onf0OVzR8kiqF/WThgLdFhxwa4e/KF/0qe38IwIdofoSWBTvvxQOesaz6riAFAUaYjoF9fLLQ==} - '@vue/compiler-dom@3.5.30': - resolution: {integrity: sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==} + '@vue/compiler-dom@3.5.31': + resolution: {integrity: sha512-BMY/ozS/xxjYqRFL+tKdRpATJYDTTgWSo0+AJvJNg4ig+Hgb0dOsHPXvloHQ5hmlivUqw1Yt2pPIqp4e0v1GUw==} - '@vue/compiler-sfc@3.5.30': - resolution: {integrity: sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==} + '@vue/compiler-sfc@3.5.31': + resolution: {integrity: sha512-M8wpPgR9UJ8MiRGjppvx9uWJfLV7A/T+/rL8s/y3QG3u0c2/YZgff3d6SuimKRIhcYnWg5fTfDMlz2E6seUW8Q==} - '@vue/compiler-ssr@3.5.30': - resolution: {integrity: sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==} + '@vue/compiler-ssr@3.5.31': + resolution: {integrity: sha512-h0xIMxrt/LHOvJKMri+vdYT92BrK3HFLtDqq9Pr/lVVfE4IyKZKvWf0vJFW10Yr6nX02OR4MkJwI0c1HDa1hog==} - '@vue/shared@3.5.30': - resolution: {integrity: sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==} + '@vue/shared@3.5.31': + resolution: {integrity: sha512-nBxuiuS9Lj5bPkPbWogPUnjxxWpkRniX7e5UBQDWl6Fsf4roq9wwV+cR7ezQ4zXswNvPIlsdj1slcLB7XCsRAw==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -3942,8 +4724,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agentation@2.3.3: - resolution: {integrity: sha512-AUZgFCdBQ/nAohlFsHByM9S2Dp7ECMNqVjlOke4hv/90v+wTiwrGladEkgWS60RDQp+CJ5p97meeCthYgTFlKQ==} + agentation@3.0.2: + resolution: {integrity: sha512-iGzBxFVTuZEIKzLY6AExSLAQH6i6SwxV4pAu7v7m3X6bInZ7qlZXAwrEqyc4+EfP4gM7z2RXBF6SF4DeH0f2lA==} peerDependencies: react: '>=18.0.0' react-dom: '>=18.0.0' @@ -3953,8 +4735,8 @@ packages: react-dom: optional: true - ahooks@3.9.6: - resolution: {integrity: sha512-Mr7f05swd5SmKlR9SZo5U6M0LsL4ErweLzpdgXjA1JPmnZ78Vr6wzx0jUtvoxrcqGKYnX0Yjc02iEASVxHFPjQ==} + ahooks@3.9.7: + resolution: {integrity: sha512-S0lvzhbdlhK36RFBkGv+RbOM/dbbweym+BIHM/bwwuWVSVN5TuVErHPMWo4w0t1NDYg5KPp2iEf7Y7E5LASYiw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3982,6 +4764,10 @@ packages: resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} engines: {node: '>=18'} + ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -4034,6 +4820,9 @@ packages: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} + assertion-error-formatter@3.0.0: + resolution: {integrity: sha512-6YyAVLrEze0kQ7CmJfUgrLHb+Y7XghmL2Ie7ijVa2Y9ynP3LV+VDiwFk62Dn0qtqbmY0BT0ss6p1xxpiF2PYbQ==} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -4052,6 +4841,9 @@ packages: async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + autoprefixer@10.4.27: resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} engines: {node: ^10 || ^12 || >=14} @@ -4059,6 +4851,9 @@ packages: peerDependencies: postcss: ^8.1.0 + axios@1.14.0: + resolution: {integrity: sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==} + bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -4080,14 +4875,11 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.8: - resolution: {integrity: sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ==} + baseline-browser-mapping@2.10.12: + resolution: {integrity: sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==} engines: {node: '>=6.0.0'} hasBin: true - bidi-js@1.0.3: - resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} - binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -4095,8 +4887,8 @@ packages: birecord@0.1.1: resolution: {integrity: sha512-VUpsf/qykW0heRlC8LooCq28Kxn3mAqKohhDG/49rrsQ1dT1CXyj/pgXS+5BSRzFTR/3DyIBOqQOrGyZOh71Aw==} - birpc@2.9.0: - resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} + birpc@4.0.0: + resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -4107,8 +4899,8 @@ packages: brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - brace-expansion@5.0.4: - resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} braces@3.0.3: @@ -4141,14 +4933,28 @@ packages: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: 0.27.2 + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + cac@7.0.0: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -4160,13 +4966,16 @@ packages: camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} - caniuse-lite@1.0.30001780: - resolution: {integrity: sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==} + caniuse-lite@1.0.30001781: + resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==} canvas@3.2.2: resolution: {integrity: sha512-duEt4h1HHu9sJZyVKfLRXR6tsKPY7cEELzxSRJkwddOXYvQT3P/+es98SV384JA0zMOZ5s+9gatnGfM6sL4Drg==} engines: {node: ^18.12.0 || >= 20.9.0} + capital-case@1.0.4: + resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -4260,6 +5069,9 @@ packages: resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} engines: {node: '>=8'} + class-transformer@0.5.1: + resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -4277,6 +5089,10 @@ packages: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} engines: {node: '>=18'} + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + cli-truncate@5.2.0: resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} engines: {node: '>=20'} @@ -4310,12 +5126,24 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + comma-separated-tokens@1.0.8: resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@14.0.0: + resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} + engines: {node: '>=20'} + + commander@14.0.2: + resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} + engines: {node: '>=20'} + commander@14.0.3: resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} engines: {node: '>=20'} @@ -4339,6 +5167,10 @@ packages: resolution: {integrity: sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw==} engines: {node: '>= 12.0.0'} + comment-parser@1.4.6: + resolution: {integrity: sha512-ObxuY6vnbWTN6Od72xfwN9DbzC7Y2vv8u1Soi9ahRKL37gb6y1qk6/dgjs+3JWuXJHWvsg3BXIwzd/rkmAwavg==} + engines: {node: '>= 12.0.0'} + compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} @@ -4348,6 +5180,10 @@ packages: confbox@0.2.4: resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + consola@3.4.2: + 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==} @@ -4399,10 +5235,6 @@ packages: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - 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-what@6.2.2: resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} @@ -4581,10 +5413,6 @@ packages: dagre-d3-es@7.0.14: resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} - data-urls@7.0.0: - resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - dayjs@1.11.20: resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} @@ -4633,8 +5461,12 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - delaunator@5.0.1: - resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + delaunator@5.1.0: + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} @@ -4660,6 +5492,10 @@ packages: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + diff@4.0.4: + resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} + engines: {node: '>=0.3.1'} + dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} @@ -4697,6 +5533,10 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + echarts-for-react@3.0.6: resolution: {integrity: sha512-4zqLgTGWS3JvkQDXjzkR1k1CHRdpd6by0988TWMJgnvDytegWLbeP/VNZmMa+0VJx2eD7Y632bi2JquXDgiGJg==} peerDependencies: @@ -4706,8 +5546,8 @@ packages: echarts@6.0.0: resolution: {integrity: sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==} - electron-to-chromium@1.5.313: - resolution: {integrity: sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==} + electron-to-chromium@1.5.328: + resolution: {integrity: sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==} elkjs@0.11.1: resolution: {integrity: sha512-zxxR9k+rx5ktMwT/FwyLdPCrq7xN6e4VGGHH8hA01vVYKjTFik7nHOxBnAYtrgYUB1RpAiLvA1/U2YraWxyKKg==} @@ -4770,12 +5610,31 @@ packages: error-stack-parser-es@1.0.5: resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} es-module-lexer@2.0.0: resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + es-toolkit@1.45.1: resolution: {integrity: sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw==} @@ -4815,8 +5674,8 @@ packages: peerDependencies: eslint: '>=6.0.0' - eslint-config-flat-gitignore@2.2.1: - resolution: {integrity: sha512-wA5EqN0era7/7Gt5Botlsfin/UNY0etJSEeBgbUlFLFrBi47rAN//+39fI7fpYcl8RENutlFtvp/zRa/M/pZNg==} + eslint-config-flat-gitignore@2.3.0: + resolution: {integrity: sha512-bg4ZLGgoARg1naWfsINUUb/52Ksw/K22K+T16D38Y8v+/sGwwIYrGvH/JBjOin+RQtxxC9tzNNiy4shnGtGyyQ==} peerDependencies: eslint: ^9.5.0 || ^10.0.0 @@ -4896,8 +5755,8 @@ packages: peerDependencies: eslint: '>=9.0.0' - eslint-plugin-jsdoc@62.8.0: - resolution: {integrity: sha512-hu3r9/6JBmPG6wTcqtYzgZAnjEG2eqRUATfkFscokESg1VDxZM21ZaMire0KjeMwfj+SXvgB4Rvh5LBuesj92w==} + eslint-plugin-jsdoc@62.8.1: + resolution: {integrity: sha512-e9358PdHgvcMF98foNd3L7hVCw70Lt+YcSL7JzlJebB8eT5oRJtW6bHMQKoAwJtw6q0q0w/fRIr2kwnHdFDI6A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 @@ -4996,11 +5855,11 @@ packages: peerDependencies: eslint: ^8.0.0 || ^9.0.0 || ^10.0.0 - eslint-plugin-storybook@10.3.1: - resolution: {integrity: sha512-zWE8cQTJo2Wuw6I/Ag73rP5rLbaypm5p3G2BV74Y7Lc8NwNclAwNi5u+yl9qBQLW2aSXotDW9fjj3Mx+GeEgfA==} + eslint-plugin-storybook@10.3.3: + resolution: {integrity: sha512-jo8wZvKaJlxxrNvf4hCsROJP3CdlpaLiYewAs5Ww+PJxCrLelIi5XVHWOAgBvvr3H9WDKvUw8xuvqPYqAlpkFg==} peerDependencies: eslint: '>=8' - storybook: ^10.3.1 + storybook: ^10.3.3 eslint-plugin-toml@1.3.1: resolution: {integrity: sha512-1l00fBP03HIt9IPV7ZxBi7x0y0NMdEZmakL1jBD6N/FoKBvfKxPw5S8XkmzBecOnFBTn5Z8sNJtL5vdf9cpRMQ==} @@ -5222,6 +6081,10 @@ packages: fflate@0.7.4: resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -5242,6 +6105,9 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + fix-dts-default-cjs-exports@1.0.1: + resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -5249,6 +6115,19 @@ packages: flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + format@0.2.2: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} @@ -5275,11 +6154,19 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + functional-red-black-tree@1.0.1: resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} @@ -5294,10 +6181,18 @@ packages: resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} engines: {node: '>=18'} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + get-nonce@1.0.1: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} @@ -5326,6 +6221,10 @@ packages: resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} engines: {node: 18 || 20 || >=22} + global-dirs@3.0.1: + resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} + engines: {node: '>=10'} + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -5350,6 +6249,10 @@ packages: peerDependencies: csstype: ^3.0.10 + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -5360,10 +6263,22 @@ packages: resolution: {integrity: sha512-Tz23LR9T9jOGVZm2x1EPdXqwA37G/owYMxRwU0E4miurAtFsPMQ1d2Jc2okUaSjZqAFz2oEn3FLXC5a0a+siyA==} engines: {node: '>=20.0.0'} + has-ansi@4.0.1: + resolution: {integrity: sha512-Qr4RtTm30xvEdqUXbSBVWDu+PrTokJOwe/FU+VdfJPk+MXAPoeOzKpRyrDTnZIJwAkQ4oBLTU53nu0HrkF/Z2A==} + engines: {node: '>=8'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + hast-util-from-dom@5.0.1: resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} @@ -5428,13 +6343,13 @@ packages: highlightjs-vue@1.0.0: resolution: {integrity: sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==} - hono@4.12.8: - resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==} + hono@4.12.9: + resolution: {integrity: sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==} engines: {node: '>=16.9.0'} - html-encoding-sniffer@6.0.0: - resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + hosted-git-info@9.0.2: + resolution: {integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==} + engines: {node: ^20.17.0 || >=22.9.0} html-entities@2.6.0: resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} @@ -5465,10 +6380,10 @@ packages: i18next-resources-to-backend@1.2.1: resolution: {integrity: sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==} - i18next@25.10.4: - resolution: {integrity: sha512-XsE/6eawy090meuFU0BTY9BtmWr1m9NSwLr0NK7/A04LA58wdAvDsi9WNOJ40Qb1E9NIPbvnVLZEN2fWDd3/3Q==} + i18next@25.10.10: + resolution: {integrity: sha512-cqUW2Z3EkRx7NqSyywjkgCLK7KLCL6IFVFcONG7nVYIJ3ekZ1/N5jUsihHV6Bq37NfhgtczxJcxduELtjTwkuQ==} peerDependencies: - typescript: ^5 + typescript: ^5 || ^6 peerDependenciesMeta: typescript: optional: true @@ -5524,12 +6439,20 @@ packages: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} + index-to-position@1.2.0: + resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} + engines: {node: '>=18'} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + ini@2.0.0: + resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} + engines: {node: '>=10'} + inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} @@ -5593,25 +6516,38 @@ packages: is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-in-ssh@1.0.0: + resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} + engines: {node: '>=20'} + is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} hasBin: true + is-installed-globally@0.4.0: + resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} + engines: {node: '>=10'} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} - is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - 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-wsl@3.1.1: resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} engines: {node: '>=16'} @@ -5646,8 +6582,8 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true - jotai@2.18.1: - resolution: {integrity: sha512-e0NOzK+yRFwHo7DOp0DS0Ycq74KMEAObDWFGmfEL28PD9nLqBTt3/Ug7jf9ca72x0gC9LQZG9zH+0ISICmy3iA==} + jotai@2.19.0: + resolution: {integrity: sha512-r2wwxEXP1F2JteDLZEOPoIpAHhV89paKsN5GWVYndPNMMP/uVZDcC+fNj0A8NjKgaPWzdyO8Vp8YcYKe0uCEqQ==} engines: {node: '>=12.20.0'} peerDependencies: '@babel/core': '>=7.0.0' @@ -5664,6 +6600,10 @@ packages: react: optional: true + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + js-audio-recorder@1.0.7: resolution: {integrity: sha512-JiDODCElVHGrFyjGYwYyNi7zCbKk9va9C77w+zCPMmi4C6ix7zsX2h3ddHugmo4dOTOTCym9++b/wVW9nC0IaA==} @@ -5691,15 +6631,6 @@ packages: resolution: {integrity: sha512-/2uqY7x6bsrpi3i9LVU6J89352C0rpMk0as8trXxCtvd4kPk1ke/Eyif6wqfSLvoNJqcDG9Vk4UsXgygzCt2xA==} engines: {node: '>=20.0.0'} - jsdom@29.0.1: - resolution: {integrity: sha512-z6JOK5gRO7aMybVq/y/MlIpKh8JIi68FBKMUtKkK2KH/wMSRlCxQ682d08LB9fYXplyY/UXG8P4XXTScmdjApg==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} - peerDependencies: - canvas: ^3.2.2 - peerDependenciesMeta: - canvas: - optional: true - jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -5739,8 +6670,8 @@ packages: resolution: {integrity: sha512-eQQBjBnsVtGacsG9uJNB8qOr3yA8rga4wAaGG1qRcBzSIvfhERLrWxMAM1hp5fcS6Abo8M4+bUBTekYR0qTPQw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - katex@0.16.40: - resolution: {integrity: sha512-1DJcK/L05k1Y9Gf7wMcyuqFOL6BiY3vY0CFcAM/LPRN04NALxcl6u7lOWNsp3f/bCHWxigzQl6FbR95XJ4R84Q==} + katex@0.16.44: + resolution: {integrity: sha512-EkxoDTk8ufHqHlf9QxGwcxeLkWRR3iOuYfRpfORgYfqc8s13bgb+YtRY59NK5ZpRaCwq1kqA6a5lpX8C/eLphQ==} hasBin: true keyv@4.5.4: @@ -5749,11 +6680,14 @@ packages: khroma@2.1.0: resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} - knip@6.0.2: - resolution: {integrity: sha512-W17Bo5N9AYn0ZkgWHGBmK/01SrSmr3B6iStr3zudDa2eqi+Kc8VmPjSpTYKDV2Uy/kojrlcH/gS1wypAXfXRRA==} + knip@6.1.0: + resolution: {integrity: sha512-n5eVbJP7HXmwTsiJcELWJe2O1ESxyCTNxJzRTIECDYDTM465qnqk7fL2dv6ae3NUFvFWorZvGlh9mcwxwJ5Xgw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + knuth-shuffle-seeded@1.0.6: + resolution: {integrity: sha512-9pFH0SplrfyKyojCLxZfMcvkhf5hH0d+UwR9nTVJ/DDQJGuzcXjTwB7TP7sDfehSudlGGaOLblmEWqv04ERVWg==} + kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} @@ -5888,6 +6822,10 @@ packages: resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==} engines: {node: '>=20.0.0'} + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + loader-runner@4.3.1: resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} engines: {node: '>=6.11.5'} @@ -5906,6 +6844,12 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + lodash@4.17.23: resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} @@ -5923,6 +6867,9 @@ packages: loupe@3.2.1: resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lowlight@1.20.0: resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} @@ -5968,11 +6915,15 @@ packages: engines: {node: '>= 20'} hasBin: true - marked@17.0.4: - resolution: {integrity: sha512-NOmVMM+KAokHMvjWmC5N/ZOvgmSWuqJB8FoYI019j4ogb/PeRMKoKIjReZ2w3376kkA8dSJIP8uD993Kxc0iRQ==} + marked@17.0.5: + resolution: {integrity: sha512-6hLvc0/JEbRjRgzI6wnT2P1XuM1/RrrDEX0kPt0N7jGm1133g6X7DlxFasUIx+72aKAr904GTxhSLDrd5DIlZg==} engines: {node: '>= 20'} hasBin: true + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + mdast-util-directive@3.1.0: resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} @@ -6042,9 +6993,6 @@ packages: mdn-data@2.23.0: resolution: {integrity: sha512-786vq1+4079JSeu2XdcDjrhi/Ry7BWtjDl9WtGPWLiIHb2T66GvIVflZTBoSNZ5JqTtJGYEVMuFA/lbQlMOyDQ==} - mdn-data@2.27.1: - resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} - memoize-one@5.2.1: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} @@ -6184,6 +7132,11 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + mime@4.1.0: resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} engines: {node: '>=16'} @@ -6225,8 +7178,13 @@ packages: mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - mlly@1.8.1: - resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==} + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} module-alias@2.3.4: resolution: {integrity: sha512-bOclZt8hkpuGgSSoG07PKmvzTizROilUTvLNyrMqvlC9snhs7y7GzjNWAVbISIOlhCP1T14rH1PDAV9iNyBq/w==} @@ -6299,6 +7257,9 @@ packages: sass: optional: true + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + node-abi@3.89.0: resolution: {integrity: sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==} engines: {node: '>=10'} @@ -6312,6 +7273,10 @@ packages: node-releases@2.0.36: resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} + normalize-package-data@8.0.0: + resolution: {integrity: sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==} + engines: {node: ^20.17.0 || >=22.9.0} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -6374,6 +7339,10 @@ packages: resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} engines: {node: '>=18'} + open@11.0.0: + resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} + engines: {node: '>=20'} + openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} @@ -6381,24 +7350,24 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} - oxc-parser@0.120.0: - resolution: {integrity: sha512-WyPWZlcIm+Fkte63FGfgFB8mAAk33aH9h5N9lphXVOHSXEBFFsmYdOBedVKly363aWABjZdaj/m9lBfEY4wt+w==} + oxc-parser@0.121.0: + resolution: {integrity: sha512-ek9o58+SCv6AV7nchiAcUJy1DNE2CC5WRdBcO0mF+W4oRjNQfPO7b3pLjTHSFECpHkKGOZSQxx3hk8viIL5YCg==} engines: {node: ^20.19.0 || >=22.12.0} oxc-resolver@11.19.1: resolution: {integrity: sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg==} - oxfmt@0.41.0: - resolution: {integrity: sha512-sKLdJZdQ3bw6x9qKiT7+eID4MNEXlDHf5ZacfIircrq6Qwjk0L6t2/JQlZZrVHTXJawK3KaMuBoJnEJPcqCEdg==} + oxfmt@0.42.0: + resolution: {integrity: sha512-QhejGErLSMReNuZ6vxgFHDyGoPbjTRNi6uGHjy0cvIjOQFqD6xmr/T+3L41ixR3NIgzcNiJ6ylQKpvShTgDfqg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - oxlint-tsgolint@0.17.1: - resolution: {integrity: sha512-gJc7hb1ZQFbWjRDYpu1XG+5IRdr1S/Jz/W2ohcpaqIXuDmHU0ujGiM0x05J0nIfwMF3HOEcANi/+j6T0Uecdpg==} + oxlint-tsgolint@0.17.3: + resolution: {integrity: sha512-1eh4bcpOMw0e7+YYVxmhFc2mo/V6hJ2+zfukqf+GprvVn3y94b69M/xNrYLmx5A+VdYe0i/bJ2xOs6Hp/jRmRA==} hasBin: true - oxlint@1.56.0: - resolution: {integrity: sha512-Q+5Mj5PVaH/R6/fhMMFzw4dT+KPB+kQW4kaL8FOIq7tfhlnEVp6+3lcWqFruuTNlUo9srZUW3qH7Id4pskeR6g==} + oxlint@1.57.0: + resolution: {integrity: sha512-DGFsuBX5MFZX9yiDdtKjTrYPq45CZ8Fft6qCltJITYZxfwYjVdGf/6wycGYTACloauwIPxUnYhBVeZbHvleGhw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -6411,6 +7380,10 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@7.3.0: + resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} + engines: {node: '>=20'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -6418,6 +7391,10 @@ packages: package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + pad-right@0.2.2: + resolution: {integrity: sha512-4cy8M95ioIGolCoMmm2cMntGR1lPLEbOMzOKu8bzjuJP6JpzEMQcDHmh7hHLYGgob+nKe1YHFMaG4V59HQa89g==} + engines: {node: '>=0.10.0'} + pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} @@ -6444,6 +7421,10 @@ packages: parse-imports-exports@0.2.4: resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + parse-statements@1.0.11: resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} @@ -6536,6 +7517,16 @@ packages: pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + playwright-core@1.58.2: + resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.58.2: + resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==} + engines: {node: '>=18'} + hasBin: true + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -6622,6 +7613,10 @@ packages: resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} engines: {node: ^10 || ^12 || >=14} + powershell-utils@0.1.0: + resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} + engines: {node: '>=20'} + prebuild-install@7.1.3: resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} engines: {node: '>=10'} @@ -6640,15 +7635,26 @@ packages: resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} engines: {node: '>=6'} + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + property-expr@2.0.6: + resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + property-information@5.6.0: resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + pump@3.0.4: resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} @@ -6713,8 +7719,8 @@ packages: react: '>= 16.3.0' react-dom: '>= 16.3.0' - react-easy-crop@5.5.6: - resolution: {integrity: sha512-Jw3/ozs8uXj3NpL511Suc4AHY+mLRO23rUgipXvNYKqezcFSYHxe4QXibBymkOoY6oOtLVMPO2HNPRHYvMPyTw==} + react-easy-crop@5.5.7: + resolution: {integrity: sha512-kYo4NtMeXFQB7h1U+h5yhUkE46WQbQdq7if54uDlbMdZHdRgNehfvaFrXnFw5NR1PNoUOJIfTwLnWmEx/MaZnA==} peerDependencies: react: '>=16.4.0' react-dom: '>=16.4.0' @@ -6733,14 +7739,14 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' - react-i18next@16.6.1: - resolution: {integrity: sha512-izjXh+AkBLy3h3xe3sh6Gg1flhFHc3UyzsMftMKYJr2Z7WvAZQIdjjpHypctN41zFoeLdJUNGDgP1+Qich2fYg==} + react-i18next@16.6.6: + resolution: {integrity: sha512-ZgL2HUoW34UKUkOV7uSQFE1CDnRPD+tCR3ywSuWH7u2iapnz86U8Bi3Vrs620qNDzCf1F47NxglCEkchCTDOHw==} peerDependencies: - i18next: '>= 25.6.2' + i18next: '>= 25.10.9' react: '>= 16.8.0' react-dom: '*' react-native: '*' - typescript: ^5 + typescript: ^5 || ^6 peerDependenciesMeta: react-dom: optional: true @@ -6854,6 +7860,14 @@ packages: read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + read-package-up@12.0.0: + resolution: {integrity: sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw==} + engines: {node: '>=20'} + + read-pkg@10.1.0: + resolution: {integrity: sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==} + engines: {node: '>=20'} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -6892,6 +7906,9 @@ packages: resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + refractor@3.6.0: resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} @@ -6899,6 +7916,9 @@ packages: resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + regexp-match-indices@1.0.2: + resolution: {integrity: sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==} + regexp-tree@0.1.27: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true @@ -6949,6 +7969,10 @@ packages: remend@1.3.0: resolution: {integrity: sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw==} + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} @@ -6967,6 +7991,10 @@ packages: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -6986,8 +8014,13 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - robust-predicates@3.0.2: - resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + robust-predicates@3.0.3: + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} + + rolldown@1.0.0-rc.12: + resolution: {integrity: sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true rollup@4.59.0: resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} @@ -7029,10 +8062,6 @@ packages: resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} engines: {node: '>=11.0.0'} - saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} - scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} @@ -7048,6 +8077,9 @@ packages: resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} engines: {node: ^14.0.0 || >=16.0.0} + seed-random@2.2.0: + resolution: {integrity: sha512-34EQV6AAHQGhoc0tn/96a9Fsi6v2xdqe/dMUwljGRaFOzR3EgRmECvD0O8vi8X+/uQ50LGHfkNu/Eue5TPKZkQ==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -7141,20 +8173,29 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + 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-expression-parse@4.0.0: resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} spdx-license-ids@3.0.23: resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} - srvx@0.11.12: - resolution: {integrity: sha512-AQfrGqntqVPXgP03pvBDN1KyevHC+KmYVqb8vVf4N+aomQqdhaZxjvoVp+AOm4u6x+GgNQY3MVzAUIn+TqwkOA==} + srvx@0.11.13: + resolution: {integrity: sha512-oknN6qduuMPafxKtHucUeG32Q963pjriA5g3/Bl05cwEsUe5VVbIU4qR9LrALHbipSCyBe+VmfDGGydqazDRkw==} engines: {node: '>=20.16.0'} hasBin: true + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + state-local@1.0.7: resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} @@ -7165,8 +8206,8 @@ packages: resolution: {integrity: sha512-9SN0XIjBBXCT6ZXXVnScJN4KP2RyFg6B8sEoFlugVHMANysfaEni4LTWlvUQQ/R0wgZl1Ovt9KBQbzn21kHoZA==} engines: {node: '>=20.19.0'} - storybook@10.3.1: - resolution: {integrity: sha512-i/CA1dUyVcF6cNL3tgPTQ/G6Evh6r3QdATuiiKObrA3QkEKmt3jrY+WeuQA7FCcmHk/vKabeliNrblaff8aY6Q==} + storybook@10.3.3: + resolution: {integrity: sha512-tMoRAts9EVqf+mEMPLC6z1DPyHbcPe+CV1MhLN55IKsl0HxNjvVGK44rVPSePbltPE6vIsn4bdRj6CCUt8SJwQ==} hasBin: true peerDependencies: prettier: ^2 || ^3 @@ -7180,6 +8221,10 @@ packages: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 + string-argv@0.3.1: + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} + engines: {node: '>=0.6.19'} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -7231,6 +8276,9 @@ packages: strip-literal@3.1.0: resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + structured-clone-es@2.0.0: + resolution: {integrity: sha512-5UuAHmBLXYPCl22xWJrFuGmIhBKQzxISPVz6E7nmTmTcAOpUzlbjKJsRrCE4vADmMQ0dzeCnlWn9XufnAGf76Q==} + style-to-js@1.1.21: resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} @@ -7275,9 +8323,6 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - synckit@0.11.12: resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7309,10 +8354,6 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - tapable@2.3.0: - resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} - engines: {node: '>=6'} - tapable@2.3.2: resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} engines: {node: '>=6'} @@ -7360,6 +8401,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tiny-case@1.0.3: + resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} + tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} @@ -7372,6 +8416,9 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.4: resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} engines: {node: '>=18'} @@ -7418,17 +8465,16 @@ packages: resolution: {integrity: sha512-A5F0cM6+mDleacLIEUkmfpkBbnHJFV1d2rprHU2MXNk7mlxHq2zGojA+SRvQD1RoMo9gqjZPWEaKG4v1BQ48lw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - tough-cookie@6.0.1: - resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} - engines: {node: '>=16'} - - tr46@6.0.0: - resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} - engines: {node: '>=20'} + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -7436,8 +8482,8 @@ packages: trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -7487,6 +8533,25 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsup@8.5.1: + resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + tsx@4.21.0: resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} engines: {node: '>=18.0.0'} @@ -7502,8 +8567,16 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@5.4.4: - resolution: {integrity: sha512-JnTrzGu+zPV3aXIUhnyWJj4z/wigMsdYajGLIYakqyOW1nPllzXEJee0QQbHj+CTIQtXGlAjuK0UY+2xTyjVAw==} + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + type-fest@5.5.0: + resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==} engines: {node: '>=20'} typescript@5.9.3: @@ -7536,13 +8609,13 @@ packages: resolution: {integrity: sha512-jxytwMHhsbdpBXxLAcuu0fzlQeXCNnWdDyRHpvWsUl8vd98UwYdl9YTyn8/HcpcJPC3pwUveefsa3zTxyD/ERg==} engines: {node: '>=20.18.1'} - undici@7.24.6: - resolution: {integrity: sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==} - engines: {node: '>=20.18.1'} - unicode-trie@2.0.0: resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} + unicorn-magic@0.4.0: + resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} + engines: {node: '>=20'} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -7591,6 +8664,9 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + upper-case-first@2.0.2: + resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -7655,6 +8731,9 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-arity@1.1.0: + resolution: {integrity: sha512-kkyIsXKwemfSy8ZEoaIz06ApApnWsk5hQO0vLjZS6UkBiGiW++Jsyb8vSBoc0WKlffGoGs5yYy/j5pp8zckrFA==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -7666,14 +8745,17 @@ packages: resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} hasBin: true - valibot@1.3.0: - resolution: {integrity: sha512-SItIaOFnWYho/AcRU5gOtyfkTsuDTC3tRv+jy4/py8xERPnvHdM+ybD1iIqWTATVWG1nZetOfwZKq5upBjSqzw==} + valibot@1.3.1: + resolution: {integrity: sha512-sfdRir/QFM0JaF22hqTroPc5xy4DimuGQVKFrzF1YfGwaS1nJot3Y8VqMdLO2Lg27fMzat2yD3pY5PbAYO39Gg==} peerDependencies: typescript: '>=5' peerDependenciesMeta: typescript: optional: true + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vfile-location@5.0.3: resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} @@ -7683,15 +8765,14 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vinext@https://pkg.pr.new/vinext@b6a2cac: - resolution: {tarball: https://pkg.pr.new/vinext@b6a2cac} - version: 0.0.5 + vinext@0.0.38: + resolution: {integrity: sha512-zlQswirXCApDgAFq1eoO/YbRlavGE+Bnowz5vXoQa2EmbFhYg52+T8SZs1QWdOqkbZMhpLIV/iaWvHtkRv2t4Q==} engines: {node: '>=22'} hasBin: true peerDependencies: '@mdx-js/rollup': ^3.0.0 '@vitejs/plugin-react': ^5.1.4 || ^6.0.0 - '@vitejs/plugin-rsc': ^0.5.19 + '@vitejs/plugin-rsc': ^0.5.21 react: '>=19.2.0' react-dom: '>=19.2.0' react-server-dom-webpack: ^19.2.4 @@ -7704,41 +8785,31 @@ packages: react-server-dom-webpack: optional: true - vite-dev-rpc@1.1.0: - resolution: {integrity: sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==} - peerDependencies: - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 - - vite-hot-client@2.1.0: - resolution: {integrity: sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==} - peerDependencies: - vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 - vite-plugin-commonjs@0.10.4: resolution: {integrity: sha512-eWQuvQKCcx0QYB5e5xfxBNjQKyrjEWZIR9UOkOV6JAgxVhtbZvCOF+FNC2ZijBJ3U3Px04ZMMyyMyFBVWIJ5+g==} vite-plugin-dynamic-import@1.6.0: resolution: {integrity: sha512-TM0sz70wfzTIo9YCxVFwS8OA9lNREsh+0vMHGSkWDTZ7bgd1Yjs5RV8EgB634l/91IsXJReg0xtmuQqP0mf+rg==} - vite-plugin-inspect@11.3.3: - resolution: {integrity: sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==} + vite-plugin-inspect@12.0.0-beta.1: + resolution: {integrity: sha512-ang8DMcQxr2MJRjdvwabkD0uOPFB5/fP4hldZvAqCl82SABXK1zYLyZKGrauCblR61cvDUavxyiHbtD4zTdw0A==} engines: {node: '>=14'} peerDependencies: '@nuxt/kit': '*' - vite: ^6.0.0 || ^7.0.0-0 + vite: ^8.0.0-0 peerDependenciesMeta: '@nuxt/kit': optional: true - vite-plugin-storybook-nextjs@3.2.3: - resolution: {integrity: sha512-NQvkiZKfbGmk0j3mYeTJnGiucV+VOcryCsm/CoE7rBVRrpVntg5lWj+CbosFwHhGPpWQ3I4HJ3nSRzDq0u74Ug==} + vite-plugin-storybook-nextjs@3.2.4: + resolution: {integrity: sha512-shFOJpGQsWDS1FLm8BR8b6FIQC65pFZ5a0IUFGLiBHAX1eRz0N8TOhUJN4p708zfPBLDXqWzj++ocECe8gSoMg==} peerDependencies: next: ^14.1.0 || ^15.0.0 || ^16.0.0 - storybook: ^0.0.0-0 || ^9.0.0 || ^10.0.0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 + storybook: ^0.0.0-0 || ^9.0.0 || ^10.0.0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 || ^10.4.0-0 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - vite-plus@0.1.13: - resolution: {integrity: sha512-DP87+eRFhYYDdcjm2nr3DOKt0cv6mIXCNXn+zc59YHgR0Wh7uL2E/55mjusJ7ajwcXenpGW+c4KPeoqhQAbhxg==} + vite-plus@0.1.14: + resolution: {integrity: sha512-p4pWlpZZNiEsHxPWNdeIU9iuPix3ydm3ficb0dXPggoyIkdotfXtvn2NPX9KwfiQImU72EVEs4+VYBZYNcUYrw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -7755,6 +8826,49 @@ packages: peerDependencies: vite: '*' + vite@8.0.3: + resolution: {integrity: sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: 0.27.2 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: 2.8.3 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vitefu@1.1.2: resolution: {integrity: sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==} peerDependencies: @@ -7763,8 +8877,8 @@ packages: vite: optional: true - vitest-canvas-mock@1.1.3: - resolution: {integrity: sha512-zlKJR776Qgd+bcACPh0Pq5MG3xWq+CdkACKY/wX4Jyija0BSz8LH3aCCgwFKYFwtm565+050YFEGG9Ki0gE/Hw==} + vitest-canvas-mock@1.1.4: + resolution: {integrity: sha512-4boWHY+STwAxGl1+uwakNNoQky5EjPLC8HuponXNoAscYyT1h/F7RUvTkl4IyF/MiWr3V8Q626je3Iel3eArqA==} peerDependencies: vitest: ^3.0.0 || ^4.0.0 @@ -7798,10 +8912,6 @@ packages: peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - w3c-xmlserializer@5.0.0: - resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} - engines: {node: '>=18'} - walk-up-path@4.0.0: resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} engines: {node: 20 || >=22} @@ -7816,10 +8926,6 @@ packages: web-vitals@5.1.0: resolution: {integrity: sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg==} - webidl-conversions@8.0.1: - resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} - engines: {node: '>=20'} - webpack-sources@3.3.4: resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} engines: {node: '>=10.13.0'} @@ -7850,14 +8956,6 @@ packages: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} - whatwg-mimetype@5.0.0: - resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} - engines: {node: '>=20'} - - whatwg-url@16.0.1: - resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -7874,18 +8972,6 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.19.0: - resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - ws@8.20.0: resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} engines: {node: '>=10.0.0'} @@ -7902,16 +8988,17 @@ packages: resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} engines: {node: '>=18'} + wsl-utils@0.3.1: + resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} + engines: {node: '>=20'} + xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} - xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} - - xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + xmlbuilder@15.1.1: + resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} + engines: {node: '>=8.0'} xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} @@ -7945,9 +9032,16 @@ packages: 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'} + yoga-layout@3.2.1: resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} + yup@1.7.1: + resolution: {integrity: sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==} + zen-observable@0.10.0: resolution: {integrity: sha512-iI3lT0iojZhKwT5DaFy2Ce42n3yFcLdFyOh01G7H0flMY60P8MJuVFEoJoNwXlmAyQ45GrjL6AcZmmlv8A5rbw==} @@ -8013,27 +9107,27 @@ snapshots: '@alloc/quick-lru@5.2.0': {} - '@amplitude/analytics-browser@2.37.0': + '@amplitude/analytics-browser@2.38.0': dependencies: - '@amplitude/analytics-core': 2.43.0 - '@amplitude/plugin-autocapture-browser': 1.24.1 - '@amplitude/plugin-custom-enrichment-browser': 0.1.0 - '@amplitude/plugin-network-capture-browser': 1.9.9 - '@amplitude/plugin-page-url-enrichment-browser': 0.7.0 - '@amplitude/plugin-page-view-tracking-browser': 2.9.1 - '@amplitude/plugin-web-vitals-browser': 1.1.24 + '@amplitude/analytics-core': 2.44.0 + '@amplitude/plugin-autocapture-browser': 1.25.0 + '@amplitude/plugin-custom-enrichment-browser': 0.1.2 + '@amplitude/plugin-network-capture-browser': 1.9.11 + '@amplitude/plugin-page-url-enrichment-browser': 0.7.3 + '@amplitude/plugin-page-view-tracking-browser': 2.9.4 + '@amplitude/plugin-web-vitals-browser': 1.1.26 tslib: 2.8.1 - '@amplitude/analytics-client-common@2.4.39': + '@amplitude/analytics-client-common@2.4.41': dependencies: '@amplitude/analytics-connector': 1.6.4 - '@amplitude/analytics-core': 2.43.0 + '@amplitude/analytics-core': 2.44.0 '@amplitude/analytics-types': 2.11.1 tslib: 2.8.1 '@amplitude/analytics-connector@1.6.4': {} - '@amplitude/analytics-core@2.43.0': + '@amplitude/analytics-core@2.44.0': dependencies: '@amplitude/analytics-connector': 1.6.4 '@types/zen-observable': 0.8.3 @@ -8047,96 +9141,100 @@ snapshots: dependencies: js-base64: 3.7.8 - '@amplitude/plugin-autocapture-browser@1.24.1': + '@amplitude/plugin-autocapture-browser@1.25.0': dependencies: - '@amplitude/analytics-core': 2.43.0 + '@amplitude/analytics-core': 2.44.0 tslib: 2.8.1 - '@amplitude/plugin-custom-enrichment-browser@0.1.0': + '@amplitude/plugin-custom-enrichment-browser@0.1.2': dependencies: - '@amplitude/analytics-core': 2.43.0 + '@amplitude/analytics-core': 2.44.0 tslib: 2.8.1 - '@amplitude/plugin-network-capture-browser@1.9.9': + '@amplitude/plugin-network-capture-browser@1.9.11': dependencies: - '@amplitude/analytics-core': 2.43.0 + '@amplitude/analytics-core': 2.44.0 tslib: 2.8.1 - '@amplitude/plugin-page-url-enrichment-browser@0.7.0': + '@amplitude/plugin-page-url-enrichment-browser@0.7.3': dependencies: - '@amplitude/analytics-core': 2.43.0 + '@amplitude/analytics-core': 2.44.0 tslib: 2.8.1 - '@amplitude/plugin-page-view-tracking-browser@2.9.1': + '@amplitude/plugin-page-view-tracking-browser@2.9.4': dependencies: - '@amplitude/analytics-core': 2.43.0 + '@amplitude/analytics-core': 2.44.0 tslib: 2.8.1 - '@amplitude/plugin-session-replay-browser@1.27.1(@amplitude/rrweb@2.0.0-alpha.36)(rollup@4.59.0)': + '@amplitude/plugin-session-replay-browser@1.27.5(@amplitude/rrweb@2.0.0-alpha.37)(rollup@4.59.0)': dependencies: - '@amplitude/analytics-client-common': 2.4.39 - '@amplitude/analytics-core': 2.43.0 + '@amplitude/analytics-client-common': 2.4.41 + '@amplitude/analytics-core': 2.44.0 '@amplitude/analytics-types': 2.11.1 - '@amplitude/rrweb-plugin-console-record': 2.0.0-alpha.36(@amplitude/rrweb@2.0.0-alpha.36) + '@amplitude/rrweb-plugin-console-record': 2.0.0-alpha.36(@amplitude/rrweb@2.0.0-alpha.37) '@amplitude/rrweb-record': 2.0.0-alpha.36 - '@amplitude/session-replay-browser': 1.34.1(@amplitude/rrweb@2.0.0-alpha.36)(rollup@4.59.0) + '@amplitude/session-replay-browser': 1.35.0(@amplitude/rrweb@2.0.0-alpha.37)(rollup@4.59.0) idb-keyval: 6.2.2 tslib: 2.8.1 transitivePeerDependencies: - '@amplitude/rrweb' - rollup - '@amplitude/plugin-web-vitals-browser@1.1.24': + '@amplitude/plugin-web-vitals-browser@1.1.26': dependencies: - '@amplitude/analytics-core': 2.43.0 + '@amplitude/analytics-core': 2.44.0 tslib: 2.8.1 web-vitals: 5.1.0 - '@amplitude/rrdom@2.0.0-alpha.36': + '@amplitude/rrdom@2.0.0-alpha.37': dependencies: - '@amplitude/rrweb-snapshot': 2.0.0-alpha.36 + '@amplitude/rrweb-snapshot': 2.0.0-alpha.37 '@amplitude/rrweb-packer@2.0.0-alpha.36': dependencies: - '@amplitude/rrweb-types': 2.0.0-alpha.36 + '@amplitude/rrweb-types': 2.0.0-alpha.37 fflate: 0.4.8 - '@amplitude/rrweb-plugin-console-record@2.0.0-alpha.36(@amplitude/rrweb@2.0.0-alpha.36)': + '@amplitude/rrweb-plugin-console-record@2.0.0-alpha.36(@amplitude/rrweb@2.0.0-alpha.37)': dependencies: - '@amplitude/rrweb': 2.0.0-alpha.36 + '@amplitude/rrweb': 2.0.0-alpha.37 '@amplitude/rrweb-record@2.0.0-alpha.36': dependencies: - '@amplitude/rrweb': 2.0.0-alpha.36 - '@amplitude/rrweb-types': 2.0.0-alpha.36 + '@amplitude/rrweb': 2.0.0-alpha.37 + '@amplitude/rrweb-types': 2.0.0-alpha.37 - '@amplitude/rrweb-snapshot@2.0.0-alpha.36': + '@amplitude/rrweb-snapshot@2.0.0-alpha.37': dependencies: postcss: 8.5.8 '@amplitude/rrweb-types@2.0.0-alpha.36': {} + '@amplitude/rrweb-types@2.0.0-alpha.37': {} + '@amplitude/rrweb-utils@2.0.0-alpha.36': {} - '@amplitude/rrweb@2.0.0-alpha.36': + '@amplitude/rrweb-utils@2.0.0-alpha.37': {} + + '@amplitude/rrweb@2.0.0-alpha.37': dependencies: - '@amplitude/rrdom': 2.0.0-alpha.36 - '@amplitude/rrweb-snapshot': 2.0.0-alpha.36 - '@amplitude/rrweb-types': 2.0.0-alpha.36 - '@amplitude/rrweb-utils': 2.0.0-alpha.36 + '@amplitude/rrdom': 2.0.0-alpha.37 + '@amplitude/rrweb-snapshot': 2.0.0-alpha.37 + '@amplitude/rrweb-types': 2.0.0-alpha.37 + '@amplitude/rrweb-utils': 2.0.0-alpha.37 '@types/css-font-loading-module': 0.0.7 '@xstate/fsm': 1.6.5 base64-arraybuffer: 1.0.2 mitt: 3.0.1 - '@amplitude/session-replay-browser@1.34.1(@amplitude/rrweb@2.0.0-alpha.36)(rollup@4.59.0)': + '@amplitude/session-replay-browser@1.35.0(@amplitude/rrweb@2.0.0-alpha.37)(rollup@4.59.0)': dependencies: - '@amplitude/analytics-client-common': 2.4.39 - '@amplitude/analytics-core': 2.43.0 + '@amplitude/analytics-client-common': 2.4.41 + '@amplitude/analytics-core': 2.44.0 '@amplitude/analytics-types': 2.11.1 '@amplitude/experiment-core': 0.7.2 '@amplitude/rrweb-packer': 2.0.0-alpha.36 - '@amplitude/rrweb-plugin-console-record': 2.0.0-alpha.36(@amplitude/rrweb@2.0.0-alpha.36) + '@amplitude/rrweb-plugin-console-record': 2.0.0-alpha.36(@amplitude/rrweb@2.0.0-alpha.37) '@amplitude/rrweb-record': 2.0.0-alpha.36 '@amplitude/rrweb-types': 2.0.0-alpha.36 '@amplitude/rrweb-utils': 2.0.0-alpha.36 @@ -8150,34 +9248,34 @@ snapshots: '@amplitude/targeting@0.2.0': dependencies: - '@amplitude/analytics-client-common': 2.4.39 - '@amplitude/analytics-core': 2.43.0 + '@amplitude/analytics-client-common': 2.4.41 + '@amplitude/analytics-core': 2.44.0 '@amplitude/analytics-types': 2.11.1 '@amplitude/experiment-core': 0.7.2 idb: 8.0.0 tslib: 2.8.1 - '@antfu/eslint-config@7.7.3(@eslint-react/eslint-plugin@3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.2.1)(@typescript-eslint/rule-tester@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3))(@typescript-eslint/utils@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(@vue/compiler-sfc@3.5.30)(eslint-plugin-react-hooks@7.0.1(eslint@10.1.0(jiti@1.21.7)))(eslint-plugin-react-refresh@0.5.2(eslint@10.1.0(jiti@1.21.7)))(eslint@10.1.0(jiti@1.21.7))(oxlint@1.56.0(oxlint-tsgolint@0.17.1))(typescript@5.9.3)': + '@antfu/eslint-config@7.7.3(@eslint-react/eslint-plugin@3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@next/eslint-plugin-next@16.2.1)(@typescript-eslint/rule-tester@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.2(typescript@5.9.3))(@typescript-eslint/utils@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(@vue/compiler-sfc@3.5.31)(eslint-plugin-react-hooks@7.0.1(eslint@10.1.0(jiti@1.21.7)))(eslint-plugin-react-refresh@0.5.2(eslint@10.1.0(jiti@1.21.7)))(eslint@10.1.0(jiti@1.21.7))(oxlint@1.57.0(oxlint-tsgolint@0.17.3))(typescript@5.9.3)': dependencies: '@antfu/install-pkg': 1.1.0 '@clack/prompts': 1.1.0 - '@e18e/eslint-plugin': 0.2.0(eslint@10.1.0(jiti@1.21.7))(oxlint@1.56.0(oxlint-tsgolint@0.17.1)) + '@e18e/eslint-plugin': 0.2.0(eslint@10.1.0(jiti@1.21.7))(oxlint@1.57.0(oxlint-tsgolint@0.17.3)) '@eslint-community/eslint-plugin-eslint-comments': 4.7.1(eslint@10.1.0(jiti@1.21.7)) '@eslint/markdown': 7.5.1 '@stylistic/eslint-plugin': 5.10.0(eslint@10.1.0(jiti@1.21.7)) - '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/parser': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@vitest/eslint-plugin': 1.6.12(@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@vitest/eslint-plugin': 1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) ansis: 4.2.0 cac: 7.0.0 eslint: 10.1.0(jiti@1.21.7) - eslint-config-flat-gitignore: 2.2.1(eslint@10.1.0(jiti@1.21.7)) + eslint-config-flat-gitignore: 2.3.0(eslint@10.1.0(jiti@1.21.7)) eslint-flat-config-utils: 3.0.2 eslint-merge-processors: 2.0.0(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-antfu: 3.2.2(eslint@10.1.0(jiti@1.21.7)) - eslint-plugin-command: 3.5.2(@typescript-eslint/rule-tester@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3))(@typescript-eslint/utils@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7)) + eslint-plugin-command: 3.5.2(@typescript-eslint/rule-tester@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.2(typescript@5.9.3))(@typescript-eslint/utils@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-import-lite: 0.5.2(eslint@10.1.0(jiti@1.21.7)) - eslint-plugin-jsdoc: 62.8.0(eslint@10.1.0(jiti@1.21.7)) + eslint-plugin-jsdoc: 62.8.1(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-jsonc: 3.1.2(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-n: 17.24.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint-plugin-no-only-tests: 3.3.0 @@ -8186,10 +9284,10 @@ snapshots: eslint-plugin-regexp: 3.1.0(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-toml: 1.3.1(eslint@10.1.0(jiti@1.21.7)) eslint-plugin-unicorn: 63.0.0(eslint@10.1.0(jiti@1.21.7)) - eslint-plugin-unused-imports: 4.4.1(@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7)) - eslint-plugin-vue: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.1.0(jiti@1.21.7)))(@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(vue-eslint-parser@10.4.0(eslint@10.1.0(jiti@1.21.7))) + eslint-plugin-unused-imports: 4.4.1(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7)) + eslint-plugin-vue: 10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.1.0(jiti@1.21.7)))(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(vue-eslint-parser@10.4.0(eslint@10.1.0(jiti@1.21.7))) eslint-plugin-yml: 3.3.1(eslint@10.1.0(jiti@1.21.7)) - eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.30)(eslint@10.1.0(jiti@1.21.7)) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.31)(eslint@10.1.0(jiti@1.21.7)) globals: 17.4.0 local-pkg: 1.1.2 parse-gitignore: 2.0.0 @@ -8227,27 +9325,6 @@ snapshots: '@antfu/utils@8.1.1': {} - '@asamuzakjp/css-color@5.1.1': - dependencies: - '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 - lru-cache: 11.2.7 - optional: true - - '@asamuzakjp/dom-selector@7.0.4': - dependencies: - '@asamuzakjp/nwsapi': 2.3.9 - bidi-js: 1.0.3 - css-tree: 3.2.1 - is-potential-custom-element-name: 1.0.1 - lru-cache: 11.2.7 - optional: true - - '@asamuzakjp/nwsapi@2.3.9': - optional: true - '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -8269,7 +9346,7 @@ snapshots: '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -8341,7 +9418,7 @@ snapshots: '@babel/parser': 7.29.2 '@babel/template': 7.28.6 '@babel/types': 7.29.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -8378,11 +9455,6 @@ snapshots: '@braintree/sanitize-url@7.1.2': {} - '@bramus/specificity@2.4.2': - dependencies: - css-tree: 3.2.1 - optional: true - '@chevrotain/cst-dts-gen@11.1.2': dependencies: '@chevrotain/gast': 11.1.2 @@ -8400,13 +9472,13 @@ snapshots: '@chevrotain/utils@11.1.2': {} - '@chromatic-com/storybook@5.0.2(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': + '@chromatic-com/storybook@5.1.1(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: '@neoconfetti/react': 1.0.0 chromatic: 13.3.5 filesize: 10.1.6 jsonfile: 6.2.0 - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) strip-ansi: 7.2.0 transitivePeerDependencies: - '@chromatic-com/cypress' @@ -8434,7 +9506,7 @@ snapshots: '@code-inspector/core@1.4.5': dependencies: - '@vue/compiler-dom': 3.5.30 + '@vue/compiler-dom': 3.5.31 chalk: 4.1.2 dotenv: 16.6.1 launch-ide: 1.4.3 @@ -8474,55 +9546,135 @@ snapshots: transitivePeerDependencies: - supports-color - '@csstools/color-helpers@6.0.2': + '@colors/colors@1.5.0': optional: true - '@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@cucumber/ci-environment@13.0.0': {} + + '@cucumber/cucumber-expressions@19.0.0': dependencies: - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 - optional: true + regexp-match-indices: 1.0.2 - '@csstools/css-color-parser@4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@cucumber/cucumber@12.7.0': dependencies: - '@csstools/color-helpers': 6.0.2 - '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 - optional: true + '@cucumber/ci-environment': 13.0.0 + '@cucumber/cucumber-expressions': 19.0.0 + '@cucumber/gherkin': 38.0.0 + '@cucumber/gherkin-streams': 6.0.0(@cucumber/gherkin@38.0.0)(@cucumber/message-streams@4.0.1(@cucumber/messages@32.0.1))(@cucumber/messages@32.0.1) + '@cucumber/gherkin-utils': 11.0.0 + '@cucumber/html-formatter': 23.0.0(@cucumber/messages@32.0.1) + '@cucumber/junit-xml-formatter': 0.9.0(@cucumber/messages@32.0.1) + '@cucumber/message-streams': 4.0.1(@cucumber/messages@32.0.1) + '@cucumber/messages': 32.0.1 + '@cucumber/pretty-formatter': 1.0.1(@cucumber/cucumber@12.7.0)(@cucumber/messages@32.0.1) + '@cucumber/tag-expressions': 9.1.0 + assertion-error-formatter: 3.0.0 + capital-case: 1.0.4 + chalk: 4.1.2 + cli-table3: 0.6.5 + commander: 14.0.3 + debug: 4.4.3(supports-color@8.1.1) + error-stack-parser: 2.1.4 + figures: 3.2.0 + glob: 13.0.6 + has-ansi: 4.0.1 + indent-string: 4.0.0 + is-installed-globally: 0.4.0 + is-stream: 2.0.1 + knuth-shuffle-seeded: 1.0.6 + lodash.merge: 4.6.2 + lodash.mergewith: 4.6.2 + luxon: 3.7.2 + mime: 3.0.0 + mkdirp: 3.0.1 + mz: 2.7.0 + progress: 2.0.3 + read-package-up: 12.0.0 + semver: 7.7.4 + string-argv: 0.3.1 + supports-color: 8.1.1 + type-fest: 4.41.0 + util-arity: 1.1.0 + yaml: 2.8.3 + yup: 1.7.1 - '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': + '@cucumber/gherkin-streams@6.0.0(@cucumber/gherkin@38.0.0)(@cucumber/message-streams@4.0.1(@cucumber/messages@32.0.1))(@cucumber/messages@32.0.1)': dependencies: - '@csstools/css-tokenizer': 4.0.0 - optional: true + '@cucumber/gherkin': 38.0.0 + '@cucumber/message-streams': 4.0.1(@cucumber/messages@32.0.1) + '@cucumber/messages': 32.0.1 + commander: 14.0.0 + source-map-support: 0.5.21 - '@csstools/css-syntax-patches-for-csstree@1.1.2(css-tree@3.2.1)': - optionalDependencies: - css-tree: 3.2.1 - optional: true + '@cucumber/gherkin-utils@11.0.0': + dependencies: + '@cucumber/gherkin': 38.0.0 + '@cucumber/messages': 32.0.1 + '@teppeis/multimaps': 3.0.0 + commander: 14.0.2 + source-map-support: 0.5.21 - '@csstools/css-tokenizer@4.0.0': - optional: true + '@cucumber/gherkin@38.0.0': + dependencies: + '@cucumber/messages': 32.0.1 - '@e18e/eslint-plugin@0.2.0(eslint@10.1.0(jiti@1.21.7))(oxlint@1.56.0(oxlint-tsgolint@0.17.1))': + '@cucumber/html-formatter@23.0.0(@cucumber/messages@32.0.1)': + dependencies: + '@cucumber/messages': 32.0.1 + + '@cucumber/junit-xml-formatter@0.9.0(@cucumber/messages@32.0.1)': + dependencies: + '@cucumber/messages': 32.0.1 + '@cucumber/query': 14.7.0(@cucumber/messages@32.0.1) + '@teppeis/multimaps': 3.0.0 + luxon: 3.7.2 + xmlbuilder: 15.1.1 + + '@cucumber/message-streams@4.0.1(@cucumber/messages@32.0.1)': + dependencies: + '@cucumber/messages': 32.0.1 + + '@cucumber/messages@32.0.1': + dependencies: + class-transformer: 0.5.1 + reflect-metadata: 0.2.2 + + '@cucumber/pretty-formatter@1.0.1(@cucumber/cucumber@12.7.0)(@cucumber/messages@32.0.1)': + dependencies: + '@cucumber/cucumber': 12.7.0 + '@cucumber/messages': 32.0.1 + ansi-styles: 5.2.0 + cli-table3: 0.6.5 + figures: 3.2.0 + ts-dedent: 2.2.0 + + '@cucumber/query@14.7.0(@cucumber/messages@32.0.1)': + dependencies: + '@cucumber/messages': 32.0.1 + '@teppeis/multimaps': 3.0.0 + lodash.sortby: 4.7.0 + + '@cucumber/tag-expressions@9.1.0': {} + + '@e18e/eslint-plugin@0.2.0(eslint@10.1.0(jiti@1.21.7))(oxlint@1.57.0(oxlint-tsgolint@0.17.3))': dependencies: eslint-plugin-depend: 1.5.0(eslint@10.1.0(jiti@1.21.7)) optionalDependencies: eslint: 10.1.0(jiti@1.21.7) - oxlint: 1.56.0(oxlint-tsgolint@0.17.1) + oxlint: 1.57.0(oxlint-tsgolint@0.17.3) '@egoist/tailwindcss-icons@1.9.2(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))': dependencies: '@iconify/utils': 3.1.0 tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.3) - '@emnapi/core@1.9.0': + '@emnapi/core@1.9.1': dependencies: '@emnapi/wasi-threads': 1.2.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.9.0': + '@emnapi/runtime@1.9.1': dependencies: tslib: 2.8.1 optional: true @@ -8537,7 +9689,7 @@ snapshots: '@es-joy/jsdoccomment@0.84.0': dependencies: '@types/estree': 1.0.8 - '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/types': 8.57.2 comment-parser: 1.4.5 esquery: 1.7.0 jsdoc-type-pratt-parser: 7.1.1 @@ -8633,6 +9785,11 @@ snapshots: eslint: 10.1.0(jiti@1.21.7) eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.9.1(eslint@10.1.0(jiti@2.6.1))': + dependencies: + eslint: 10.1.0(jiti@2.6.1) + eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.9.1(eslint@9.27.0(jiti@1.21.7))': dependencies: eslint: 9.27.0(jiti@1.21.7) @@ -8642,9 +9799,9 @@ snapshots: '@eslint-react/ast@3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) string-ts: 2.3.1 typescript: 5.9.3 @@ -8656,9 +9813,9 @@ snapshots: '@eslint-react/ast': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/shared': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/var': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) ts-pattern: 5.9.0 typescript: 5.9.3 @@ -8668,24 +9825,24 @@ snapshots: '@eslint-react/eslint-plugin@3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: '@eslint-react/shared': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/type-utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/type-utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) eslint-plugin-react-dom: 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint-plugin-react-naming-convention: 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint-plugin-react-rsc: 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint-plugin-react-web-api: 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint-plugin-react-x: 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color '@eslint-react/shared@3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) ts-pattern: 5.9.0 typescript: 5.9.3 @@ -8697,9 +9854,9 @@ snapshots: dependencies: '@eslint-react/ast': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/shared': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) ts-pattern: 5.9.0 typescript: 5.9.3 @@ -8715,7 +9872,7 @@ snapshots: '@eslint/config-array@0.20.1': dependencies: '@eslint/object-schema': 2.1.7 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -8723,7 +9880,7 @@ snapshots: '@eslint/config-array@0.23.3': dependencies: '@eslint/object-schema': 3.0.3 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) minimatch: 10.2.4 transitivePeerDependencies: - supports-color @@ -8758,7 +9915,7 @@ snapshots: '@eslint/eslintrc@3.3.5': dependencies: ajv: 6.14.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -8769,6 +9926,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/js@10.0.1(eslint@10.1.0(jiti@2.6.1))': + optionalDependencies: + eslint: 10.1.0(jiti@2.6.1) + '@eslint/js@9.27.0': {} '@eslint/markdown@7.5.1': @@ -8804,9 +9965,6 @@ snapshots: '@eslint/core': 1.1.1 levn: 0.4.1 - '@exodus/bytes@1.15.0': - optional: true - '@floating-ui/core@1.7.5': dependencies: '@floating-ui/utils': 0.2.11 @@ -8862,9 +10020,9 @@ snapshots: dependencies: react: 19.2.4 - '@hono/node-server@1.19.11(hono@4.12.8)': + '@hono/node-server@1.19.11(hono@4.12.9)': dependencies: - hono: 4.12.8 + hono: 4.12.9 '@humanfs/core@0.19.1': {} @@ -8906,11 +10064,11 @@ snapshots: '@antfu/install-pkg': 1.1.0 '@antfu/utils': 8.1.1 '@iconify/types': 2.0.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) globals: 15.15.0 kolorist: 1.8.0 local-pkg: 1.1.2 - mlly: 1.8.1 + mlly: 1.8.2 transitivePeerDependencies: - supports-color @@ -8918,7 +10076,7 @@ snapshots: dependencies: '@antfu/install-pkg': 1.1.0 '@iconify/types': 2.0.0 - mlly: 1.8.1 + mlly: 1.8.2 '@img/colour@1.1.0': {} @@ -9004,7 +10162,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.9.0 + '@emnapi/runtime': 1.9.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -9020,11 +10178,11 @@ snapshots: dependencies: minipass: 7.1.3 - '@joshwooding/vite-plugin-react-docgen-typescript@0.6.4(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3)': + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.4(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3)': dependencies: glob: 13.0.6 react-docgen-typescript: 2.4.0(typescript@5.9.3) - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' optionalDependencies: typescript: 5.9.3 @@ -9279,10 +10437,10 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@napi-rs/wasm-runtime@1.1.1': + '@napi-rs/wasm-runtime@1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)': dependencies: - '@emnapi/core': 1.9.0 - '@emnapi/runtime': 1.9.0 + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 '@tybys/wasm-util': 0.10.1 optional: true @@ -9339,139 +10497,146 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 + '@nolyfill/hasown@1.0.44': {} + '@nolyfill/is-core-module@1.0.39': {} '@nolyfill/safer-buffer@1.0.44': {} '@nolyfill/side-channel@1.0.44': {} - '@orpc/client@1.13.9': + '@orpc/client@1.13.13': dependencies: - '@orpc/shared': 1.13.9 - '@orpc/standard-server': 1.13.9 - '@orpc/standard-server-fetch': 1.13.9 - '@orpc/standard-server-peer': 1.13.9 + '@orpc/shared': 1.13.13 + '@orpc/standard-server': 1.13.13 + '@orpc/standard-server-fetch': 1.13.13 + '@orpc/standard-server-peer': 1.13.13 transitivePeerDependencies: - '@opentelemetry/api' - '@orpc/contract@1.13.9': + '@orpc/contract@1.13.13': dependencies: - '@orpc/client': 1.13.9 - '@orpc/shared': 1.13.9 + '@orpc/client': 1.13.13 + '@orpc/shared': 1.13.13 '@standard-schema/spec': 1.1.0 openapi-types: 12.1.3 transitivePeerDependencies: - '@opentelemetry/api' - '@orpc/openapi-client@1.13.9': + '@orpc/openapi-client@1.13.13': dependencies: - '@orpc/client': 1.13.9 - '@orpc/contract': 1.13.9 - '@orpc/shared': 1.13.9 - '@orpc/standard-server': 1.13.9 + '@orpc/client': 1.13.13 + '@orpc/contract': 1.13.13 + '@orpc/shared': 1.13.13 + '@orpc/standard-server': 1.13.13 transitivePeerDependencies: - '@opentelemetry/api' - '@orpc/shared@1.13.9': + '@orpc/shared@1.13.13': dependencies: radash: 12.1.1 - type-fest: 5.4.4 + type-fest: 5.5.0 - '@orpc/standard-server-fetch@1.13.9': + '@orpc/standard-server-fetch@1.13.13': dependencies: - '@orpc/shared': 1.13.9 - '@orpc/standard-server': 1.13.9 + '@orpc/shared': 1.13.13 + '@orpc/standard-server': 1.13.13 transitivePeerDependencies: - '@opentelemetry/api' - '@orpc/standard-server-peer@1.13.9': + '@orpc/standard-server-peer@1.13.13': dependencies: - '@orpc/shared': 1.13.9 - '@orpc/standard-server': 1.13.9 + '@orpc/shared': 1.13.13 + '@orpc/standard-server': 1.13.13 transitivePeerDependencies: - '@opentelemetry/api' - '@orpc/standard-server@1.13.9': + '@orpc/standard-server@1.13.13': dependencies: - '@orpc/shared': 1.13.9 + '@orpc/shared': 1.13.13 transitivePeerDependencies: - '@opentelemetry/api' - '@orpc/tanstack-query@1.13.9(@orpc/client@1.13.9)(@tanstack/query-core@5.95.0)': + '@orpc/tanstack-query@1.13.13(@orpc/client@1.13.13)(@tanstack/query-core@5.95.2)': dependencies: - '@orpc/client': 1.13.9 - '@orpc/shared': 1.13.9 - '@tanstack/query-core': 5.95.0 + '@orpc/client': 1.13.13 + '@orpc/shared': 1.13.13 + '@tanstack/query-core': 5.95.2 transitivePeerDependencies: - '@opentelemetry/api' '@ota-meshi/ast-token-store@0.3.0': {} - '@oxc-parser/binding-android-arm-eabi@0.120.0': + '@oxc-parser/binding-android-arm-eabi@0.121.0': optional: true - '@oxc-parser/binding-android-arm64@0.120.0': + '@oxc-parser/binding-android-arm64@0.121.0': optional: true - '@oxc-parser/binding-darwin-arm64@0.120.0': + '@oxc-parser/binding-darwin-arm64@0.121.0': optional: true - '@oxc-parser/binding-darwin-x64@0.120.0': + '@oxc-parser/binding-darwin-x64@0.121.0': optional: true - '@oxc-parser/binding-freebsd-x64@0.120.0': + '@oxc-parser/binding-freebsd-x64@0.121.0': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.120.0': + '@oxc-parser/binding-linux-arm-gnueabihf@0.121.0': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.120.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.121.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.120.0': + '@oxc-parser/binding-linux-arm64-gnu@0.121.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.120.0': + '@oxc-parser/binding-linux-arm64-musl@0.121.0': optional: true - '@oxc-parser/binding-linux-ppc64-gnu@0.120.0': + '@oxc-parser/binding-linux-ppc64-gnu@0.121.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.120.0': + '@oxc-parser/binding-linux-riscv64-gnu@0.121.0': optional: true - '@oxc-parser/binding-linux-riscv64-musl@0.120.0': + '@oxc-parser/binding-linux-riscv64-musl@0.121.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.120.0': + '@oxc-parser/binding-linux-s390x-gnu@0.121.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.120.0': + '@oxc-parser/binding-linux-x64-gnu@0.121.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.120.0': + '@oxc-parser/binding-linux-x64-musl@0.121.0': optional: true - '@oxc-parser/binding-openharmony-arm64@0.120.0': + '@oxc-parser/binding-openharmony-arm64@0.121.0': optional: true - '@oxc-parser/binding-wasm32-wasi@0.120.0': + '@oxc-parser/binding-wasm32-wasi@0.121.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)': dependencies: - '@napi-rs/wasm-runtime': 1.1.1 + '@napi-rs/wasm-runtime': 1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.120.0': + '@oxc-parser/binding-win32-arm64-msvc@0.121.0': optional: true - '@oxc-parser/binding-win32-ia32-msvc@0.120.0': + '@oxc-parser/binding-win32-ia32-msvc@0.121.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.120.0': + '@oxc-parser/binding-win32-x64-msvc@0.121.0': optional: true - '@oxc-project/runtime@0.120.0': {} + '@oxc-project/runtime@0.121.0': {} - '@oxc-project/types@0.120.0': {} + '@oxc-project/types@0.121.0': {} + + '@oxc-project/types@0.122.0': {} '@oxc-resolver/binding-android-arm-eabi@11.19.1': optional: true @@ -9521,9 +10686,12 @@ snapshots: '@oxc-resolver/binding-openharmony-arm64@11.19.1': optional: true - '@oxc-resolver/binding-wasm32-wasi@11.19.1': + '@oxc-resolver/binding-wasm32-wasi@11.19.1(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)': dependencies: - '@napi-rs/wasm-runtime': 1.1.1 + '@napi-rs/wasm-runtime': 1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' optional: true '@oxc-resolver/binding-win32-arm64-msvc@11.19.1': @@ -9535,136 +10703,136 @@ snapshots: '@oxc-resolver/binding-win32-x64-msvc@11.19.1': optional: true - '@oxfmt/binding-android-arm-eabi@0.41.0': + '@oxfmt/binding-android-arm-eabi@0.42.0': optional: true - '@oxfmt/binding-android-arm64@0.41.0': + '@oxfmt/binding-android-arm64@0.42.0': optional: true - '@oxfmt/binding-darwin-arm64@0.41.0': + '@oxfmt/binding-darwin-arm64@0.42.0': optional: true - '@oxfmt/binding-darwin-x64@0.41.0': + '@oxfmt/binding-darwin-x64@0.42.0': optional: true - '@oxfmt/binding-freebsd-x64@0.41.0': + '@oxfmt/binding-freebsd-x64@0.42.0': optional: true - '@oxfmt/binding-linux-arm-gnueabihf@0.41.0': + '@oxfmt/binding-linux-arm-gnueabihf@0.42.0': optional: true - '@oxfmt/binding-linux-arm-musleabihf@0.41.0': + '@oxfmt/binding-linux-arm-musleabihf@0.42.0': optional: true - '@oxfmt/binding-linux-arm64-gnu@0.41.0': + '@oxfmt/binding-linux-arm64-gnu@0.42.0': optional: true - '@oxfmt/binding-linux-arm64-musl@0.41.0': + '@oxfmt/binding-linux-arm64-musl@0.42.0': optional: true - '@oxfmt/binding-linux-ppc64-gnu@0.41.0': + '@oxfmt/binding-linux-ppc64-gnu@0.42.0': optional: true - '@oxfmt/binding-linux-riscv64-gnu@0.41.0': + '@oxfmt/binding-linux-riscv64-gnu@0.42.0': optional: true - '@oxfmt/binding-linux-riscv64-musl@0.41.0': + '@oxfmt/binding-linux-riscv64-musl@0.42.0': optional: true - '@oxfmt/binding-linux-s390x-gnu@0.41.0': + '@oxfmt/binding-linux-s390x-gnu@0.42.0': optional: true - '@oxfmt/binding-linux-x64-gnu@0.41.0': + '@oxfmt/binding-linux-x64-gnu@0.42.0': optional: true - '@oxfmt/binding-linux-x64-musl@0.41.0': + '@oxfmt/binding-linux-x64-musl@0.42.0': optional: true - '@oxfmt/binding-openharmony-arm64@0.41.0': + '@oxfmt/binding-openharmony-arm64@0.42.0': optional: true - '@oxfmt/binding-win32-arm64-msvc@0.41.0': + '@oxfmt/binding-win32-arm64-msvc@0.42.0': optional: true - '@oxfmt/binding-win32-ia32-msvc@0.41.0': + '@oxfmt/binding-win32-ia32-msvc@0.42.0': optional: true - '@oxfmt/binding-win32-x64-msvc@0.41.0': + '@oxfmt/binding-win32-x64-msvc@0.42.0': optional: true - '@oxlint-tsgolint/darwin-arm64@0.17.1': + '@oxlint-tsgolint/darwin-arm64@0.17.3': optional: true - '@oxlint-tsgolint/darwin-x64@0.17.1': + '@oxlint-tsgolint/darwin-x64@0.17.3': optional: true - '@oxlint-tsgolint/linux-arm64@0.17.1': + '@oxlint-tsgolint/linux-arm64@0.17.3': optional: true - '@oxlint-tsgolint/linux-x64@0.17.1': + '@oxlint-tsgolint/linux-x64@0.17.3': optional: true - '@oxlint-tsgolint/win32-arm64@0.17.1': + '@oxlint-tsgolint/win32-arm64@0.17.3': optional: true - '@oxlint-tsgolint/win32-x64@0.17.1': + '@oxlint-tsgolint/win32-x64@0.17.3': optional: true - '@oxlint/binding-android-arm-eabi@1.56.0': + '@oxlint/binding-android-arm-eabi@1.57.0': optional: true - '@oxlint/binding-android-arm64@1.56.0': + '@oxlint/binding-android-arm64@1.57.0': optional: true - '@oxlint/binding-darwin-arm64@1.56.0': + '@oxlint/binding-darwin-arm64@1.57.0': optional: true - '@oxlint/binding-darwin-x64@1.56.0': + '@oxlint/binding-darwin-x64@1.57.0': optional: true - '@oxlint/binding-freebsd-x64@1.56.0': + '@oxlint/binding-freebsd-x64@1.57.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.56.0': + '@oxlint/binding-linux-arm-gnueabihf@1.57.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.56.0': + '@oxlint/binding-linux-arm-musleabihf@1.57.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.56.0': + '@oxlint/binding-linux-arm64-gnu@1.57.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.56.0': + '@oxlint/binding-linux-arm64-musl@1.57.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.56.0': + '@oxlint/binding-linux-ppc64-gnu@1.57.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.56.0': + '@oxlint/binding-linux-riscv64-gnu@1.57.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.56.0': + '@oxlint/binding-linux-riscv64-musl@1.57.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.56.0': + '@oxlint/binding-linux-s390x-gnu@1.57.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.56.0': + '@oxlint/binding-linux-x64-gnu@1.57.0': optional: true - '@oxlint/binding-linux-x64-musl@1.56.0': + '@oxlint/binding-linux-x64-musl@1.57.0': optional: true - '@oxlint/binding-openharmony-arm64@1.56.0': + '@oxlint/binding-openharmony-arm64@1.57.0': optional: true - '@oxlint/binding-win32-arm64-msvc@1.56.0': + '@oxlint/binding-win32-arm64-msvc@1.57.0': optional: true - '@oxlint/binding-win32-ia32-msvc@1.56.0': + '@oxlint/binding-win32-ia32-msvc@1.57.0': optional: true - '@oxlint/binding-win32-x64-msvc@1.56.0': + '@oxlint/binding-win32-x64-msvc@1.57.0': optional: true '@parcel/watcher-android-arm64@2.5.6': @@ -9730,6 +10898,10 @@ snapshots: '@pkgr/core@0.2.9': {} + '@playwright/test@1.58.2': + dependencies: + playwright: 1.58.2 + '@polka/url@1.0.0-next.29': {} '@preact/signals-core@1.14.0': {} @@ -9902,7 +11074,7 @@ snapshots: '@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-types/shared': 3.33.1(react@19.2.4) - '@swc/helpers': 0.5.19 + '@swc/helpers': 0.5.20 clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -9913,13 +11085,13 @@ snapshots: '@react-aria/utils': 3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@react-stately/flags': 3.1.2 '@react-types/shared': 3.33.1(react@19.2.4) - '@swc/helpers': 0.5.19 + '@swc/helpers': 0.5.20 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@react-aria/ssr@3.9.10(react@19.2.4)': dependencies: - '@swc/helpers': 0.5.19 + '@swc/helpers': 0.5.20 react: 19.2.4 '@react-aria/utils@3.33.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': @@ -9928,18 +11100,18 @@ snapshots: '@react-stately/flags': 3.1.2 '@react-stately/utils': 3.11.0(react@19.2.4) '@react-types/shared': 3.33.1(react@19.2.4) - '@swc/helpers': 0.5.19 + '@swc/helpers': 0.5.20 clsx: 2.1.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) '@react-stately/flags@3.1.2': dependencies: - '@swc/helpers': 0.5.19 + '@swc/helpers': 0.5.20 '@react-stately/utils@3.11.0(react@19.2.4)': dependencies: - '@swc/helpers': 0.5.19 + '@swc/helpers': 0.5.20 react: 19.2.4 '@react-types/shared@3.33.1(react@19.2.4)': @@ -10032,6 +11204,58 @@ snapshots: '@rgrove/parse-xml@4.2.0': {} + '@rolldown/binding-android-arm64@1.0.0-rc.12': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.12': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.12': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.12': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.12': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.12': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)': + dependencies: + '@napi-rs/wasm-runtime': 1.1.2(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.12': + optional: true + + '@rolldown/pluginutils@1.0.0-rc.12': {} + '@rolldown/pluginutils@1.0.0-rc.5': {} '@rolldown/pluginutils@1.0.0-rc.7': {} @@ -10126,38 +11350,38 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true - '@sentry-internal/browser-utils@10.45.0': + '@sentry-internal/browser-utils@10.46.0': dependencies: - '@sentry/core': 10.45.0 + '@sentry/core': 10.46.0 - '@sentry-internal/feedback@10.45.0': + '@sentry-internal/feedback@10.46.0': dependencies: - '@sentry/core': 10.45.0 + '@sentry/core': 10.46.0 - '@sentry-internal/replay-canvas@10.45.0': + '@sentry-internal/replay-canvas@10.46.0': dependencies: - '@sentry-internal/replay': 10.45.0 - '@sentry/core': 10.45.0 + '@sentry-internal/replay': 10.46.0 + '@sentry/core': 10.46.0 - '@sentry-internal/replay@10.45.0': + '@sentry-internal/replay@10.46.0': dependencies: - '@sentry-internal/browser-utils': 10.45.0 - '@sentry/core': 10.45.0 + '@sentry-internal/browser-utils': 10.46.0 + '@sentry/core': 10.46.0 - '@sentry/browser@10.45.0': + '@sentry/browser@10.46.0': dependencies: - '@sentry-internal/browser-utils': 10.45.0 - '@sentry-internal/feedback': 10.45.0 - '@sentry-internal/replay': 10.45.0 - '@sentry-internal/replay-canvas': 10.45.0 - '@sentry/core': 10.45.0 + '@sentry-internal/browser-utils': 10.46.0 + '@sentry-internal/feedback': 10.46.0 + '@sentry-internal/replay': 10.46.0 + '@sentry-internal/replay-canvas': 10.46.0 + '@sentry/core': 10.46.0 - '@sentry/core@10.45.0': {} + '@sentry/core@10.46.0': {} - '@sentry/react@10.45.0(react@19.2.4)': + '@sentry/react@10.46.0(react@19.2.4)': dependencies: - '@sentry/browser': 10.45.0 - '@sentry/core': 10.45.0 + '@sentry/browser': 10.46.0 + '@sentry/core': 10.46.0 react: 19.2.4 '@shuding/opentype.js@1.4.0-beta.0': @@ -10205,15 +11429,15 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@storybook/addon-docs@10.3.1(@types/react@19.2.14)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))': + '@storybook/addon-docs@10.3.3(@types/react@19.2.14)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4) - '@storybook/csf-plugin': 10.3.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) + '@storybook/csf-plugin': 10.3.3(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) '@storybook/icons': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@storybook/react-dom-shim': 10.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + '@storybook/react-dom-shim': 10.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' @@ -10222,41 +11446,41 @@ snapshots: - vite - webpack - '@storybook/addon-links@10.3.1(react@19.2.4)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': + '@storybook/addon-links@10.3.3(react@19.2.4)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: '@storybook/global': 5.0.0 - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) optionalDependencies: react: 19.2.4 - '@storybook/addon-onboarding@10.3.1(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': + '@storybook/addon-onboarding@10.3.3(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@storybook/addon-themes@10.3.1(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': + '@storybook/addon-themes@10.3.3(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ts-dedent: 2.2.0 - '@storybook/builder-vite@10.3.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))': + '@storybook/builder-vite@10.3.3(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))': dependencies: - '@storybook/csf-plugin': 10.3.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@storybook/csf-plugin': 10.3.3(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ts-dedent: 2.2.0 - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' transitivePeerDependencies: - esbuild - rollup - webpack - '@storybook/csf-plugin@10.3.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))': + '@storybook/csf-plugin@10.3.3(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))': dependencies: - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) unplugin: 2.3.11 optionalDependencies: esbuild: 0.27.2 rollup: 4.59.0 - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' webpack: 5.105.4(esbuild@0.27.2)(uglify-js@3.19.3) '@storybook/global@5.0.0': {} @@ -10266,18 +11490,18 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@storybook/nextjs-vite@10.3.1(@babel/core@7.29.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(next@16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))': + '@storybook/nextjs-vite@10.3.3(@babel/core@7.29.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(next@16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))': dependencies: - '@storybook/builder-vite': 10.3.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) - '@storybook/react': 10.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) - '@storybook/react-vite': 10.3.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) - next: 16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) + '@storybook/builder-vite': 10.3.3(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) + '@storybook/react': 10.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@storybook/react-vite': 10.3.3(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) + next: 16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.4) - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' - vite-plugin-storybook-nextjs: 3.2.3(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(next@16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vite-plugin-storybook-nextjs: 3.2.4(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(next@16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -10288,27 +11512,27 @@ snapshots: - supports-color - webpack - '@storybook/react-dom-shim@10.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': + '@storybook/react-dom-shim@10.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@storybook/react-vite@10.3.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))': + '@storybook/react-vite@10.3.3(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.4(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.4(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3) '@rollup/pluginutils': 5.3.0(rollup@4.59.0) - '@storybook/builder-vite': 10.3.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) - '@storybook/react': 10.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@storybook/builder-vite': 10.3.3(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(rollup@4.59.0)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) + '@storybook/react': 10.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) empathic: 2.0.0 magic-string: 0.30.21 react: 19.2.4 react-docgen: 8.0.3 react-dom: 19.2.4(react@19.2.4) resolve: 1.22.11 - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tsconfig-paths: 4.2.0 - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' transitivePeerDependencies: - esbuild - rollup @@ -10316,15 +11540,15 @@ snapshots: - typescript - webpack - '@storybook/react@10.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': + '@storybook/react@10.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': dependencies: '@storybook/global': 5.0.0 - '@storybook/react-dom-shim': 10.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + '@storybook/react-dom-shim': 10.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) react: 19.2.4 react-docgen: 8.0.3 react-docgen-typescript: 2.4.0(typescript@5.9.3) react-dom: 19.2.4(react@19.2.4) - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -10332,7 +11556,7 @@ snapshots: '@streamdown/math@1.0.2(react@19.2.4)': dependencies: - katex: 0.16.40 + katex: 0.16.44 react: 19.2.4 rehype-katex: 7.0.1 remark-math: 6.0.0 @@ -10342,7 +11566,7 @@ snapshots: '@stylistic/eslint-plugin@5.10.0(eslint@10.1.0(jiti@1.21.7))': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@1.21.7)) - '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/types': 8.57.2 eslint: 10.1.0(jiti@1.21.7) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -10355,22 +11579,22 @@ snapshots: dependencies: tslib: 2.8.1 - '@swc/helpers@0.5.19': + '@swc/helpers@0.5.20': dependencies: tslib: 2.8.1 - '@t3-oss/env-core@0.13.11(typescript@5.9.3)(valibot@1.3.0(typescript@5.9.3))(zod@4.3.6)': + '@t3-oss/env-core@0.13.11(typescript@5.9.3)(valibot@1.3.1(typescript@5.9.3))(zod@4.3.6)': optionalDependencies: typescript: 5.9.3 - valibot: 1.3.0(typescript@5.9.3) + valibot: 1.3.1(typescript@5.9.3) zod: 4.3.6 - '@t3-oss/env-nextjs@0.13.11(typescript@5.9.3)(valibot@1.3.0(typescript@5.9.3))(zod@4.3.6)': + '@t3-oss/env-nextjs@0.13.11(typescript@5.9.3)(valibot@1.3.1(typescript@5.9.3))(zod@4.3.6)': dependencies: - '@t3-oss/env-core': 0.13.11(typescript@5.9.3)(valibot@1.3.0(typescript@5.9.3))(zod@4.3.6) + '@t3-oss/env-core': 0.13.11(typescript@5.9.3)(valibot@1.3.1(typescript@5.9.3))(zod@4.3.6) optionalDependencies: typescript: 5.9.3 - valibot: 1.3.0(typescript@5.9.3) + valibot: 1.3.1(typescript@5.9.3) zod: 4.3.6 '@tailwindcss/typography@0.5.19(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))': @@ -10422,9 +11646,9 @@ snapshots: - csstype - utf-8-validate - '@tanstack/eslint-plugin-query@5.95.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': + '@tanstack/eslint-plugin-query@5.95.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) optionalDependencies: typescript: 5.9.3 @@ -10435,7 +11659,7 @@ snapshots: dependencies: '@tanstack/devtools-event-client': 0.4.3 '@tanstack/pacer-lite': 0.1.1 - '@tanstack/store': 0.9.2 + '@tanstack/store': 0.9.3 '@tanstack/form-devtools@0.2.19(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11)': dependencies: @@ -10455,9 +11679,9 @@ snapshots: '@tanstack/pacer-lite@0.1.1': {} - '@tanstack/query-core@5.95.0': {} + '@tanstack/query-core@5.95.2': {} - '@tanstack/query-devtools@5.95.0': {} + '@tanstack/query-devtools@5.95.2': {} '@tanstack/react-devtools@0.10.0(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(csstype@3.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(solid-js@1.9.11)': dependencies: @@ -10487,25 +11711,25 @@ snapshots: '@tanstack/react-form@1.28.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@tanstack/form-core': 1.28.5 - '@tanstack/react-store': 0.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tanstack/react-store': 0.9.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 transitivePeerDependencies: - react-dom - '@tanstack/react-query-devtools@5.95.0(@tanstack/react-query@5.95.0(react@19.2.4))(react@19.2.4)': + '@tanstack/react-query-devtools@5.95.2(@tanstack/react-query@5.95.2(react@19.2.4))(react@19.2.4)': dependencies: - '@tanstack/query-devtools': 5.95.0 - '@tanstack/react-query': 5.95.0(react@19.2.4) + '@tanstack/query-devtools': 5.95.2 + '@tanstack/react-query': 5.95.2(react@19.2.4) react: 19.2.4 - '@tanstack/react-query@5.95.0(react@19.2.4)': + '@tanstack/react-query@5.95.2(react@19.2.4)': dependencies: - '@tanstack/query-core': 5.95.0 + '@tanstack/query-core': 5.95.2 react: 19.2.4 - '@tanstack/react-store@0.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@tanstack/react-store@0.9.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: - '@tanstack/store': 0.9.2 + '@tanstack/store': 0.9.3 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) use-sync-external-store: 1.6.0(react@19.2.4) @@ -10516,10 +11740,12 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@tanstack/store@0.9.2': {} + '@tanstack/store@0.9.3': {} '@tanstack/virtual-core@3.13.23': {} + '@teppeis/multimaps@3.0.0': {} + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0 @@ -10571,7 +11797,7 @@ snapshots: '@tsslint/compat-eslint@3.0.2(jiti@1.21.7)(typescript@5.9.3)': dependencies: '@tsslint/types': 3.0.2 - '@typescript-eslint/parser': 8.57.1(eslint@9.27.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.2(eslint@9.27.0(jiti@1.21.7))(typescript@5.9.3) eslint: 9.27.0(jiti@1.21.7) transitivePeerDependencies: - jiti @@ -10582,7 +11808,7 @@ snapshots: dependencies: '@tsslint/types': 3.0.2 minimatch: 10.2.4 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) optionalDependencies: '@tsslint/compat-eslint': 3.0.2(jiti@1.21.7)(typescript@5.9.3) transitivePeerDependencies: @@ -10747,7 +11973,7 @@ snapshots: '@types/d3-transition': 3.0.9 '@types/d3-zoom': 3.0.8 - '@types/debug@4.1.12': + '@types/debug@4.1.13': dependencies: '@types/ms': 2.1.0 @@ -10805,6 +12031,8 @@ snapshots: dependencies: undici-types: 7.18.2 + '@types/normalize-package-data@2.4.4': {} + '@types/papaparse@5.5.2': dependencies: '@types/node': 25.5.0 @@ -10855,60 +12083,88 @@ snapshots: '@types/zen-observable@0.8.3': {} - '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/type-utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.1 + '@typescript-eslint/parser': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/type-utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.2 eslint: 10.1.0(jiti@1.21.7) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3))(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.1 - debug: 4.4.3 + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.57.2(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/type-utils': 8.57.2(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.2 + eslint: 10.1.0(jiti@2.6.1) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.2 + debug: 4.4.3(supports-color@8.1.1) eslint: 10.1.0(jiti@1.21.7) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.1(eslint@9.27.0(jiti@1.21.7))(typescript@5.9.3)': + '@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.1 - debug: 4.4.3 + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.2 + debug: 4.4.3(supports-color@8.1.1) + eslint: 10.1.0(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.57.2(eslint@9.27.0(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.2 + debug: 4.4.3(supports-color@8.1.1) eslint: 9.27.0(jiti@1.21.7) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.57.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.57.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) - '@typescript-eslint/types': 8.57.1 - debug: 4.4.3 + '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.9.3) + '@typescript-eslint/types': 8.57.2 + debug: 4.4.3(supports-color@8.1.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/rule-tester@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': + '@typescript-eslint/rule-tester@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/parser': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) ajv: 6.14.0 eslint: 10.1.0(jiti@1.21.7) json-stable-stringify-without-jsonify: 1.0.1 @@ -10918,90 +12174,113 @@ snapshots: - supports-color - typescript - '@typescript-eslint/scope-manager@8.57.1': + '@typescript-eslint/scope-manager@8.57.2': dependencies: - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/visitor-keys': 8.57.1 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/visitor-keys': 8.57.2 - '@typescript-eslint/tsconfig-utils@8.57.1(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.57.2(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - debug: 4.4.3 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + debug: 4.4.3(supports-color@8.1.1) eslint: 10.1.0(jiti@1.21.7) - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.57.1': {} - - '@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.57.2(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.57.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/visitor-keys': 8.57.1 - debug: 4.4.3 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3) + debug: 4.4.3(supports-color@8.1.1) + eslint: 10.1.0(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.57.2': {} + + '@typescript-eslint/typescript-estree@8.57.2(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.57.2(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.9.3) + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/visitor-keys': 8.57.2 + debug: 4.4.3(supports-color@8.1.1) minimatch: 10.2.4 semver: 7.7.4 tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': + '@typescript-eslint/utils@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@1.21.7)) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.57.1': + '@typescript-eslint/utils@8.57.2(eslint@10.1.0(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.57.1 + '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + eslint: 10.1.0(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.57.2': + dependencies: + '@typescript-eslint/types': 8.57.2 eslint-visitor-keys: 5.0.1 - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260322.1': + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260329.1': optional: true - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260322.1': + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260329.1': optional: true - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260322.1': + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260329.1': optional: true - '@typescript/native-preview-linux-arm@7.0.0-dev.20260322.1': + '@typescript/native-preview-linux-arm@7.0.0-dev.20260329.1': optional: true - '@typescript/native-preview-linux-x64@7.0.0-dev.20260322.1': + '@typescript/native-preview-linux-x64@7.0.0-dev.20260329.1': optional: true - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260322.1': + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260329.1': optional: true - '@typescript/native-preview-win32-x64@7.0.0-dev.20260322.1': + '@typescript/native-preview-win32-x64@7.0.0-dev.20260329.1': optional: true - '@typescript/native-preview@7.0.0-dev.20260322.1': + '@typescript/native-preview@7.0.0-dev.20260329.1': optionalDependencies: - '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260322.1 - '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260322.1 - '@typescript/native-preview-linux-arm': 7.0.0-dev.20260322.1 - '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260322.1 - '@typescript/native-preview-linux-x64': 7.0.0-dev.20260322.1 - '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260322.1 - '@typescript/native-preview-win32-x64': 7.0.0-dev.20260322.1 + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260329.1 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260329.1 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20260329.1 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260329.1 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20260329.1 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260329.1 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20260329.1 '@ungap/structured-clone@1.3.0': {} @@ -11009,34 +12288,56 @@ snapshots: dependencies: unpic: 4.2.2 - '@unpic/react@1.0.2(next@16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@unpic/react@1.0.2(next@16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@unpic/core': 1.0.3 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: - next: 16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) + next: 16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) '@upsetjs/venn.js@2.0.0': optionalDependencies: d3-selection: 3.0.0 d3-transition: 3.0.1(d3-selection@3.0.0) - '@valibot/to-json-schema@1.6.0(valibot@1.3.0(typescript@5.9.3))': + '@valibot/to-json-schema@1.6.0(valibot@1.3.1(typescript@5.9.3))': dependencies: - valibot: 1.3.0(typescript@5.9.3) + valibot: 1.3.1(typescript@5.9.3) '@vercel/og@0.8.6': dependencies: '@resvg/resvg-wasm': 2.4.0 satori: 0.16.0 - '@vitejs/plugin-react@6.0.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))': + '@vitejs/devtools-kit@0.1.11(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3)(ws@8.20.0)': + dependencies: + '@vitejs/devtools-rpc': 0.1.11(typescript@5.9.3)(ws@8.20.0) + birpc: 4.0.0 + ohash: 2.0.11 + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + transitivePeerDependencies: + - typescript + - ws + + '@vitejs/devtools-rpc@0.1.11(typescript@5.9.3)(ws@8.20.0)': + dependencies: + birpc: 4.0.0 + ohash: 2.0.11 + p-limit: 7.3.0 + structured-clone-es: 2.0.0 + valibot: 1.3.1(typescript@5.9.3) + optionalDependencies: + ws: 8.20.0 + transitivePeerDependencies: + - typescript + + '@vitejs/plugin-react@6.0.1(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' - '@vitejs/plugin-rsc@0.5.21(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)))(react@19.2.4)': + '@vitejs/plugin-rsc@0.5.21(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)))(react@19.2.4)': dependencies: '@rolldown/pluginutils': 1.0.0-rc.5 es-module-lexer: 2.0.0 @@ -11045,18 +12346,18 @@ snapshots: periscopic: 4.0.2 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - srvx: 0.11.12 + srvx: 0.11.13 strip-literal: 3.1.0 turbo-stream: 3.2.0 - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' - vitefu: 1.1.2(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vitefu: 1.1.2(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) optionalDependencies: react-server-dom-webpack: 19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) - '@vitest/coverage-v8@4.1.0(@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))': + '@vitest/coverage-v8@4.1.2(@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.0 + '@vitest/utils': 4.1.2 ast-v8-to-istanbul: 1.0.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -11065,16 +12366,31 @@ snapshots: obug: 2.1.1 std-env: 4.0.0 tinyrainbow: 3.1.0 - vitest: '@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vitest: '@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' - '@vitest/eslint-plugin@1.6.12(@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': + '@vitest/coverage-v8@4.1.2(@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3))': dependencies: - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.1.2 + ast-v8-to-istanbul: 1.0.0 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + magicast: 0.5.2 + obug: 2.1.1 + std-env: 4.0.0 + tinyrainbow: 3.1.0 + vitest: '@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3)' + + '@vitest/eslint-plugin@1.6.13(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) optionalDependencies: + '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) typescript: 5.9.3 - vitest: '@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vitest: '@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' transitivePeerDependencies: - supports-color @@ -11090,7 +12406,7 @@ snapshots: dependencies: tinyrainbow: 2.0.0 - '@vitest/pretty-format@4.1.0': + '@vitest/pretty-format@4.1.2': dependencies: tinyrainbow: 3.1.0 @@ -11104,16 +12420,16 @@ snapshots: loupe: 3.2.1 tinyrainbow: 2.0.0 - '@vitest/utils@4.1.0': + '@vitest/utils@4.1.2': dependencies: - '@vitest/pretty-format': 4.1.0 + '@vitest/pretty-format': 4.1.2 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 - '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)': + '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)': dependencies: - '@oxc-project/runtime': 0.120.0 - '@oxc-project/types': 0.120.0 + '@oxc-project/runtime': 0.121.0 + '@oxc-project/types': 0.122.0 lightningcss: 1.32.0 postcss: 8.5.8 optionalDependencies: @@ -11127,23 +12443,46 @@ snapshots: typescript: 5.9.3 yaml: 2.8.3 - '@voidzero-dev/vite-plus-darwin-arm64@0.1.13': + '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)': + dependencies: + '@oxc-project/runtime': 0.121.0 + '@oxc-project/types': 0.122.0 + lightningcss: 1.32.0 + postcss: 8.5.8 + optionalDependencies: + '@types/node': 25.5.0 + esbuild: 0.27.2 + fsevents: 2.3.3 + jiti: 2.6.1 + sass: 1.98.0 + terser: 5.46.1 + tsx: 4.21.0 + typescript: 5.9.3 + yaml: 2.8.3 + + '@voidzero-dev/vite-plus-darwin-arm64@0.1.14': optional: true - '@voidzero-dev/vite-plus-darwin-x64@0.1.13': + '@voidzero-dev/vite-plus-darwin-x64@0.1.14': optional: true - '@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.13': + '@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.14': optional: true - '@voidzero-dev/vite-plus-linux-x64-gnu@0.1.13': + '@voidzero-dev/vite-plus-linux-arm64-musl@0.1.14': optional: true - '@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)': + '@voidzero-dev/vite-plus-linux-x64-gnu@0.1.14': + optional: true + + '@voidzero-dev/vite-plus-linux-x64-musl@0.1.14': + optional: true + + '@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@voidzero-dev/vite-plus-core': 0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) + '@voidzero-dev/vite-plus-core': 0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) es-module-lexer: 1.7.0 obug: 2.1.1 pixelmatch: 7.1.0 @@ -11153,12 +12492,11 @@ snapshots: tinybench: 2.9.0 tinyexec: 1.0.4 tinyglobby: 0.2.15 - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' - ws: 8.19.0 + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + ws: 8.20.0 optionalDependencies: '@types/node': 25.5.0 happy-dom: 20.8.9 - jsdom: 29.0.1(canvas@3.2.2) transitivePeerDependencies: - '@arethetypeswrong/core' - '@tsdown/css' @@ -11180,10 +12518,50 @@ snapshots: - utf-8-validate - yaml - '@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.13': + '@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3)': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@voidzero-dev/vite-plus-core': 0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) + es-module-lexer: 1.7.0 + obug: 2.1.1 + pixelmatch: 7.1.0 + pngjs: 7.0.0 + sirv: 3.0.2 + std-env: 4.0.0 + tinybench: 2.9.0 + tinyexec: 1.0.4 + tinyglobby: 0.2.15 + vite: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) + ws: 8.20.0 + optionalDependencies: + '@types/node': 25.5.0 + happy-dom: 20.8.9 + transitivePeerDependencies: + - '@arethetypeswrong/core' + - '@tsdown/css' + - '@tsdown/exe' + - '@vitejs/devtools' + - bufferutil + - esbuild + - jiti + - less + - publint + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - typescript + - unplugin-unused + - utf-8-validate + - yaml + + '@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.14': optional: true - '@voidzero-dev/vite-plus-win32-x64-msvc@0.1.13': + '@voidzero-dev/vite-plus-win32-x64-msvc@0.1.14': optional: true '@volar/language-core@2.4.28': @@ -11200,37 +12578,37 @@ snapshots: path-browserify: 1.0.1 vscode-uri: 3.1.0 - '@vue/compiler-core@3.5.30': + '@vue/compiler-core@3.5.31': dependencies: '@babel/parser': 7.29.2 - '@vue/shared': 3.5.30 + '@vue/shared': 3.5.31 entities: 7.0.1 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.30': + '@vue/compiler-dom@3.5.31': dependencies: - '@vue/compiler-core': 3.5.30 - '@vue/shared': 3.5.30 + '@vue/compiler-core': 3.5.31 + '@vue/shared': 3.5.31 - '@vue/compiler-sfc@3.5.30': + '@vue/compiler-sfc@3.5.31': dependencies: '@babel/parser': 7.29.2 - '@vue/compiler-core': 3.5.30 - '@vue/compiler-dom': 3.5.30 - '@vue/compiler-ssr': 3.5.30 - '@vue/shared': 3.5.30 + '@vue/compiler-core': 3.5.31 + '@vue/compiler-dom': 3.5.31 + '@vue/compiler-ssr': 3.5.31 + '@vue/shared': 3.5.31 estree-walker: 2.0.2 magic-string: 0.30.21 postcss: 8.5.8 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.30': + '@vue/compiler-ssr@3.5.31': dependencies: - '@vue/compiler-dom': 3.5.30 - '@vue/shared': 3.5.30 + '@vue/compiler-dom': 3.5.31 + '@vue/shared': 3.5.31 - '@vue/shared@3.5.30': {} + '@vue/shared@3.5.31': {} '@webassemblyjs/ast@1.14.1': dependencies: @@ -11330,12 +12708,12 @@ snapshots: acorn@8.16.0: {} - agentation@2.3.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + agentation@3.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4): optionalDependencies: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - ahooks@3.9.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + ahooks@3.9.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@babel/runtime': 7.29.2 '@types/js-cookie': 3.0.6 @@ -11377,6 +12755,8 @@ snapshots: dependencies: environment: 1.1.0 + ansi-regex@4.1.1: {} + ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} @@ -11414,6 +12794,12 @@ snapshots: aria-query@5.3.2: {} + assertion-error-formatter@3.0.0: + dependencies: + diff: 4.0.4 + pad-right: 0.2.2 + repeat-string: 1.6.1 + assertion-error@2.0.1: {} ast-types@0.16.1: @@ -11430,15 +12816,25 @@ snapshots: async@3.2.6: {} + asynckit@0.4.0: {} + autoprefixer@10.4.27(postcss@8.5.8): dependencies: browserslist: 4.28.1 - caniuse-lite: 1.0.30001780 + caniuse-lite: 1.0.30001781 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.8 postcss-value-parser: 4.2.0 + axios@1.14.0: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + bail@2.0.2: {} balanced-match@1.0.2: {} @@ -11452,18 +12848,13 @@ snapshots: base64-js@1.5.1: optional: true - baseline-browser-mapping@2.10.8: {} - - bidi-js@1.0.3: - dependencies: - require-from-string: 2.0.2 - optional: true + baseline-browser-mapping@2.10.12: {} binary-extensions@2.3.0: {} birecord@0.1.1: {} - birpc@2.9.0: {} + birpc@4.0.0: {} bl@4.1.0: dependencies: @@ -11478,7 +12869,7 @@ snapshots: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.4: + brace-expansion@5.0.5: dependencies: balanced-match: 4.0.4 @@ -11488,9 +12879,9 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.10.8 - caniuse-lite: 1.0.30001780 - electron-to-chromium: 1.5.313 + baseline-browser-mapping: 2.10.12 + caniuse-lite: 1.0.30001781 + electron-to-chromium: 1.5.328 node-releases: 2.0.36 update-browserslist-db: 1.2.3(browserslist@4.28.1) @@ -11512,17 +12903,29 @@ snapshots: dependencies: run-applescript: 7.1.0 + bundle-require@5.1.0(esbuild@0.27.2): + dependencies: + esbuild: 0.27.2 + load-tsconfig: 0.2.5 + bytes@3.1.2: {} + cac@6.7.14: {} + cac@7.0.0: {} + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + callsites@3.1.0: {} camelcase-css@2.0.1: {} camelize@1.0.1: {} - caniuse-lite@1.0.30001780: {} + caniuse-lite@1.0.30001781: {} canvas@3.2.2: dependencies: @@ -11530,6 +12933,12 @@ snapshots: prebuild-install: 7.1.3 optional: true + capital-case@1.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + upper-case-first: 2.0.2 + ccount@2.0.1: {} chai@5.3.3: @@ -11632,6 +13041,8 @@ snapshots: ci-info@4.4.0: {} + class-transformer@0.5.1: {} + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -11648,6 +13059,12 @@ snapshots: dependencies: restore-cursor: 5.1.0 + cli-table3@0.6.5: + dependencies: + string-width: 8.2.0 + optionalDependencies: + '@colors/colors': 1.5.0 + cli-truncate@5.2.0: dependencies: slice-ansi: 8.0.0 @@ -11691,10 +13108,18 @@ snapshots: colorette@2.0.20: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + comma-separated-tokens@1.0.8: {} comma-separated-tokens@2.0.3: {} + commander@14.0.0: {} + + commander@14.0.2: {} + commander@14.0.3: {} commander@2.20.3: {} @@ -11707,12 +13132,16 @@ snapshots: comment-parser@1.4.5: {} + comment-parser@1.4.6: {} + compare-versions@6.1.1: {} confbox@0.1.8: {} confbox@0.2.4: {} + consola@3.4.2: {} + convert-source-map@2.0.0: {} copy-to-clipboard@3.3.3: @@ -11773,12 +13202,6 @@ snapshots: mdn-data: 2.0.30 source-map-js: 1.2.1 - css-tree@3.2.1: - dependencies: - mdn-data: 2.27.1 - source-map-js: 1.2.1 - optional: true - css-what@6.2.2: {} css.escape@1.5.1: {} @@ -11835,7 +13258,7 @@ snapshots: d3-delaunay@6.0.4: dependencies: - delaunator: 5.0.1 + delaunator: 5.1.0 d3-dispatch@3.0.1: {} @@ -11977,19 +13400,13 @@ snapshots: d3: 7.9.0 lodash-es: 4.17.23 - data-urls@7.0.0: - dependencies: - whatwg-mimetype: 5.0.0 - whatwg-url: 16.0.1 - transitivePeerDependencies: - - '@noble/hashes' - optional: true - dayjs@1.11.20: {} - debug@4.4.3: + debug@4.4.3(supports-color@8.1.1): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 decimal.js@10.6.0: {} @@ -12020,9 +13437,11 @@ snapshots: defu@6.1.4: {} - delaunator@5.0.1: + delaunator@5.1.0: dependencies: - robust-predicates: 3.0.2 + robust-predicates: 3.0.3 + + delayed-stream@1.0.0: {} dequal@2.0.3: {} @@ -12040,6 +13459,8 @@ snapshots: diff-sequences@29.6.3: {} + diff@4.0.4: {} + dlv@1.1.3: {} doctrine@3.0.0: @@ -12078,6 +13499,12 @@ snapshots: dotenv@16.6.1: {} + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + echarts-for-react@3.0.6(echarts@6.0.0)(react@19.2.4): dependencies: echarts: 6.0.0 @@ -12090,7 +13517,7 @@ snapshots: tslib: 2.3.0 zrender: 6.0.0 - electron-to-chromium@1.5.313: {} + electron-to-chromium@1.5.328: {} elkjs@0.11.1: {} @@ -12128,7 +13555,7 @@ snapshots: enhanced-resolve@5.20.1: dependencies: graceful-fs: 4.2.11 - tapable: 2.3.0 + tapable: 2.3.2 entities@4.5.0: {} @@ -12140,10 +13567,29 @@ snapshots: error-stack-parser-es@1.0.5: {} + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + es-module-lexer@1.7.0: {} es-module-lexer@2.0.0: {} + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: '@nolyfill/hasown@1.0.44' + es-toolkit@1.45.1: {} esast-util-from-estree@2.0.0: @@ -12204,7 +13650,7 @@ snapshots: eslint: 10.1.0(jiti@1.21.7) semver: 7.7.4 - eslint-config-flat-gitignore@2.2.1(eslint@10.1.0(jiti@1.21.7)): + eslint-config-flat-gitignore@2.3.0(eslint@10.1.0(jiti@1.21.7)): dependencies: '@eslint/compat': 2.0.3(eslint@10.1.0(jiti@1.21.7)) eslint: 10.1.0(jiti@1.21.7) @@ -12238,30 +13684,30 @@ snapshots: dependencies: eslint: 10.1.0(jiti@1.21.7) - eslint-plugin-better-tailwindcss@4.3.2(eslint@10.1.0(jiti@1.21.7))(oxlint@1.56.0(oxlint-tsgolint@0.17.1))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))(typescript@5.9.3): + eslint-plugin-better-tailwindcss@4.3.2(eslint@10.1.0(jiti@1.21.7))(oxlint@1.57.0(oxlint-tsgolint@0.17.3))(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.3))(typescript@5.9.3): dependencies: '@eslint/css-tree': 3.6.9 - '@valibot/to-json-schema': 1.6.0(valibot@1.3.0(typescript@5.9.3)) + '@valibot/to-json-schema': 1.6.0(valibot@1.3.1(typescript@5.9.3)) enhanced-resolve: 5.20.1 jiti: 2.6.1 synckit: 0.11.12 tailwind-csstree: 0.1.5 tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.3) tsconfig-paths-webpack-plugin: 4.2.0 - valibot: 1.3.0(typescript@5.9.3) + valibot: 1.3.1(typescript@5.9.3) optionalDependencies: eslint: 10.1.0(jiti@1.21.7) - oxlint: 1.56.0(oxlint-tsgolint@0.17.1) + oxlint: 1.57.0(oxlint-tsgolint@0.17.3) transitivePeerDependencies: - '@eslint/css' - typescript - eslint-plugin-command@3.5.2(@typescript-eslint/rule-tester@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3))(@typescript-eslint/utils@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7)): + eslint-plugin-command@3.5.2(@typescript-eslint/rule-tester@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.2(typescript@5.9.3))(@typescript-eslint/utils@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7)): dependencies: '@es-joy/jsdoccomment': 0.84.0 - '@typescript-eslint/rule-tester': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/rule-tester': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) eslint-plugin-depend@1.5.0(eslint@10.1.0(jiti@1.21.7)): @@ -12286,13 +13732,13 @@ snapshots: dependencies: eslint: 10.1.0(jiti@1.21.7) - eslint-plugin-jsdoc@62.8.0(eslint@10.1.0(jiti@1.21.7)): + eslint-plugin-jsdoc@62.8.1(eslint@10.1.0(jiti@1.21.7)): dependencies: '@es-joy/jsdoccomment': 0.84.0 '@es-joy/resolve.exports': 1.2.0 are-docs-informative: 0.0.2 comment-parser: 1.4.5 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint: 10.1.0(jiti@1.21.7) espree: 11.2.0 @@ -12358,7 +13804,7 @@ snapshots: eslint-plugin-no-barrel-files@1.2.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3): dependencies: - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) transitivePeerDependencies: - eslint - supports-color @@ -12368,7 +13814,7 @@ snapshots: eslint-plugin-perfectionist@5.7.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3): dependencies: - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) natural-orderby: 5.0.0 transitivePeerDependencies: @@ -12392,9 +13838,9 @@ snapshots: '@eslint-react/core': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/shared': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/var': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) compare-versions: 6.1.1 eslint: 10.1.0(jiti@1.21.7) ts-pattern: 5.9.0 @@ -12419,10 +13865,10 @@ snapshots: '@eslint-react/core': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/shared': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/var': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/type-utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/type-utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) compare-versions: 6.1.1 eslint: 10.1.0(jiti@1.21.7) string-ts: 2.3.1 @@ -12440,10 +13886,10 @@ snapshots: '@eslint-react/ast': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/shared': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/var': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/type-utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/type-utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) ts-pattern: 5.9.0 typescript: 5.9.3 @@ -12456,9 +13902,9 @@ snapshots: '@eslint-react/core': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/shared': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/var': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) birecord: 0.1.1 eslint: 10.1.0(jiti@1.21.7) ts-pattern: 5.9.0 @@ -12472,14 +13918,14 @@ snapshots: '@eslint-react/core': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/shared': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) '@eslint-react/var': 3.0.0(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/type-utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/type-utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) compare-versions: 6.1.1 eslint: 10.1.0(jiti@1.21.7) string-ts: 2.3.1 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) ts-pattern: 5.9.0 typescript: 5.9.3 transitivePeerDependencies: @@ -12489,7 +13935,7 @@ snapshots: dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@1.21.7)) '@eslint-community/regexpp': 4.12.2 - comment-parser: 1.4.5 + comment-parser: 1.4.6 eslint: 10.1.0(jiti@1.21.7) jsdoc-type-pratt-parser: 7.1.1 refa: 0.12.1 @@ -12509,14 +13955,14 @@ snapshots: minimatch: 10.2.4 scslre: 0.3.0 semver: 7.7.4 - ts-api-utils: 2.4.0(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 - eslint-plugin-storybook@10.3.1(eslint@10.1.0(jiti@1.21.7))(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3): + eslint-plugin-storybook@10.3.3(eslint@10.1.0(jiti@1.21.7))(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3): dependencies: - '@typescript-eslint/utils': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint: 10.1.0(jiti@1.21.7) - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) transitivePeerDependencies: - supports-color - typescript @@ -12526,7 +13972,7 @@ snapshots: '@eslint/core': 1.1.1 '@eslint/plugin-kit': 0.6.1 '@ota-meshi/ast-token-store': 0.3.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 10.1.0(jiti@1.21.7) toml-eslint-parser: 1.0.3 transitivePeerDependencies: @@ -12552,13 +13998,13 @@ snapshots: semver: 7.7.4 strip-indent: 4.1.1 - eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7)): + eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7)): dependencies: eslint: 10.1.0(jiti@1.21.7) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) - eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.1.0(jiti@1.21.7)))(@typescript-eslint/parser@8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(vue-eslint-parser@10.4.0(eslint@10.1.0(jiti@1.21.7))): + eslint-plugin-vue@10.8.0(@stylistic/eslint-plugin@5.10.0(eslint@10.1.0(jiti@1.21.7)))(@typescript-eslint/parser@8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3))(eslint@10.1.0(jiti@1.21.7))(vue-eslint-parser@10.4.0(eslint@10.1.0(jiti@1.21.7))): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@1.21.7)) eslint: 10.1.0(jiti@1.21.7) @@ -12570,14 +14016,14 @@ snapshots: xml-name-validator: 4.0.0 optionalDependencies: '@stylistic/eslint-plugin': 5.10.0(eslint@10.1.0(jiti@1.21.7)) - '@typescript-eslint/parser': 8.57.1(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.2(eslint@10.1.0(jiti@1.21.7))(typescript@5.9.3) eslint-plugin-yml@3.3.1(eslint@10.1.0(jiti@1.21.7)): dependencies: '@eslint/core': 1.1.1 '@eslint/plugin-kit': 0.6.1 '@ota-meshi/ast-token-store': 0.3.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) diff-sequences: 29.6.3 escape-string-regexp: 5.0.0 eslint: 10.1.0(jiti@1.21.7) @@ -12586,9 +14032,9 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.30)(eslint@10.1.0(jiti@1.21.7)): + eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.31)(eslint@10.1.0(jiti@1.21.7)): dependencies: - '@vue/compiler-sfc': 3.5.30 + '@vue/compiler-sfc': 3.5.31 eslint: 10.1.0(jiti@1.21.7) eslint-scope@5.1.1: @@ -12628,7 +14074,7 @@ snapshots: '@types/estree': 1.0.8 ajv: 6.14.0 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint-scope: 9.1.2 eslint-visitor-keys: 5.0.1 @@ -12651,6 +14097,43 @@ snapshots: transitivePeerDependencies: - supports-color + eslint@10.1.0(jiti@2.6.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.1.0(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.3 + '@eslint/config-helpers': 0.5.3 + '@eslint/core': 1.1.1 + '@eslint/plugin-kit': 0.6.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.14.0 + cross-spawn: 7.0.6 + debug: 4.4.3(supports-color@8.1.1) + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.4 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + eslint@9.27.0(jiti@1.21.7): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.27.0(jiti@1.21.7)) @@ -12669,7 +14152,7 @@ snapshots: ajv: 6.14.0 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -12771,7 +14254,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) get-stream: 5.2.0 yauzl: 3.2.1 optionalDependencies: @@ -12827,6 +14310,10 @@ snapshots: fflate@0.7.4: {} + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -12844,6 +14331,12 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + fix-dts-default-cjs-exports@1.0.1: + dependencies: + magic-string: 0.30.21 + mlly: 1.8.2 + rollup: 4.59.0 + flat-cache@4.0.1: dependencies: flatted: 3.4.2 @@ -12851,6 +14344,16 @@ snapshots: flatted@3.4.2: {} + follow-redirects@1.15.11: {} + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: '@nolyfill/hasown@1.0.44' + mime-types: 2.1.35 + format@0.2.2: {} formatly@0.3.0: @@ -12871,9 +14374,14 @@ snapshots: fs-constants@1.0.0: optional: true + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + functional-red-black-tree@1.0.1: {} fzf@0.5.2: {} @@ -12882,8 +14390,26 @@ snapshots: get-east-asian-width@1.5.0: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: '@nolyfill/hasown@1.0.44' + math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + get-stream@5.2.0: dependencies: pump: 3.0.4 @@ -12913,6 +14439,10 @@ snapshots: minipass: 7.1.3 path-scurry: 2.0.2 + global-dirs@3.0.1: + dependencies: + ini: 2.0.0 + globals@14.0.0: {} globals@15.15.0: {} @@ -12927,6 +14457,8 @@ snapshots: dependencies: csstype: 3.2.3 + gopd@1.2.0: {} + graceful-fs@4.2.11: {} hachure-fill@0.5.2: {} @@ -12943,8 +14475,18 @@ snapshots: - bufferutil - utf-8-validate + has-ansi@4.0.1: + dependencies: + ansi-regex: 4.1.1 + has-flag@4.0.0: {} + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + hast-util-from-dom@5.0.1: dependencies: '@types/hast': 3.0.4 @@ -13100,14 +14642,11 @@ snapshots: highlightjs-vue@1.0.0: {} - hono@4.12.8: {} + hono@4.12.9: {} - html-encoding-sniffer@6.0.0: + hosted-git-info@9.0.2: dependencies: - '@exodus/bytes': 1.15.0 - transitivePeerDependencies: - - '@noble/hashes' - optional: true + lru-cache: 11.2.7 html-entities@2.6.0: {} @@ -13136,7 +14675,7 @@ snapshots: dependencies: '@babel/runtime': 7.29.2 - i18next@25.10.4(typescript@5.9.3): + i18next@25.10.10(typescript@5.9.3): dependencies: '@babel/runtime': 7.29.2 optionalDependencies: @@ -13182,12 +14721,16 @@ snapshots: indent-string@5.0.0: {} + index-to-position@1.2.0: {} + inherits@2.0.4: optional: true ini@1.3.8: optional: true + ini@2.0.0: {} + inline-style-parser@0.2.7: {} internmap@1.0.1: {} @@ -13238,21 +14781,29 @@ snapshots: is-hexadecimal@2.0.1: {} + is-in-ssh@1.0.0: {} + is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 + is-installed-globally@0.4.0: + dependencies: + global-dirs: 3.0.1 + is-path-inside: 3.0.3 + is-number@7.0.0: {} - is-plain-obj@4.1.0: {} + is-path-inside@3.0.3: {} - is-potential-custom-element-name@1.0.1: - optional: true + is-plain-obj@4.1.0: {} is-reference@3.0.3: dependencies: '@types/estree': 1.0.8 + is-stream@2.0.1: {} + is-wsl@3.1.1: dependencies: is-inside-container: 1.0.0 @@ -13284,13 +14835,15 @@ snapshots: jiti@2.6.1: {} - jotai@2.18.1(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.14)(react@19.2.4): + jotai@2.19.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.14)(react@19.2.4): optionalDependencies: '@babel/core': 7.29.0 '@babel/template': 7.28.6 '@types/react': 19.2.14 react: 19.2.4 + joycon@3.1.1: {} + js-audio-recorder@1.0.7: {} js-base64@3.7.8: {} @@ -13309,35 +14862,6 @@ snapshots: jsdoc-type-pratt-parser@7.1.1: {} - jsdom@29.0.1(canvas@3.2.2): - dependencies: - '@asamuzakjp/css-color': 5.1.1 - '@asamuzakjp/dom-selector': 7.0.4 - '@bramus/specificity': 2.4.2 - '@csstools/css-syntax-patches-for-csstree': 1.1.2(css-tree@3.2.1) - '@exodus/bytes': 1.15.0 - css-tree: 3.2.1 - data-urls: 7.0.0 - decimal.js: 10.6.0 - html-encoding-sniffer: 6.0.0 - is-potential-custom-element-name: 1.0.1 - lru-cache: 11.2.7 - parse5: 8.0.0 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 6.0.1 - undici: 7.24.6 - w3c-xmlserializer: 5.0.0 - webidl-conversions: 8.0.1 - whatwg-mimetype: 5.0.0 - whatwg-url: 16.0.1 - xml-name-validator: 5.0.0 - optionalDependencies: - canvas: 3.2.2 - transitivePeerDependencies: - - '@noble/hashes' - optional: true - jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -13368,7 +14892,7 @@ snapshots: jsx-ast-utils-x@0.1.0: {} - katex@0.16.40: + katex@0.16.44: dependencies: commander: 8.3.0 @@ -13378,7 +14902,7 @@ snapshots: khroma@2.1.0: {} - knip@6.0.2: + knip@6.1.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1): dependencies: '@nodelib/fs.walk': 1.2.8 fast-glob: 3.3.3 @@ -13386,8 +14910,8 @@ snapshots: get-tsconfig: 4.13.7 jiti: 2.6.1 minimist: 1.2.8 - oxc-parser: 0.120.0 - oxc-resolver: 11.19.1 + oxc-parser: 0.121.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + oxc-resolver: 11.19.1(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) picocolors: 1.1.1 picomatch: 4.0.4 smol-toml: 1.6.1 @@ -13395,6 +14919,13 @@ snapshots: unbash: 2.2.0 yaml: 2.8.3 zod: 4.3.6 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + + knuth-shuffle-seeded@1.0.6: + dependencies: + seed-random: 2.2.0 kolorist@1.8.0: {} @@ -13513,11 +15044,13 @@ snapshots: rfdc: 1.4.1 wrap-ansi: 9.0.2 + load-tsconfig@0.2.5: {} + loader-runner@4.3.1: {} local-pkg@1.1.2: dependencies: - mlly: 1.8.1 + mlly: 1.8.2 pkg-types: 2.3.0 quansync: 0.2.11 @@ -13529,6 +15062,10 @@ snapshots: lodash.merge@4.6.2: {} + lodash.mergewith@4.6.2: {} + + lodash.sortby@4.7.0: {} + lodash@4.17.23: {} log-update@6.1.0: @@ -13547,6 +15084,10 @@ snapshots: loupe@3.2.1: {} + lower-case@2.0.2: + dependencies: + tslib: 2.8.1 + lowlight@1.20.0: dependencies: fault: 1.0.4 @@ -13584,7 +15125,9 @@ snapshots: marked@16.4.2: {} - marked@17.0.4: {} + marked@17.0.5: {} + + math-intrinsics@1.1.0: {} mdast-util-directive@3.1.0: dependencies: @@ -13797,9 +15340,6 @@ snapshots: mdn-data@2.23.0: {} - mdn-data@2.27.1: - optional: true - memoize-one@5.2.1: {} merge-stream@2.0.0: {} @@ -13821,7 +15361,7 @@ snapshots: dagre-d3-es: 7.0.14 dayjs: 1.11.20 dompurify: 3.3.2 - katex: 0.16.40 + katex: 0.16.44 khroma: 2.1.0 lodash-es: 4.17.23 marked: 16.4.2 @@ -13928,7 +15468,7 @@ snapshots: dependencies: '@types/katex': 0.16.8 devlop: 1.1.0 - katex: 0.16.40 + katex: 0.16.44 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 @@ -14101,8 +15641,8 @@ snapshots: micromark@4.0.2: dependencies: - '@types/debug': 4.1.12 - debug: 4.4.3 + '@types/debug': 4.1.13 + debug: 4.4.3(supports-color@8.1.1) decode-named-character-reference: 1.3.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -14132,6 +15672,8 @@ snapshots: dependencies: mime-db: 1.52.0 + mime@3.0.0: {} + mime@4.1.0: {} mimic-function@5.0.1: {} @@ -14143,7 +15685,7 @@ snapshots: minimatch@10.2.4: dependencies: - brace-expansion: 5.0.4 + brace-expansion: 5.0.5 minimatch@3.1.5: dependencies: @@ -14162,7 +15704,9 @@ snapshots: mkdirp-classic@0.5.3: optional: true - mlly@1.8.1: + mkdirp@3.0.1: {} + + mlly@1.8.2: dependencies: acorn: 8.16.0 pathe: 2.0.3 @@ -14210,12 +15754,12 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - next@16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0): + next@16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0): dependencies: '@next/env': 16.2.1 '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.10.8 - caniuse-lite: 1.0.30001780 + baseline-browser-mapping: 2.10.12 + caniuse-lite: 1.0.30001781 postcss: 8.4.31 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -14229,12 +15773,18 @@ snapshots: '@next/swc-linux-x64-musl': 16.2.1 '@next/swc-win32-arm64-msvc': 16.2.1 '@next/swc-win32-x64-msvc': 16.2.1 + '@playwright/test': 1.58.2 sass: 1.98.0 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.8.1 + node-abi@3.89.0: dependencies: semver: 7.7.4 @@ -14247,6 +15797,12 @@ snapshots: node-releases@2.0.36: {} + normalize-package-data@8.0.0: + dependencies: + hosted-git-info: 9.0.2 + semver: 7.7.4 + validate-npm-package-license: 3.0.4 + normalize-path@3.0.0: {} normalize-wheel@1.0.1: {} @@ -14255,12 +15811,12 @@ snapshots: dependencies: boolbase: 1.0.0 - nuqs@2.8.9(next@16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react@19.2.4): + nuqs@2.8.9(next@16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react@19.2.4): dependencies: '@standard-schema/spec': 1.0.0 react: 19.2.4 optionalDependencies: - next: 16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) + next: 16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) object-assign@4.1.1: {} @@ -14293,6 +15849,15 @@ snapshots: is-inside-container: 1.0.0 wsl-utils: 0.1.0 + open@11.0.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.1.0 + wsl-utils: 0.3.1 + openapi-types@12.1.3: {} optionator@0.9.4: @@ -14304,32 +15869,35 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 - oxc-parser@0.120.0: + oxc-parser@0.121.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1): dependencies: - '@oxc-project/types': 0.120.0 + '@oxc-project/types': 0.121.0 optionalDependencies: - '@oxc-parser/binding-android-arm-eabi': 0.120.0 - '@oxc-parser/binding-android-arm64': 0.120.0 - '@oxc-parser/binding-darwin-arm64': 0.120.0 - '@oxc-parser/binding-darwin-x64': 0.120.0 - '@oxc-parser/binding-freebsd-x64': 0.120.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.120.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.120.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.120.0 - '@oxc-parser/binding-linux-arm64-musl': 0.120.0 - '@oxc-parser/binding-linux-ppc64-gnu': 0.120.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.120.0 - '@oxc-parser/binding-linux-riscv64-musl': 0.120.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.120.0 - '@oxc-parser/binding-linux-x64-gnu': 0.120.0 - '@oxc-parser/binding-linux-x64-musl': 0.120.0 - '@oxc-parser/binding-openharmony-arm64': 0.120.0 - '@oxc-parser/binding-wasm32-wasi': 0.120.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.120.0 - '@oxc-parser/binding-win32-ia32-msvc': 0.120.0 - '@oxc-parser/binding-win32-x64-msvc': 0.120.0 + '@oxc-parser/binding-android-arm-eabi': 0.121.0 + '@oxc-parser/binding-android-arm64': 0.121.0 + '@oxc-parser/binding-darwin-arm64': 0.121.0 + '@oxc-parser/binding-darwin-x64': 0.121.0 + '@oxc-parser/binding-freebsd-x64': 0.121.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.121.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.121.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.121.0 + '@oxc-parser/binding-linux-arm64-musl': 0.121.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.121.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.121.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.121.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.121.0 + '@oxc-parser/binding-linux-x64-gnu': 0.121.0 + '@oxc-parser/binding-linux-x64-musl': 0.121.0 + '@oxc-parser/binding-openharmony-arm64': 0.121.0 + '@oxc-parser/binding-wasm32-wasi': 0.121.0(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + '@oxc-parser/binding-win32-arm64-msvc': 0.121.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.121.0 + '@oxc-parser/binding-win32-x64-msvc': 0.121.0 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - oxc-resolver@11.19.1: + oxc-resolver@11.19.1(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1): optionalDependencies: '@oxc-resolver/binding-android-arm-eabi': 11.19.1 '@oxc-resolver/binding-android-arm64': 11.19.1 @@ -14347,77 +15915,88 @@ snapshots: '@oxc-resolver/binding-linux-x64-gnu': 11.19.1 '@oxc-resolver/binding-linux-x64-musl': 11.19.1 '@oxc-resolver/binding-openharmony-arm64': 11.19.1 - '@oxc-resolver/binding-wasm32-wasi': 11.19.1 + '@oxc-resolver/binding-wasm32-wasi': 11.19.1(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) '@oxc-resolver/binding-win32-arm64-msvc': 11.19.1 '@oxc-resolver/binding-win32-ia32-msvc': 11.19.1 '@oxc-resolver/binding-win32-x64-msvc': 11.19.1 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - oxfmt@0.41.0: + oxfmt@0.42.0: dependencies: tinypool: 2.1.0 optionalDependencies: - '@oxfmt/binding-android-arm-eabi': 0.41.0 - '@oxfmt/binding-android-arm64': 0.41.0 - '@oxfmt/binding-darwin-arm64': 0.41.0 - '@oxfmt/binding-darwin-x64': 0.41.0 - '@oxfmt/binding-freebsd-x64': 0.41.0 - '@oxfmt/binding-linux-arm-gnueabihf': 0.41.0 - '@oxfmt/binding-linux-arm-musleabihf': 0.41.0 - '@oxfmt/binding-linux-arm64-gnu': 0.41.0 - '@oxfmt/binding-linux-arm64-musl': 0.41.0 - '@oxfmt/binding-linux-ppc64-gnu': 0.41.0 - '@oxfmt/binding-linux-riscv64-gnu': 0.41.0 - '@oxfmt/binding-linux-riscv64-musl': 0.41.0 - '@oxfmt/binding-linux-s390x-gnu': 0.41.0 - '@oxfmt/binding-linux-x64-gnu': 0.41.0 - '@oxfmt/binding-linux-x64-musl': 0.41.0 - '@oxfmt/binding-openharmony-arm64': 0.41.0 - '@oxfmt/binding-win32-arm64-msvc': 0.41.0 - '@oxfmt/binding-win32-ia32-msvc': 0.41.0 - '@oxfmt/binding-win32-x64-msvc': 0.41.0 + '@oxfmt/binding-android-arm-eabi': 0.42.0 + '@oxfmt/binding-android-arm64': 0.42.0 + '@oxfmt/binding-darwin-arm64': 0.42.0 + '@oxfmt/binding-darwin-x64': 0.42.0 + '@oxfmt/binding-freebsd-x64': 0.42.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.42.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.42.0 + '@oxfmt/binding-linux-arm64-gnu': 0.42.0 + '@oxfmt/binding-linux-arm64-musl': 0.42.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.42.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.42.0 + '@oxfmt/binding-linux-riscv64-musl': 0.42.0 + '@oxfmt/binding-linux-s390x-gnu': 0.42.0 + '@oxfmt/binding-linux-x64-gnu': 0.42.0 + '@oxfmt/binding-linux-x64-musl': 0.42.0 + '@oxfmt/binding-openharmony-arm64': 0.42.0 + '@oxfmt/binding-win32-arm64-msvc': 0.42.0 + '@oxfmt/binding-win32-ia32-msvc': 0.42.0 + '@oxfmt/binding-win32-x64-msvc': 0.42.0 - oxlint-tsgolint@0.17.1: + oxlint-tsgolint@0.17.3: optionalDependencies: - '@oxlint-tsgolint/darwin-arm64': 0.17.1 - '@oxlint-tsgolint/darwin-x64': 0.17.1 - '@oxlint-tsgolint/linux-arm64': 0.17.1 - '@oxlint-tsgolint/linux-x64': 0.17.1 - '@oxlint-tsgolint/win32-arm64': 0.17.1 - '@oxlint-tsgolint/win32-x64': 0.17.1 + '@oxlint-tsgolint/darwin-arm64': 0.17.3 + '@oxlint-tsgolint/darwin-x64': 0.17.3 + '@oxlint-tsgolint/linux-arm64': 0.17.3 + '@oxlint-tsgolint/linux-x64': 0.17.3 + '@oxlint-tsgolint/win32-arm64': 0.17.3 + '@oxlint-tsgolint/win32-x64': 0.17.3 - oxlint@1.56.0(oxlint-tsgolint@0.17.1): + oxlint@1.57.0(oxlint-tsgolint@0.17.3): optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.56.0 - '@oxlint/binding-android-arm64': 1.56.0 - '@oxlint/binding-darwin-arm64': 1.56.0 - '@oxlint/binding-darwin-x64': 1.56.0 - '@oxlint/binding-freebsd-x64': 1.56.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.56.0 - '@oxlint/binding-linux-arm-musleabihf': 1.56.0 - '@oxlint/binding-linux-arm64-gnu': 1.56.0 - '@oxlint/binding-linux-arm64-musl': 1.56.0 - '@oxlint/binding-linux-ppc64-gnu': 1.56.0 - '@oxlint/binding-linux-riscv64-gnu': 1.56.0 - '@oxlint/binding-linux-riscv64-musl': 1.56.0 - '@oxlint/binding-linux-s390x-gnu': 1.56.0 - '@oxlint/binding-linux-x64-gnu': 1.56.0 - '@oxlint/binding-linux-x64-musl': 1.56.0 - '@oxlint/binding-openharmony-arm64': 1.56.0 - '@oxlint/binding-win32-arm64-msvc': 1.56.0 - '@oxlint/binding-win32-ia32-msvc': 1.56.0 - '@oxlint/binding-win32-x64-msvc': 1.56.0 - oxlint-tsgolint: 0.17.1 + '@oxlint/binding-android-arm-eabi': 1.57.0 + '@oxlint/binding-android-arm64': 1.57.0 + '@oxlint/binding-darwin-arm64': 1.57.0 + '@oxlint/binding-darwin-x64': 1.57.0 + '@oxlint/binding-freebsd-x64': 1.57.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.57.0 + '@oxlint/binding-linux-arm-musleabihf': 1.57.0 + '@oxlint/binding-linux-arm64-gnu': 1.57.0 + '@oxlint/binding-linux-arm64-musl': 1.57.0 + '@oxlint/binding-linux-ppc64-gnu': 1.57.0 + '@oxlint/binding-linux-riscv64-gnu': 1.57.0 + '@oxlint/binding-linux-riscv64-musl': 1.57.0 + '@oxlint/binding-linux-s390x-gnu': 1.57.0 + '@oxlint/binding-linux-x64-gnu': 1.57.0 + '@oxlint/binding-linux-x64-musl': 1.57.0 + '@oxlint/binding-openharmony-arm64': 1.57.0 + '@oxlint/binding-win32-arm64-msvc': 1.57.0 + '@oxlint/binding-win32-ia32-msvc': 1.57.0 + '@oxlint/binding-win32-x64-msvc': 1.57.0 + oxlint-tsgolint: 0.17.3 p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 + p-limit@7.3.0: + dependencies: + yocto-queue: 1.2.2 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 package-manager-detector@1.6.0: {} + pad-right@0.2.2: + dependencies: + repeat-string: 1.6.1 + pako@0.2.9: {} papaparse@5.5.3: {} @@ -14456,6 +16035,12 @@ snapshots: dependencies: parse-statements: 1.0.11 + parse-json@8.3.0: + dependencies: + '@babel/code-frame': 7.29.0 + index-to-position: 1.2.0 + type-fest: 4.41.0 + parse-statements@1.0.11: {} parse5-htmlparser2-tree-adapter@7.1.0: @@ -14531,7 +16116,7 @@ snapshots: pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.8.1 + mlly: 1.8.2 pathe: 2.0.3 pkg-types@2.3.0: @@ -14540,6 +16125,14 @@ snapshots: exsolve: 1.0.8 pathe: 2.0.3 + playwright-core@1.58.2: {} + + playwright@1.58.2: + dependencies: + playwright-core: 1.58.2 + optionalDependencies: + fsevents: 2.3.2 + pluralize@8.0.0: {} pngjs@7.0.0: {} @@ -14558,7 +16151,7 @@ snapshots: portfinder@1.0.38: dependencies: async: 3.2.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -14587,6 +16180,15 @@ snapshots: tsx: 4.21.0 yaml: 2.8.3 + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.3): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 2.6.1 + postcss: 8.5.8 + tsx: 4.21.0 + yaml: 2.8.3 + postcss-nested@6.2.0(postcss@8.5.8): dependencies: postcss: 8.5.8 @@ -14621,6 +16223,8 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + powershell-utils@0.1.0: {} + prebuild-install@7.1.3: dependencies: detect-libc: 2.1.2 @@ -14647,18 +16251,24 @@ snapshots: prismjs@1.30.0: {} + progress@2.0.3: {} + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 + property-expr@2.0.6: {} + property-information@5.6.0: dependencies: xtend: 4.0.2 property-information@7.1.0: {} + proxy-from-env@2.1.0: {} + pump@3.0.4: dependencies: end-of-stream: 1.4.5 @@ -14731,7 +16341,7 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - react-easy-crop@5.5.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + react-easy-crop@5.5.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: normalize-wheel: 1.0.1 react: 19.2.4 @@ -14749,11 +16359,11 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - react-i18next@16.6.1(i18next@25.10.4(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3): + react-i18next@16.6.6(i18next@25.10.10(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3): dependencies: '@babel/runtime': 7.29.2 html-parse-stringify: 3.0.1 - i18next: 25.10.4(typescript@5.9.3) + i18next: 25.10.10(typescript@5.9.3) react: 19.2.4 use-sync-external-store: 1.6.0(react@19.2.4) optionalDependencies: @@ -14881,6 +16491,20 @@ snapshots: dependencies: pify: 2.3.0 + read-package-up@12.0.0: + dependencies: + find-up-simple: 1.0.1 + read-pkg: 10.1.0 + type-fest: 5.5.0 + + read-pkg@10.1.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 8.0.0 + parse-json: 8.3.0 + type-fest: 5.5.0 + unicorn-magic: 0.4.0 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -14940,6 +16564,8 @@ snapshots: dependencies: '@eslint-community/regexpp': 4.12.2 + reflect-metadata@0.2.2: {} + refractor@3.6.0: dependencies: hastscript: 6.0.0 @@ -14951,6 +16577,10 @@ snapshots: '@eslint-community/regexpp': 4.12.2 refa: 0.12.1 + regexp-match-indices@1.0.2: + dependencies: + regexp-tree: 0.1.27 + regexp-tree@0.1.27: {} regjsparser@0.13.0: @@ -14967,7 +16597,7 @@ snapshots: '@types/katex': 0.16.8 hast-util-from-html-isomorphic: 2.0.0 hast-util-to-text: 4.0.2 - katex: 0.16.40 + katex: 0.16.44 unist-util-visit-parents: 6.0.2 vfile: 6.0.3 @@ -15057,6 +16687,8 @@ snapshots: remend@1.3.0: {} + repeat-string@1.6.1: {} + require-from-string@2.0.2: {} reselect@5.1.1: {} @@ -15067,6 +16699,8 @@ snapshots: resolve-from@4.0.0: {} + resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} resolve@1.22.11: @@ -15084,7 +16718,31 @@ snapshots: rfdc@1.4.1: {} - robust-predicates@3.0.2: {} + robust-predicates@3.0.3: {} + + rolldown@1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1): + dependencies: + '@oxc-project/types': 0.122.0 + '@rolldown/pluginutils': 1.0.0-rc.12 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.12 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.12 + '@rolldown/binding-darwin-x64': 1.0.0-rc.12 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.12 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.12 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.12 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.12 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.12 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.12 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.12 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.12 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' rollup@4.59.0: dependencies: @@ -15163,11 +16821,6 @@ snapshots: sax@1.6.0: {} - saxes@6.0.0: - dependencies: - xmlchars: 2.2.0 - optional: true - scheduler@0.27.0: {} schema-utils@4.3.3: @@ -15185,6 +16838,8 @@ snapshots: refa: 0.12.1 regexp-ast-analysis: 0.7.1 + seed-random@2.2.0: {} + semver@6.3.1: {} semver@7.7.4: {} @@ -15291,8 +16946,18 @@ snapshots: space-separated-tokens@2.0.2: {} + 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-expression-parse@4.0.0: dependencies: spdx-exceptions: 2.5.0 @@ -15300,7 +16965,9 @@ snapshots: spdx-license-ids@3.0.23: {} - srvx@0.11.12: {} + srvx@0.11.13: {} + + stackframe@1.3.4: {} state-local@1.0.7: {} @@ -15308,7 +16975,7 @@ snapshots: std-semver@1.0.8: {} - storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -15321,7 +16988,7 @@ snapshots: recast: 0.23.11 semver: 7.7.4 use-sync-external-store: 1.6.0(react@19.2.4) - ws: 8.19.0 + ws: 8.20.0 transitivePeerDependencies: - '@testing-library/dom' - bufferutil @@ -15334,7 +17001,7 @@ snapshots: clsx: 2.1.1 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 - marked: 17.0.4 + marked: 17.0.5 mermaid: 11.13.0 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) @@ -15352,6 +17019,8 @@ snapshots: transitivePeerDependencies: - supports-color + string-argv@0.3.1: {} + string-argv@0.3.2: {} string-ts@2.3.1: {} @@ -15396,6 +17065,8 @@ snapshots: dependencies: js-tokens: 9.0.1 + structured-clone-es@2.0.0: {} + style-to-js@1.1.21: dependencies: style-to-object: 1.0.14 @@ -15443,9 +17114,6 @@ snapshots: picocolors: 1.1.1 sax: 1.6.0 - symbol-tree@3.2.4: - optional: true - synckit@0.11.12: dependencies: '@pkgr/core': 0.2.9 @@ -15488,8 +17156,6 @@ snapshots: - tsx - yaml - tapable@2.3.0: {} - tapable@2.3.2: {} tar-fs@2.1.4: @@ -15559,6 +17225,8 @@ snapshots: dependencies: any-promise: 1.3.0 + tiny-case@1.0.3: {} + tiny-inflate@1.0.3: {} tiny-invariant@1.2.0: {} @@ -15567,6 +17235,8 @@ snapshots: tinybench@2.9.0: {} + tinyexec@0.3.2: {} + tinyexec@1.0.4: {} tinyglobby@0.2.15: @@ -15603,23 +17273,17 @@ snapshots: dependencies: eslint-visitor-keys: 5.0.1 + toposort@2.0.2: {} + totalist@3.0.1: {} - tough-cookie@6.0.1: - dependencies: - tldts: 7.0.27 - optional: true - - tr46@6.0.0: - dependencies: - punycode: 2.3.1 - optional: true + tree-kill@1.2.2: {} trim-lines@3.0.1: {} trough@2.2.0: {} - ts-api-utils@2.4.0(typescript@5.9.3): + ts-api-utils@2.5.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -15644,7 +17308,7 @@ snapshots: dependencies: chalk: 4.1.2 enhanced-resolve: 5.20.1 - tapable: 2.3.0 + tapable: 2.3.2 tsconfig-paths: 4.2.0 tsconfig-paths@4.2.0: @@ -15659,6 +17323,34 @@ snapshots: tslib@2.8.1: {} + tsup@8.5.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3): + dependencies: + bundle-require: 5.1.0(esbuild@0.27.2) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3(supports-color@8.1.1) + esbuild: 0.27.2 + fix-dts-default-cjs-exports: 1.0.1 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8)(tsx@4.21.0)(yaml@2.8.3) + resolve-from: 5.0.0 + rollup: 4.59.0 + source-map: 0.7.6 + sucrase: 3.35.1 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.5.8 + typescript: 5.9.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + tsx@4.21.0: dependencies: esbuild: 0.27.2 @@ -15677,7 +17369,11 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-fest@5.4.4: + type-fest@2.19.0: {} + + type-fest@4.41.0: {} + + type-fest@5.5.0: dependencies: tagged-tag: 1.0.0 @@ -15706,14 +17402,13 @@ snapshots: undici@7.24.0: {} - undici@7.24.6: - optional: true - unicode-trie@2.0.0: dependencies: pako: 0.2.9 tiny-inflate: 1.0.3 + unicorn-magic@0.4.0: {} + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -15783,6 +17478,10 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + upper-case-first@2.0.2: + dependencies: + tslib: 2.8.1 + uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -15832,16 +17531,23 @@ snapshots: dependencies: react: 19.2.4 + util-arity@1.1.0: {} + util-deprecate@1.0.2: {} uuid@11.1.0: {} uuid@13.0.0: {} - valibot@1.3.0(typescript@5.9.3): + valibot@1.3.1(typescript@5.9.3): optionalDependencies: typescript: 5.9.3 + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + vfile-location@5.0.3: dependencies: '@types/unist': 3.0.3 @@ -15857,37 +17563,27 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vinext@https://pkg.pr.new/vinext@b6a2cac(33c71b051bfc49f90bf5d8b6a8976975): + vinext@0.0.38(f5786d681f520e26604259e094ebaa46): dependencies: - '@unpic/react': 1.0.2(next@16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@unpic/react': 1.0.2(next@16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@vercel/og': 0.8.6 - '@vitejs/plugin-react': 6.0.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) + '@vitejs/plugin-react': 6.0.1(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) magic-string: 0.30.21 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) rsc-html-stream: 0.0.7 - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' vite-plugin-commonjs: 0.10.4 - vite-tsconfig-paths: 6.1.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3) + vite-tsconfig-paths: 6.1.1(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3) optionalDependencies: '@mdx-js/rollup': 3.1.1(rollup@4.59.0) - '@vitejs/plugin-rsc': 0.5.21(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)))(react@19.2.4) + '@vitejs/plugin-rsc': 0.5.21(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)))(react@19.2.4) react-server-dom-webpack: 19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3)) transitivePeerDependencies: - next - supports-color - typescript - vite-dev-rpc@1.1.0(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)): - dependencies: - birpc: 2.9.0 - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' - vite-hot-client: 2.1.0(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) - - vite-hot-client@2.1.0(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)): - dependencies: - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' - vite-plugin-commonjs@0.10.4: dependencies: acorn: 8.16.0 @@ -15901,54 +17597,57 @@ snapshots: fast-glob: 3.3.3 magic-string: 0.30.21 - vite-plugin-inspect@11.3.3(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)): + vite-plugin-inspect@12.0.0-beta.1(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3)(ws@8.20.0): dependencies: + '@vitejs/devtools-kit': 0.1.11(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3)(ws@8.20.0) ansis: 4.2.0 - debug: 4.4.3 error-stack-parser-es: 1.0.5 + obug: 2.1.1 ohash: 2.0.11 - open: 10.2.0 + open: 11.0.0 perfect-debounce: 2.1.0 sirv: 3.0.2 unplugin-utils: 0.3.1 - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' - vite-dev-rpc: 1.1.0(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)) + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' transitivePeerDependencies: - - supports-color + - typescript + - ws - vite-plugin-storybook-nextjs@3.2.3(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(next@16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(storybook@10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3): + vite-plugin-storybook-nextjs@3.2.4(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(next@16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(storybook@10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3): dependencies: '@next/env': 16.0.0 image-size: 2.0.2 magic-string: 0.30.21 module-alias: 2.3.4 - next: 16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) - storybook: 10.3.1(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + next: 16.2.1(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) + storybook: 10.3.3(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ts-dedent: 2.2.0 - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' - vite-tsconfig-paths: 5.1.4(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3) + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vite-tsconfig-paths: 5.1.4(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3) transitivePeerDependencies: - supports-color - typescript - vite-plus@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3): + vite-plus@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3): dependencies: - '@oxc-project/types': 0.120.0 - '@voidzero-dev/vite-plus-core': 0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) - '@voidzero-dev/vite-plus-test': 0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) + '@oxc-project/types': 0.122.0 + '@voidzero-dev/vite-plus-core': 0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) + '@voidzero-dev/vite-plus-test': 0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) cac: 7.0.0 cross-spawn: 7.0.6 - oxfmt: 0.41.0 - oxlint: 1.56.0(oxlint-tsgolint@0.17.1) - oxlint-tsgolint: 0.17.1 + oxfmt: 0.42.0 + oxlint: 1.57.0(oxlint-tsgolint@0.17.3) + oxlint-tsgolint: 0.17.3 picocolors: 1.1.1 optionalDependencies: - '@voidzero-dev/vite-plus-darwin-arm64': 0.1.13 - '@voidzero-dev/vite-plus-darwin-x64': 0.1.13 - '@voidzero-dev/vite-plus-linux-arm64-gnu': 0.1.13 - '@voidzero-dev/vite-plus-linux-x64-gnu': 0.1.13 - '@voidzero-dev/vite-plus-win32-arm64-msvc': 0.1.13 - '@voidzero-dev/vite-plus-win32-x64-msvc': 0.1.13 + '@voidzero-dev/vite-plus-darwin-arm64': 0.1.14 + '@voidzero-dev/vite-plus-darwin-x64': 0.1.14 + '@voidzero-dev/vite-plus-linux-arm64-gnu': 0.1.14 + '@voidzero-dev/vite-plus-linux-arm64-musl': 0.1.14 + '@voidzero-dev/vite-plus-linux-x64-gnu': 0.1.14 + '@voidzero-dev/vite-plus-linux-x64-musl': 0.1.14 + '@voidzero-dev/vite-plus-win32-arm64-msvc': 0.1.14 + '@voidzero-dev/vite-plus-win32-x64-msvc': 0.1.14 transitivePeerDependencies: - '@arethetypeswrong/core' - '@edge-runtime/vm' @@ -15977,36 +17676,104 @@ snapshots: - vite - yaml - vite-tsconfig-paths@5.1.4(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3): + vite-plus@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3): dependencies: - debug: 4.4.3 + '@oxc-project/types': 0.122.0 + '@voidzero-dev/vite-plus-core': 0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3) + '@voidzero-dev/vite-plus-test': 0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))(yaml@2.8.3) + cac: 7.0.0 + cross-spawn: 7.0.6 + oxfmt: 0.42.0 + oxlint: 1.57.0(oxlint-tsgolint@0.17.3) + oxlint-tsgolint: 0.17.3 + picocolors: 1.1.1 + optionalDependencies: + '@voidzero-dev/vite-plus-darwin-arm64': 0.1.14 + '@voidzero-dev/vite-plus-darwin-x64': 0.1.14 + '@voidzero-dev/vite-plus-linux-arm64-gnu': 0.1.14 + '@voidzero-dev/vite-plus-linux-arm64-musl': 0.1.14 + '@voidzero-dev/vite-plus-linux-x64-gnu': 0.1.14 + '@voidzero-dev/vite-plus-linux-x64-musl': 0.1.14 + '@voidzero-dev/vite-plus-win32-arm64-msvc': 0.1.14 + '@voidzero-dev/vite-plus-win32-x64-msvc': 0.1.14 + transitivePeerDependencies: + - '@arethetypeswrong/core' + - '@edge-runtime/vm' + - '@opentelemetry/api' + - '@tsdown/css' + - '@tsdown/exe' + - '@types/node' + - '@vitejs/devtools' + - '@vitest/ui' + - bufferutil + - esbuild + - happy-dom + - jiti + - jsdom + - less + - publint + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - typescript + - unplugin-unused + - utf-8-validate + - vite + - yaml + + vite-tsconfig-paths@5.1.4(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3): + dependencies: + debug: 4.4.3(supports-color@8.1.1) globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' transitivePeerDependencies: - supports-color - typescript - vite-tsconfig-paths@6.1.1(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3): + vite-tsconfig-paths@6.1.1(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(typescript@5.9.3): dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' transitivePeerDependencies: - supports-color - typescript - vitefu@1.1.2(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)): + vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(esbuild@0.27.2)(jiti@2.6.1)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.8 + rolldown: 1.0.0-rc.12(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1) + tinyglobby: 0.2.15 optionalDependencies: - vite: '@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + '@types/node': 25.5.0 + esbuild: 0.27.2 + fsevents: 2.3.3 + jiti: 2.6.1 + sass: 1.98.0 + terser: 5.46.1 + tsx: 4.21.0 + yaml: 2.8.3 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - vitest-canvas-mock@1.1.3(@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)): + vitefu@1.1.2(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)): + optionalDependencies: + vite: '@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + + vitest-canvas-mock@1.1.4(@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)): dependencies: cssfontparser: 1.2.1 moo-color: 1.0.3 - vitest: '@voidzero-dev/vite-plus-test@0.1.13(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.13(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(jsdom@29.0.1(canvas@3.2.2))(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' + vitest: '@voidzero-dev/vite-plus-test@0.1.14(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.14(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.8.9)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.1)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.3)' void-elements@3.1.0: {} @@ -16029,7 +17796,7 @@ snapshots: vue-eslint-parser@10.4.0(eslint@10.1.0(jiti@1.21.7)): dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 10.1.0(jiti@1.21.7) eslint-scope: 9.1.2 eslint-visitor-keys: 5.0.1 @@ -16039,11 +17806,6 @@ snapshots: transitivePeerDependencies: - supports-color - w3c-xmlserializer@5.0.0: - dependencies: - xml-name-validator: 5.0.0 - optional: true - walk-up-path@4.0.0: {} watchpack@2.5.1: @@ -16055,9 +17817,6 @@ snapshots: web-vitals@5.1.0: {} - webidl-conversions@8.0.1: - optional: true - webpack-sources@3.3.4: {} webpack-virtual-modules@0.6.2: {} @@ -16102,18 +17861,6 @@ snapshots: whatwg-mimetype@4.0.0: {} - whatwg-mimetype@5.0.0: - optional: true - - whatwg-url@16.0.1: - dependencies: - '@exodus/bytes': 1.15.0 - tr46: 6.0.0 - webidl-conversions: 8.0.1 - transitivePeerDependencies: - - '@noble/hashes' - optional: true - which@2.0.2: dependencies: isexe: 2.0.0 @@ -16128,21 +17875,20 @@ snapshots: wrappy@1.0.2: {} - ws@8.19.0: {} - ws@8.20.0: {} wsl-utils@0.1.0: dependencies: is-wsl: 3.1.1 + wsl-utils@0.3.1: + dependencies: + is-wsl: 3.1.1 + powershell-utils: 0.1.0 + xml-name-validator@4.0.0: {} - xml-name-validator@5.0.0: - optional: true - - xmlchars@2.2.0: - optional: true + xmlbuilder@15.1.1: {} xtend@4.0.2: {} @@ -16168,8 +17914,17 @@ snapshots: yocto-queue@0.1.0: {} + yocto-queue@1.2.2: {} + yoga-layout@3.2.1: {} + yup@1.7.1: + dependencies: + property-expr: 2.0.6 + tiny-case: 1.0.3 + toposort: 2.0.2 + type-fest: 2.19.0 + zen-observable@0.10.0: {} zimmerframe@1.1.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000000..ae53a57832 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,260 @@ +trustPolicy: no-downgrade +minimumReleaseAge: 1440 +blockExoticSubdeps: true +strictDepBuilds: true +allowBuilds: + '@parcel/watcher': false + canvas: false + esbuild: false + sharp: false +packages: + - web + - e2e + - sdks/nodejs-client +overrides: + "@lexical/code": npm:lexical-code-no-prism@0.41.0 + "@monaco-editor/loader": 1.7.0 + "@nolyfill/safe-buffer": npm:safe-buffer@^5.2.1 + array-includes: npm:@nolyfill/array-includes@^1.0.44 + array.prototype.findlast: npm:@nolyfill/array.prototype.findlast@^1.0.44 + array.prototype.findlastindex: npm:@nolyfill/array.prototype.findlastindex@^1.0.44 + array.prototype.flat: npm:@nolyfill/array.prototype.flat@^1.0.44 + array.prototype.flatmap: npm:@nolyfill/array.prototype.flatmap@^1.0.44 + array.prototype.tosorted: npm:@nolyfill/array.prototype.tosorted@^1.0.44 + assert: npm:@nolyfill/assert@^1.0.26 + axios: 1.14.0 + brace-expansion@<2.0.2: 2.0.2 + canvas: ^3.2.2 + devalue@<5.3.2: 5.3.2 + dompurify@>=3.1.3 <=3.3.1: 3.3.2 + es-iterator-helpers: npm:@nolyfill/es-iterator-helpers@^1.0.21 + esbuild@<0.27.2: 0.27.2 + flatted@<=3.4.1: 3.4.2 + glob@>=10.2.0 <10.5.0: 11.1.0 + hasown: npm:@nolyfill/hasown@^1.0.44 + is-arguments: npm:@nolyfill/is-arguments@^1.0.44 + is-core-module: npm:@nolyfill/is-core-module@^1.0.39 + is-generator-function: npm:@nolyfill/is-generator-function@^1.0.44 + is-typed-array: npm:@nolyfill/is-typed-array@^1.0.44 + isarray: npm:@nolyfill/isarray@^1.0.44 + object.assign: npm:@nolyfill/object.assign@^1.0.44 + object.entries: npm:@nolyfill/object.entries@^1.0.44 + object.fromentries: npm:@nolyfill/object.fromentries@^1.0.44 + object.groupby: npm:@nolyfill/object.groupby@^1.0.44 + object.values: npm:@nolyfill/object.values@^1.0.44 + pbkdf2: ~3.1.5 + pbkdf2@<3.1.3: 3.1.3 + picomatch@<2.3.2: 2.3.2 + picomatch@>=4.0.0 <4.0.4: 4.0.4 + prismjs: ~1.30 + prismjs@<1.30.0: 1.30.0 + rollup@>=4.0.0 <4.59.0: 4.59.0 + safe-buffer: ^5.2.1 + safe-regex-test: npm:@nolyfill/safe-regex-test@^1.0.44 + safer-buffer: npm:@nolyfill/safer-buffer@^1.0.44 + side-channel: npm:@nolyfill/side-channel@^1.0.44 + smol-toml@<1.6.1: 1.6.1 + solid-js: 1.9.11 + string-width: ~8.2.0 + string.prototype.includes: npm:@nolyfill/string.prototype.includes@^1.0.44 + string.prototype.matchall: npm:@nolyfill/string.prototype.matchall@^1.0.44 + string.prototype.repeat: npm:@nolyfill/string.prototype.repeat@^1.0.44 + string.prototype.trimend: npm:@nolyfill/string.prototype.trimend@^1.0.44 + svgo@>=3.0.0 <3.3.3: 3.3.3 + tar@<=7.5.10: 7.5.11 + typed-array-buffer: npm:@nolyfill/typed-array-buffer@^1.0.44 + undici@>=7.0.0 <7.24.0: 7.24.0 + vite: npm:@voidzero-dev/vite-plus-core@0.1.14 + vitest: npm:@voidzero-dev/vite-plus-test@0.1.14 + which-typed-array: npm:@nolyfill/which-typed-array@^1.0.44 + yaml@>=2.0.0 <2.8.3: 2.8.3 + yauzl@<3.2.1: 3.2.1 +catalog: + "@amplitude/analytics-browser": 2.38.0 + "@amplitude/plugin-session-replay-browser": 1.27.5 + "@antfu/eslint-config": 7.7.3 + "@base-ui/react": 1.3.0 + "@chromatic-com/storybook": 5.1.1 + "@cucumber/cucumber": 12.7.0 + "@egoist/tailwindcss-icons": 1.9.2 + "@emoji-mart/data": 1.2.1 + "@eslint-react/eslint-plugin": 3.0.0 + "@eslint/js": ^10.0.1 + "@floating-ui/react": 0.27.19 + "@formatjs/intl-localematcher": 0.8.2 + "@headlessui/react": 2.2.9 + "@heroicons/react": 2.2.0 + "@hono/node-server": 1.19.11 + "@iconify-json/heroicons": 1.2.3 + "@iconify-json/ri": 1.2.10 + "@lexical/code": 0.42.0 + "@lexical/link": 0.42.0 + "@lexical/list": 0.42.0 + "@lexical/react": 0.42.0 + "@lexical/selection": 0.42.0 + "@lexical/text": 0.42.0 + "@lexical/utils": 0.42.0 + "@mdx-js/loader": 3.1.1 + "@mdx-js/react": 3.1.1 + "@mdx-js/rollup": 3.1.1 + "@monaco-editor/react": 4.7.0 + "@next/eslint-plugin-next": 16.2.1 + "@next/mdx": 16.2.1 + "@orpc/client": 1.13.13 + "@orpc/contract": 1.13.13 + "@orpc/openapi-client": 1.13.13 + "@orpc/tanstack-query": 1.13.13 + "@playwright/test": 1.58.2 + "@remixicon/react": 4.9.0 + "@rgrove/parse-xml": 4.2.0 + "@sentry/react": 10.46.0 + "@storybook/addon-docs": 10.3.3 + "@storybook/addon-links": 10.3.3 + "@storybook/addon-onboarding": 10.3.3 + "@storybook/addon-themes": 10.3.3 + "@storybook/nextjs-vite": 10.3.3 + "@storybook/react": 10.3.3 + "@streamdown/math": 1.0.2 + "@svgdotjs/svg.js": 3.2.5 + "@t3-oss/env-nextjs": 0.13.11 + "@tailwindcss/typography": 0.5.19 + "@tanstack/eslint-plugin-query": 5.95.2 + "@tanstack/react-devtools": 0.10.0 + "@tanstack/react-form": 1.28.5 + "@tanstack/react-form-devtools": 0.2.19 + "@tanstack/react-query": 5.95.2 + "@tanstack/react-query-devtools": 5.95.2 + "@testing-library/dom": 10.4.1 + "@testing-library/jest-dom": 6.9.1 + "@testing-library/react": 16.3.2 + "@testing-library/user-event": 14.6.1 + "@tsslint/cli": 3.0.2 + "@tsslint/compat-eslint": 3.0.2 + "@tsslint/config": 3.0.2 + "@types/js-cookie": 3.0.6 + "@types/js-yaml": 4.0.9 + "@types/negotiator": 0.6.4 + "@types/node": 25.5.0 + "@types/postcss-js": 4.1.0 + "@types/qs": 6.15.0 + "@types/react": 19.2.14 + "@types/react-dom": 19.2.3 + "@types/react-syntax-highlighter": 15.5.13 + "@types/react-window": 1.8.8 + "@types/sortablejs": 1.15.9 + "@typescript-eslint/eslint-plugin": ^8.57.2 + "@typescript-eslint/parser": 8.57.2 + "@typescript/native-preview": 7.0.0-dev.20260329.1 + "@vitejs/plugin-react": 6.0.1 + "@vitejs/plugin-rsc": 0.5.21 + "@vitest/coverage-v8": 4.1.2 + abcjs: 6.6.2 + agentation: 3.0.2 + ahooks: 3.9.7 + autoprefixer: 10.4.27 + axios: 1.14.0 + class-variance-authority: 0.7.1 + clsx: 2.1.1 + cmdk: 1.1.1 + code-inspector-plugin: 1.4.5 + copy-to-clipboard: 3.3.3 + cron-parser: 5.5.0 + dayjs: 1.11.20 + decimal.js: 10.6.0 + dompurify: 3.3.3 + echarts: 6.0.0 + echarts-for-react: 3.0.6 + elkjs: 0.11.1 + embla-carousel-autoplay: 8.6.0 + embla-carousel-react: 8.6.0 + emoji-mart: 5.6.0 + es-toolkit: 1.45.1 + eslint: 10.1.0 + eslint-markdown: 0.6.0 + eslint-plugin-better-tailwindcss: 4.3.2 + eslint-plugin-hyoban: 0.14.1 + eslint-plugin-markdown-preferences: 0.40.3 + eslint-plugin-no-barrel-files: 1.2.2 + eslint-plugin-react-hooks: 7.0.1 + eslint-plugin-react-refresh: 0.5.2 + eslint-plugin-sonarjs: 4.0.2 + eslint-plugin-storybook: 10.3.3 + fast-deep-equal: 3.1.3 + foxact: 0.3.0 + happy-dom: 20.8.9 + hono: 4.12.9 + html-entities: 2.6.0 + html-to-image: 1.11.13 + husky: 9.1.7 + i18next: 25.10.10 + i18next-resources-to-backend: 1.2.1 + iconify-import-svg: 0.1.2 + immer: 11.1.4 + jotai: 2.19.0 + js-audio-recorder: 1.0.7 + js-cookie: 3.0.5 + js-yaml: 4.1.1 + jsonschema: 1.5.0 + katex: 0.16.44 + knip: 6.1.0 + ky: 1.14.3 + lamejs: 1.2.1 + lexical: 0.42.0 + lint-staged: 16.4.0 + mermaid: 11.13.0 + mime: 4.1.0 + mitt: 3.0.1 + negotiator: 1.0.0 + next: 16.2.1 + next-themes: 0.4.6 + nuqs: 2.8.9 + pinyin-pro: 3.28.0 + postcss: 8.5.8 + postcss-js: 5.1.0 + qrcode.react: 4.2.0 + qs: 6.15.0 + react: 19.2.4 + react-18-input-autosize: 3.0.0 + react-dom: 19.2.4 + react-easy-crop: 5.5.7 + react-hotkeys-hook: 5.2.4 + react-i18next: 16.6.6 + react-multi-email: 1.0.25 + react-papaparse: 4.4.0 + react-pdf-highlighter: 8.0.0-rc.0 + react-server-dom-webpack: 19.2.4 + react-sortablejs: 6.1.4 + react-syntax-highlighter: 15.6.6 + react-textarea-autosize: 8.5.9 + react-window: 1.8.11 + reactflow: 11.11.4 + remark-breaks: 4.0.0 + remark-directive: 4.0.0 + sass: 1.98.0 + scheduler: 0.27.0 + sharp: 0.34.5 + sortablejs: 1.15.7 + std-semver: 1.0.8 + storybook: 10.3.3 + streamdown: 2.5.0 + string-ts: 2.3.1 + tailwind-merge: 2.6.1 + tailwindcss: 3.4.19 + taze: 19.10.0 + tldts: 7.0.27 + tsup: ^8.5.1 + tsx: 4.21.0 + typescript: 5.9.3 + uglify-js: 3.19.3 + unist-util-visit: 5.1.0 + use-context-selector: 2.0.0 + uuid: 13.0.0 + vinext: 0.0.38 + vite: npm:@voidzero-dev/vite-plus-core@0.1.14 + vite-plugin-inspect: 12.0.0-beta.1 + vite-plus: 0.1.14 + vitest: npm:@voidzero-dev/vite-plus-test@0.1.14 + vitest-canvas-mock: 1.1.4 + zod: 4.3.6 + zundo: 2.3.0 + zustand: 5.0.12 diff --git a/sdks/nodejs-client/README.md b/sdks/nodejs-client/README.md index f8c2803c08..7051bbc788 100644 --- a/sdks/nodejs-client/README.md +++ b/sdks/nodejs-client/README.md @@ -100,6 +100,10 @@ Notes: - Chat/completion require a stable `user` identifier in the request payload. - For streaming responses, iterate the returned AsyncIterable. Use `stream.toText()` to collect text. +## Maintainers + +This package is published from the repository workspace. Install dependencies from the repository root with `pnpm install`, then use `./scripts/publish.sh` for dry runs and publishing so `catalog:` dependencies are resolved before release. + ## License This SDK is released under the MIT License. diff --git a/sdks/nodejs-client/package.json b/sdks/nodejs-client/package.json index 7168d33c24..63fa6799b1 100644 --- a/sdks/nodejs-client/package.json +++ b/sdks/nodejs-client/package.json @@ -54,24 +54,17 @@ "publish:npm": "./scripts/publish.sh" }, "dependencies": { - "axios": "^1.13.6" + "axios": "catalog:" }, "devDependencies": { - "@eslint/js": "^10.0.1", - "@types/node": "^25.4.0", - "@typescript-eslint/eslint-plugin": "^8.57.0", - "@typescript-eslint/parser": "^8.57.0", - "@vitest/coverage-v8": "4.0.18", - "eslint": "^10.0.3", - "tsup": "^8.5.1", - "typescript": "^5.9.3", - "vitest": "^4.0.18" - }, - "pnpm": { - "overrides": { - "flatted@<=3.4.1": "3.4.2", - "picomatch@>=4.0.0 <4.0.4": "4.0.4", - "rollup@>=4.0.0 <4.59.0": "4.59.0" - } + "@eslint/js": "catalog:", + "@types/node": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "@vitest/coverage-v8": "catalog:", + "eslint": "catalog:", + "tsup": "catalog:", + "typescript": "catalog:", + "vitest": "catalog:" } } diff --git a/sdks/nodejs-client/pnpm-lock.yaml b/sdks/nodejs-client/pnpm-lock.yaml deleted file mode 100644 index 30d3cf61ee..0000000000 --- a/sdks/nodejs-client/pnpm-lock.yaml +++ /dev/null @@ -1,2255 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -overrides: - flatted@<=3.4.1: 3.4.2 - picomatch@>=4.0.0 <4.0.4: 4.0.4 - rollup@>=4.0.0 <4.59.0: 4.59.0 - -importers: - - .: - dependencies: - axios: - specifier: ^1.13.6 - version: 1.13.6 - devDependencies: - '@eslint/js': - specifier: ^10.0.1 - version: 10.0.1(eslint@10.0.3) - '@types/node': - specifier: ^25.4.0 - version: 25.4.0 - '@typescript-eslint/eslint-plugin': - specifier: ^8.57.0 - version: 8.57.0(@typescript-eslint/parser@8.57.0(eslint@10.0.3)(typescript@5.9.3))(eslint@10.0.3)(typescript@5.9.3) - '@typescript-eslint/parser': - specifier: ^8.57.0 - version: 8.57.0(eslint@10.0.3)(typescript@5.9.3) - '@vitest/coverage-v8': - specifier: 4.0.18 - version: 4.0.18(vitest@4.0.18(@types/node@25.4.0)) - eslint: - specifier: ^10.0.3 - version: 10.0.3 - tsup: - specifier: ^8.5.1 - version: 8.5.1(postcss@8.5.8)(typescript@5.9.3) - typescript: - specifier: ^5.9.3 - version: 5.9.3 - vitest: - specifier: ^4.0.18 - version: 4.0.18(@types/node@25.4.0) - -packages: - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.0': - resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} - - '@bcoe/v8-coverage@1.0.2': - resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} - engines: {node: '>=18'} - - '@esbuild/aix-ppc64@0.27.3': - resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.27.3': - resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.27.3': - resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.27.3': - resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.27.3': - resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.27.3': - resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.27.3': - resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.27.3': - resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.27.3': - resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.27.3': - resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.27.3': - resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.27.3': - resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.27.3': - resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.27.3': - resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.27.3': - resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.27.3': - resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.27.3': - resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.27.3': - resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.27.3': - resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.27.3': - resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.27.3': - resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.27.3': - resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.27.3': - resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.27.3': - resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.27.3': - resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.27.3': - resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.23.3': - resolution: {integrity: sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/config-helpers@0.5.3': - resolution: {integrity: sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/core@1.1.1': - resolution: {integrity: sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/js@10.0.1': - resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - peerDependencies: - eslint: ^10.0.0 - peerDependenciesMeta: - eslint: - optional: true - - '@eslint/object-schema@3.0.3': - resolution: {integrity: sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@eslint/plugin-kit@0.6.1': - resolution: {integrity: sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@rollup/rollup-android-arm-eabi@4.59.0': - resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.59.0': - resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.59.0': - resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.59.0': - resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.59.0': - resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.59.0': - resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': - resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.59.0': - resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.59.0': - resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.59.0': - resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loong64-gnu@4.59.0': - resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-loong64-musl@4.59.0': - resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.59.0': - resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-ppc64-musl@4.59.0': - resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.59.0': - resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.59.0': - resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.59.0': - resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.59.0': - resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.59.0': - resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-openbsd-x64@4.59.0': - resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.59.0': - resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.59.0': - resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.59.0': - resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.59.0': - resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.59.0': - resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} - cpu: [x64] - os: [win32] - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/esrecurse@4.3.1': - resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/node@25.4.0': - resolution: {integrity: sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==} - - '@typescript-eslint/eslint-plugin@8.57.0': - resolution: {integrity: sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.57.0 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/parser@8.57.0': - resolution: {integrity: sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/project-service@8.57.0': - resolution: {integrity: sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/scope-manager@8.57.0': - resolution: {integrity: sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.57.0': - resolution: {integrity: sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/type-utils@8.57.0': - resolution: {integrity: sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/types@8.57.0': - resolution: {integrity: sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.57.0': - resolution: {integrity: sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/utils@8.57.0': - resolution: {integrity: sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/visitor-keys@8.57.0': - resolution: {integrity: sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@vitest/coverage-v8@4.0.18': - resolution: {integrity: sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==} - peerDependencies: - '@vitest/browser': 4.0.18 - vitest: 4.0.18 - peerDependenciesMeta: - '@vitest/browser': - optional: true - - '@vitest/expect@4.0.18': - resolution: {integrity: sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==} - - '@vitest/mocker@4.0.18': - resolution: {integrity: sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==} - peerDependencies: - msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0-0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - - '@vitest/pretty-format@4.0.18': - resolution: {integrity: sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==} - - '@vitest/runner@4.0.18': - resolution: {integrity: sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==} - - '@vitest/snapshot@4.0.18': - resolution: {integrity: sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==} - - '@vitest/spy@4.0.18': - resolution: {integrity: sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==} - - '@vitest/utils@4.0.18': - resolution: {integrity: sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv@6.14.0: - resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - - ast-v8-to-istanbul@0.3.12: - resolution: {integrity: sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - axios@1.13.6: - resolution: {integrity: sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==} - - balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} - - brace-expansion@5.0.4: - resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} - engines: {node: 18 || 20 || >=22} - - bundle-require@5.1.0: - resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - peerDependencies: - esbuild: '>=0.18' - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} - engines: {node: '>=18'} - - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - esbuild@0.27.3: - resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} - engines: {node: '>=18'} - hasBin: true - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-scope@9.1.2: - resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@5.0.1: - resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - eslint@10.0.3: - resolution: {integrity: sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@11.2.0: - resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} - engines: {node: '>=12.0.0'} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: 4.0.4 - peerDependenciesMeta: - picomatch: - optional: true - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - fix-dts-default-cjs-exports@1.0.1: - resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} - engines: {node: '>=8'} - - joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} - - js-tokens@10.0.0: - resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - load-tsconfig@0.2.5: - resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - magicast@0.5.2: - resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} - - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - minimatch@10.2.4: - resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} - engines: {node: 18 || 20 || >=22} - - mlly@1.8.1: - resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} - - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} - peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - yaml: - optional: true - - postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} - engines: {node: ^10 || ^12 || >=14} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - rollup@4.59.0: - resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - std-env@3.10.0: - resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - - sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - - tinyexec@1.0.2: - resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} - engines: {node: '>=18'} - - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - - tinyrainbow@3.0.3: - resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} - engines: {node: '>=14.0.0'} - - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - tsup@8.5.1: - resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.5.0' - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.6.3: - resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} - - undici-types@7.18.2: - resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - vite@7.3.1: - resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' - less: ^4.0.0 - lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitest@4.0.18: - resolution: {integrity: sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.18 - '@vitest/browser-preview': 4.0.18 - '@vitest/browser-webdriverio': 4.0.18 - '@vitest/ui': 4.0.18 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@opentelemetry/api': - optional: true - '@types/node': - optional: true - '@vitest/browser-playwright': - optional: true - '@vitest/browser-preview': - optional: true - '@vitest/browser-webdriverio': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - -snapshots: - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.28.5': {} - - '@babel/parser@7.29.0': - dependencies: - '@babel/types': 7.29.0 - - '@babel/types@7.29.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - - '@bcoe/v8-coverage@1.0.2': {} - - '@esbuild/aix-ppc64@0.27.3': - optional: true - - '@esbuild/android-arm64@0.27.3': - optional: true - - '@esbuild/android-arm@0.27.3': - optional: true - - '@esbuild/android-x64@0.27.3': - optional: true - - '@esbuild/darwin-arm64@0.27.3': - optional: true - - '@esbuild/darwin-x64@0.27.3': - optional: true - - '@esbuild/freebsd-arm64@0.27.3': - optional: true - - '@esbuild/freebsd-x64@0.27.3': - optional: true - - '@esbuild/linux-arm64@0.27.3': - optional: true - - '@esbuild/linux-arm@0.27.3': - optional: true - - '@esbuild/linux-ia32@0.27.3': - optional: true - - '@esbuild/linux-loong64@0.27.3': - optional: true - - '@esbuild/linux-mips64el@0.27.3': - optional: true - - '@esbuild/linux-ppc64@0.27.3': - optional: true - - '@esbuild/linux-riscv64@0.27.3': - optional: true - - '@esbuild/linux-s390x@0.27.3': - optional: true - - '@esbuild/linux-x64@0.27.3': - optional: true - - '@esbuild/netbsd-arm64@0.27.3': - optional: true - - '@esbuild/netbsd-x64@0.27.3': - optional: true - - '@esbuild/openbsd-arm64@0.27.3': - optional: true - - '@esbuild/openbsd-x64@0.27.3': - optional: true - - '@esbuild/openharmony-arm64@0.27.3': - optional: true - - '@esbuild/sunos-x64@0.27.3': - optional: true - - '@esbuild/win32-arm64@0.27.3': - optional: true - - '@esbuild/win32-ia32@0.27.3': - optional: true - - '@esbuild/win32-x64@0.27.3': - optional: true - - '@eslint-community/eslint-utils@4.9.1(eslint@10.0.3)': - dependencies: - eslint: 10.0.3 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.2': {} - - '@eslint/config-array@0.23.3': - dependencies: - '@eslint/object-schema': 3.0.3 - debug: 4.4.3 - minimatch: 10.2.4 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.5.3': - dependencies: - '@eslint/core': 1.1.1 - - '@eslint/core@1.1.1': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/js@10.0.1(eslint@10.0.3)': - optionalDependencies: - eslint: 10.0.3 - - '@eslint/object-schema@3.0.3': {} - - '@eslint/plugin-kit@0.6.1': - dependencies: - '@eslint/core': 1.1.1 - levn: 0.4.1 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.7': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.4.3 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.4.3': {} - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@rollup/rollup-android-arm-eabi@4.59.0': - optional: true - - '@rollup/rollup-android-arm64@4.59.0': - optional: true - - '@rollup/rollup-darwin-arm64@4.59.0': - optional: true - - '@rollup/rollup-darwin-x64@4.59.0': - optional: true - - '@rollup/rollup-freebsd-arm64@4.59.0': - optional: true - - '@rollup/rollup-freebsd-x64@4.59.0': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.59.0': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.59.0': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.59.0': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.59.0': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.59.0': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.59.0': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.59.0': - optional: true - - '@rollup/rollup-linux-x64-musl@4.59.0': - optional: true - - '@rollup/rollup-openbsd-x64@4.59.0': - optional: true - - '@rollup/rollup-openharmony-arm64@4.59.0': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.59.0': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.59.0': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.59.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.59.0': - optional: true - - '@standard-schema/spec@1.1.0': {} - - '@types/chai@5.2.3': - dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 - - '@types/deep-eql@4.0.2': {} - - '@types/esrecurse@4.3.1': {} - - '@types/estree@1.0.8': {} - - '@types/json-schema@7.0.15': {} - - '@types/node@25.4.0': - dependencies: - undici-types: 7.18.2 - - '@typescript-eslint/eslint-plugin@8.57.0(@typescript-eslint/parser@8.57.0(eslint@10.0.3)(typescript@5.9.3))(eslint@10.0.3)(typescript@5.9.3)': - dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.0(eslint@10.0.3)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/type-utils': 8.57.0(eslint@10.0.3)(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@10.0.3)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.0 - eslint: 10.0.3 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.57.0(eslint@10.0.3)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.57.0 - debug: 4.4.3 - eslint: 10.0.3 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.57.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) - '@typescript-eslint/types': 8.57.0 - debug: 4.4.3 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.57.0': - dependencies: - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/visitor-keys': 8.57.0 - - '@typescript-eslint/tsconfig-utils@8.57.0(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 - - '@typescript-eslint/type-utils@8.57.0(eslint@10.0.3)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.57.0(eslint@10.0.3)(typescript@5.9.3) - debug: 4.4.3 - eslint: 10.0.3 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.57.0': {} - - '@typescript-eslint/typescript-estree@8.57.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.57.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.57.0(typescript@5.9.3) - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/visitor-keys': 8.57.0 - debug: 4.4.3 - minimatch: 10.2.4 - semver: 7.7.4 - tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.57.0(eslint@10.0.3)(typescript@5.9.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3) - '@typescript-eslint/scope-manager': 8.57.0 - '@typescript-eslint/types': 8.57.0 - '@typescript-eslint/typescript-estree': 8.57.0(typescript@5.9.3) - eslint: 10.0.3 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.57.0': - dependencies: - '@typescript-eslint/types': 8.57.0 - eslint-visitor-keys: 5.0.1 - - '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@types/node@25.4.0))': - dependencies: - '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.18 - ast-v8-to-istanbul: 0.3.12 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.2.0 - magicast: 0.5.2 - obug: 2.1.1 - std-env: 3.10.0 - tinyrainbow: 3.0.3 - vitest: 4.0.18(@types/node@25.4.0) - - '@vitest/expect@4.0.18': - dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 - chai: 6.2.2 - tinyrainbow: 3.0.3 - - '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.4.0))': - dependencies: - '@vitest/spy': 4.0.18 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 7.3.1(@types/node@25.4.0) - - '@vitest/pretty-format@4.0.18': - dependencies: - tinyrainbow: 3.0.3 - - '@vitest/runner@4.0.18': - dependencies: - '@vitest/utils': 4.0.18 - pathe: 2.0.3 - - '@vitest/snapshot@4.0.18': - dependencies: - '@vitest/pretty-format': 4.0.18 - magic-string: 0.30.21 - pathe: 2.0.3 - - '@vitest/spy@4.0.18': {} - - '@vitest/utils@4.0.18': - dependencies: - '@vitest/pretty-format': 4.0.18 - tinyrainbow: 3.0.3 - - acorn-jsx@5.3.2(acorn@8.16.0): - dependencies: - acorn: 8.16.0 - - acorn@8.16.0: {} - - ajv@6.14.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - any-promise@1.3.0: {} - - assertion-error@2.0.1: {} - - ast-v8-to-istanbul@0.3.12: - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - estree-walker: 3.0.3 - js-tokens: 10.0.0 - - asynckit@0.4.0: {} - - axios@1.13.6: - dependencies: - follow-redirects: 1.15.11 - form-data: 4.0.5 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - balanced-match@4.0.4: {} - - brace-expansion@5.0.4: - dependencies: - balanced-match: 4.0.4 - - bundle-require@5.1.0(esbuild@0.27.3): - dependencies: - esbuild: 0.27.3 - load-tsconfig: 0.2.5 - - cac@6.7.14: {} - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - chai@6.2.2: {} - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - commander@4.1.1: {} - - confbox@0.1.8: {} - - consola@3.4.2: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - deep-is@0.1.4: {} - - delayed-stream@1.0.0: {} - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-module-lexer@1.7.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - esbuild@0.27.3: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.3 - '@esbuild/android-arm': 0.27.3 - '@esbuild/android-arm64': 0.27.3 - '@esbuild/android-x64': 0.27.3 - '@esbuild/darwin-arm64': 0.27.3 - '@esbuild/darwin-x64': 0.27.3 - '@esbuild/freebsd-arm64': 0.27.3 - '@esbuild/freebsd-x64': 0.27.3 - '@esbuild/linux-arm': 0.27.3 - '@esbuild/linux-arm64': 0.27.3 - '@esbuild/linux-ia32': 0.27.3 - '@esbuild/linux-loong64': 0.27.3 - '@esbuild/linux-mips64el': 0.27.3 - '@esbuild/linux-ppc64': 0.27.3 - '@esbuild/linux-riscv64': 0.27.3 - '@esbuild/linux-s390x': 0.27.3 - '@esbuild/linux-x64': 0.27.3 - '@esbuild/netbsd-arm64': 0.27.3 - '@esbuild/netbsd-x64': 0.27.3 - '@esbuild/openbsd-arm64': 0.27.3 - '@esbuild/openbsd-x64': 0.27.3 - '@esbuild/openharmony-arm64': 0.27.3 - '@esbuild/sunos-x64': 0.27.3 - '@esbuild/win32-arm64': 0.27.3 - '@esbuild/win32-ia32': 0.27.3 - '@esbuild/win32-x64': 0.27.3 - - escape-string-regexp@4.0.0: {} - - eslint-scope@9.1.2: - dependencies: - '@types/esrecurse': 4.3.1 - '@types/estree': 1.0.8 - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@5.0.1: {} - - eslint@10.0.3: - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3) - '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.23.3 - '@eslint/config-helpers': 0.5.3 - '@eslint/core': 1.1.1 - '@eslint/plugin-kit': 0.6.1 - '@humanfs/node': 0.16.7 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - ajv: 6.14.0 - cross-spawn: 7.0.6 - debug: 4.4.3 - escape-string-regexp: 4.0.0 - eslint-scope: 9.1.2 - eslint-visitor-keys: 5.0.1 - espree: 11.2.0 - esquery: 1.7.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - minimatch: 10.2.4 - natural-compare: 1.4.0 - optionator: 0.9.4 - transitivePeerDependencies: - - supports-color - - espree@11.2.0: - dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) - eslint-visitor-keys: 5.0.1 - - esquery@1.7.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.8 - - esutils@2.0.3: {} - - expect-type@1.3.0: {} - - fast-deep-equal@3.1.3: {} - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fdir@6.5.0(picomatch@4.0.4): - optionalDependencies: - picomatch: 4.0.4 - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - fix-dts-default-cjs-exports@1.0.1: - dependencies: - magic-string: 0.30.21 - mlly: 1.8.1 - rollup: 4.59.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.4.2 - keyv: 4.5.4 - - flatted@3.4.2: {} - - follow-redirects@1.15.11: {} - - form-data@4.0.5: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.2 - mime-types: 2.1.35 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - gopd@1.2.0: {} - - has-flag@4.0.0: {} - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - html-escaper@2.0.2: {} - - ignore@5.3.2: {} - - ignore@7.0.5: {} - - imurmurhash@0.1.4: {} - - is-extglob@2.1.1: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - isexe@2.0.0: {} - - istanbul-lib-coverage@3.2.2: {} - - istanbul-lib-report@3.0.1: - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - - istanbul-reports@3.2.0: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - - joycon@3.1.1: {} - - js-tokens@10.0.0: {} - - json-buffer@3.0.1: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - lilconfig@3.1.3: {} - - lines-and-columns@1.2.4: {} - - load-tsconfig@0.2.5: {} - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - magicast@0.5.2: - dependencies: - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - source-map-js: 1.2.1 - - make-dir@4.0.0: - dependencies: - semver: 7.7.4 - - math-intrinsics@1.1.0: {} - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - minimatch@10.2.4: - dependencies: - brace-expansion: 5.0.4 - - mlly@1.8.1: - dependencies: - acorn: 8.16.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.3 - - ms@2.1.3: {} - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - nanoid@3.3.11: {} - - natural-compare@1.4.0: {} - - object-assign@4.1.1: {} - - obug@2.1.1: {} - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - pathe@2.0.3: {} - - picocolors@1.1.1: {} - - picomatch@4.0.4: {} - - pirates@4.0.7: {} - - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.8.1 - pathe: 2.0.3 - - postcss-load-config@6.0.1(postcss@8.5.8): - dependencies: - lilconfig: 3.1.3 - optionalDependencies: - postcss: 8.5.8 - - postcss@8.5.8: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - prelude-ls@1.2.1: {} - - proxy-from-env@1.1.0: {} - - punycode@2.3.1: {} - - readdirp@4.1.2: {} - - resolve-from@5.0.0: {} - - rollup@4.59.0: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.59.0 - '@rollup/rollup-android-arm64': 4.59.0 - '@rollup/rollup-darwin-arm64': 4.59.0 - '@rollup/rollup-darwin-x64': 4.59.0 - '@rollup/rollup-freebsd-arm64': 4.59.0 - '@rollup/rollup-freebsd-x64': 4.59.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 - '@rollup/rollup-linux-arm-musleabihf': 4.59.0 - '@rollup/rollup-linux-arm64-gnu': 4.59.0 - '@rollup/rollup-linux-arm64-musl': 4.59.0 - '@rollup/rollup-linux-loong64-gnu': 4.59.0 - '@rollup/rollup-linux-loong64-musl': 4.59.0 - '@rollup/rollup-linux-ppc64-gnu': 4.59.0 - '@rollup/rollup-linux-ppc64-musl': 4.59.0 - '@rollup/rollup-linux-riscv64-gnu': 4.59.0 - '@rollup/rollup-linux-riscv64-musl': 4.59.0 - '@rollup/rollup-linux-s390x-gnu': 4.59.0 - '@rollup/rollup-linux-x64-gnu': 4.59.0 - '@rollup/rollup-linux-x64-musl': 4.59.0 - '@rollup/rollup-openbsd-x64': 4.59.0 - '@rollup/rollup-openharmony-arm64': 4.59.0 - '@rollup/rollup-win32-arm64-msvc': 4.59.0 - '@rollup/rollup-win32-ia32-msvc': 4.59.0 - '@rollup/rollup-win32-x64-gnu': 4.59.0 - '@rollup/rollup-win32-x64-msvc': 4.59.0 - fsevents: 2.3.3 - - semver@7.7.4: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - siginfo@2.0.0: {} - - source-map-js@1.2.1: {} - - source-map@0.7.6: {} - - stackback@0.0.2: {} - - std-env@3.10.0: {} - - sucrase@3.35.1: - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - commander: 4.1.1 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.7 - tinyglobby: 0.2.15 - ts-interface-checker: 0.1.13 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - tinybench@2.9.0: {} - - tinyexec@0.3.2: {} - - tinyexec@1.0.2: {} - - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - - tinyrainbow@3.0.3: {} - - tree-kill@1.2.2: {} - - ts-api-utils@2.4.0(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - - ts-interface-checker@0.1.13: {} - - tsup@8.5.1(postcss@8.5.8)(typescript@5.9.3): - dependencies: - bundle-require: 5.1.0(esbuild@0.27.3) - cac: 6.7.14 - chokidar: 4.0.3 - consola: 3.4.2 - debug: 4.4.3 - esbuild: 0.27.3 - fix-dts-default-cjs-exports: 1.0.1 - joycon: 3.1.1 - picocolors: 1.1.1 - postcss-load-config: 6.0.1(postcss@8.5.8) - resolve-from: 5.0.0 - rollup: 4.59.0 - source-map: 0.7.6 - sucrase: 3.35.1 - tinyexec: 0.3.2 - tinyglobby: 0.2.15 - tree-kill: 1.2.2 - optionalDependencies: - postcss: 8.5.8 - typescript: 5.9.3 - transitivePeerDependencies: - - jiti - - supports-color - - tsx - - yaml - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - typescript@5.9.3: {} - - ufo@1.6.3: {} - - undici-types@7.18.2: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - vite@7.3.1(@types/node@25.4.0): - dependencies: - esbuild: 0.27.3 - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - postcss: 8.5.8 - rollup: 4.59.0 - tinyglobby: 0.2.15 - optionalDependencies: - '@types/node': 25.4.0 - fsevents: 2.3.3 - - vitest@4.0.18(@types/node@25.4.0): - dependencies: - '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.4.0)) - '@vitest/pretty-format': 4.0.18 - '@vitest/runner': 4.0.18 - '@vitest/snapshot': 4.0.18 - '@vitest/spy': 4.0.18 - '@vitest/utils': 4.0.18 - es-module-lexer: 1.7.0 - expect-type: 1.3.0 - magic-string: 0.30.21 - obug: 2.1.1 - pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 3.10.0 - tinybench: 2.9.0 - tinyexec: 1.0.2 - tinyglobby: 0.2.15 - tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.4.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 25.4.0 - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - yaml - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - - word-wrap@1.2.5: {} - - yocto-queue@0.1.0: {} diff --git a/sdks/nodejs-client/pnpm-workspace.yaml b/sdks/nodejs-client/pnpm-workspace.yaml deleted file mode 100644 index efc037aa84..0000000000 --- a/sdks/nodejs-client/pnpm-workspace.yaml +++ /dev/null @@ -1,2 +0,0 @@ -onlyBuiltDependencies: - - esbuild diff --git a/sdks/nodejs-client/scripts/publish.sh b/sdks/nodejs-client/scripts/publish.sh index 043cac046d..5f8e73f8c0 100755 --- a/sdks/nodejs-client/scripts/publish.sh +++ b/sdks/nodejs-client/scripts/publish.sh @@ -5,10 +5,12 @@ # A beautiful and reliable script to publish the SDK to npm # # Usage: -# ./scripts/publish.sh # Normal publish +# ./scripts/publish.sh # Normal publish # ./scripts/publish.sh --dry-run # Test without publishing # ./scripts/publish.sh --skip-tests # Skip tests (not recommended) # +# This script requires pnpm because the workspace uses catalog: dependencies. +# set -euo pipefail @@ -62,11 +64,27 @@ divider() { echo -e "${DIM}─────────────────────────────────────────────────────────────────${NC}" } +run_npm() { + env \ + -u npm_config_npm_globalconfig \ + -u NPM_CONFIG_NPM_GLOBALCONFIG \ + -u npm_config_verify_deps_before_run \ + -u NPM_CONFIG_VERIFY_DEPS_BEFORE_RUN \ + -u npm_config__jsr_registry \ + -u NPM_CONFIG__JSR_REGISTRY \ + -u npm_config_catalog \ + -u NPM_CONFIG_CATALOG \ + -u npm_config_overrides \ + -u NPM_CONFIG_OVERRIDES \ + npm "$@" +} + # ============================================================================ # Configuration # ============================================================================ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || (cd "$SCRIPT_DIR/../../.." && pwd))" DRY_RUN=false SKIP_TESTS=false @@ -123,23 +141,23 @@ main() { error "npm is not installed" exit 1 fi - NPM_VERSION=$(npm -v) + NPM_VERSION=$(run_npm -v) success "npm: v$NPM_VERSION" - # Check pnpm (optional, for local dev) - if command -v pnpm &> /dev/null; then - PNPM_VERSION=$(pnpm -v) - success "pnpm: v$PNPM_VERSION" - else - info "pnpm not found (optional)" + if ! command -v pnpm &> /dev/null; then + error "pnpm is required because this workspace publishes catalog: dependencies" + info "Install pnpm with Corepack: corepack enable" + exit 1 fi + PNPM_VERSION=$(pnpm -v) + success "pnpm: v$PNPM_VERSION" # Check npm login status - if ! npm whoami &> /dev/null; then + if ! run_npm whoami &> /dev/null; then error "Not logged in to npm. Run 'npm login' first." exit 1 fi - NPM_USER=$(npm whoami) + NPM_USER=$(run_npm whoami) success "Logged in as: ${BOLD}$NPM_USER${NC}" # ======================================================================== @@ -154,11 +172,11 @@ main() { success "Version: ${BOLD}$PACKAGE_VERSION${NC}" # Check if version already exists on npm - if npm view "$PACKAGE_NAME@$PACKAGE_VERSION" version &> /dev/null; then + if run_npm view "$PACKAGE_NAME@$PACKAGE_VERSION" version &> /dev/null; then error "Version $PACKAGE_VERSION already exists on npm!" echo "" info "Current published versions:" - npm view "$PACKAGE_NAME" versions --json 2>/dev/null | tail -5 + run_npm view "$PACKAGE_NAME" versions --json 2>/dev/null | tail -5 echo "" warning "Please update the version in package.json before publishing." exit 1 @@ -170,11 +188,7 @@ main() { # ======================================================================== step "Step 3/6: Installing dependencies..." - if command -v pnpm &> /dev/null; then - pnpm install --frozen-lockfile 2>/dev/null || pnpm install - else - npm ci 2>/dev/null || npm install - fi + pnpm --dir "$REPO_ROOT" install --frozen-lockfile 2>/dev/null || pnpm --dir "$REPO_ROOT" install success "Dependencies installed" # ======================================================================== @@ -185,11 +199,7 @@ main() { if [[ "$SKIP_TESTS" == true ]]; then warning "Skipping tests (--skip-tests flag)" else - if command -v pnpm &> /dev/null; then - pnpm test - else - npm test - fi + pnpm test success "All tests passed" fi @@ -201,11 +211,7 @@ main() { # Clean previous build rm -rf dist - if command -v pnpm &> /dev/null; then - pnpm run build - else - npm run build - fi + pnpm run build success "Build completed" # Verify build output @@ -223,15 +229,32 @@ main() { # Step 6: Publish # ======================================================================== step "Step 6/6: Publishing to npm..." - + + PACK_DIR="$(mktemp -d)" + trap 'rm -rf "$PACK_DIR"' EXIT + + pnpm pack --pack-destination "$PACK_DIR" >/dev/null + PACKAGE_TARBALL="$(find "$PACK_DIR" -maxdepth 1 -name '*.tgz' | head -n 1)" + + if [[ -z "$PACKAGE_TARBALL" ]]; then + error "Pack failed - no tarball generated" + exit 1 + fi + + if tar -xOf "$PACKAGE_TARBALL" package/package.json | grep -q '"catalog:'; then + error "Packed manifest still contains catalog: references" + exit 1 + fi + divider echo -e "${CYAN}Package contents:${NC}" - npm pack --dry-run 2>&1 | head -30 + tar -tzf "$PACKAGE_TARBALL" | head -30 divider if [[ "$DRY_RUN" == true ]]; then warning "DRY-RUN: Skipping actual publish" echo "" + info "Packed artifact: $PACKAGE_TARBALL" info "To publish for real, run without --dry-run flag" else echo "" @@ -239,7 +262,7 @@ main() { echo -e "${DIM}Press Enter to continue, or Ctrl+C to cancel...${NC}" read -r - npm publish --access public + pnpm publish --access public --no-git-checks echo "" success "🎉 Successfully published ${BOLD}$PACKAGE_NAME@$PACKAGE_VERSION${NC} to npm!" diff --git a/web/taze.config.js b/taze.config.js similarity index 95% rename from web/taze.config.js rename to taze.config.js index 7ffd76f94e..d21756e207 100644 --- a/web/taze.config.js +++ b/taze.config.js @@ -10,6 +10,7 @@ export default defineConfig({ // We can not upgrade these yet 'tailwind-merge', 'tailwindcss', + 'typescript', ], write: true, diff --git a/web/.dockerignore b/web/.dockerignore deleted file mode 100644 index 91437a2259..0000000000 --- a/web/.dockerignore +++ /dev/null @@ -1,32 +0,0 @@ -.env -.env.* - -# Logs -logs -*.log* - -# node -node_modules -dist -build -coverage -.husky -.next -.pnpm-store - -# vscode -.vscode - -# webstorm -.idea -*.iml -*.iws -*.ipr - - -# Jetbrains -.idea - -# git -.git -.gitignore \ No newline at end of file diff --git a/web/Dockerfile b/web/Dockerfile index b54bae706c..75024db4f3 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -19,21 +19,27 @@ ENV NEXT_PUBLIC_BASE_PATH="$NEXT_PUBLIC_BASE_PATH" # install packages FROM base AS packages -WORKDIR /app/web +WORKDIR /app -COPY package.json pnpm-lock.yaml /app/web/ +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml /app/ +COPY web/package.json /app/web/ +COPY e2e/package.json /app/e2e/ +COPY sdks/nodejs-client/package.json /app/sdks/nodejs-client/ # Use packageManager from package.json RUN corepack install -RUN pnpm install --frozen-lockfile +# Install only the web workspace to keep image builds from pulling in +# unrelated workspace dependencies such as e2e tooling. +RUN pnpm install --filter ./web... --frozen-lockfile # build resources FROM base AS builder -WORKDIR /app/web -COPY --from=packages /app/web/ . +WORKDIR /app +COPY --from=packages /app/ . COPY . . +WORKDIR /app/web ENV NODE_OPTIONS="--max-old-space-size=4096" RUN pnpm build @@ -64,13 +70,13 @@ RUN addgroup -S -g ${dify_uid} dify && \ chown -R dify:dify /app -WORKDIR /app/web +WORKDIR /app -COPY --from=builder --chown=dify:dify /app/web/public ./public +COPY --from=builder --chown=dify:dify /app/web/public ./web/public COPY --from=builder --chown=dify:dify /app/web/.next/standalone ./ -COPY --from=builder --chown=dify:dify /app/web/.next/static ./.next/static +COPY --from=builder --chown=dify:dify /app/web/.next/static ./web/.next/static -COPY --chown=dify:dify --chmod=755 docker/entrypoint.sh ./entrypoint.sh +COPY --chown=dify:dify --chmod=755 web/docker/entrypoint.sh ./entrypoint.sh ARG COMMIT_SHA ENV COMMIT_SHA=${COMMIT_SHA} diff --git a/web/Dockerfile.dockerignore b/web/Dockerfile.dockerignore new file mode 100644 index 0000000000..9801003d89 --- /dev/null +++ b/web/Dockerfile.dockerignore @@ -0,0 +1,34 @@ +** +!package.json +!pnpm-lock.yaml +!pnpm-workspace.yaml +!.nvmrc +!web/ +!web/** +!e2e/ +!e2e/package.json +!sdks/ +!sdks/nodejs-client/ +!sdks/nodejs-client/package.json + +.git +node_modules +.pnpm-store +web/.env +web/.env.* +web/logs +web/*.log* +web/node_modules +web/dist +web/build +web/coverage +web/.husky +web/.next +web/.pnpm-store +web/.vscode +web/.idea +web/*.iml +web/*.iws +web/*.ipr +e2e/node_modules +sdks/nodejs-client/node_modules diff --git a/web/README.md b/web/README.md index 14ca856875..2d69a94dbd 100644 --- a/web/README.md +++ b/web/README.md @@ -24,18 +24,24 @@ For example, use `vp install` instead of `pnpm install` and `vp test` instead of > > Learn more: [Corepack] +Run the following commands from the repository root. + First, install the dependencies: ```bash pnpm install ``` +> [!NOTE] +> JavaScript dependencies are managed by the workspace files at the repository root: `package.json`, `pnpm-lock.yaml`, `pnpm-workspace.yaml`, and `.nvmrc`. +> Install dependencies from the repository root, then run frontend scripts from `web/`. + Then, configure the environment variables. -Create a file named `.env.local` in the current directory and copy the contents from `.env.example`. +Create `web/.env.local` and copy the contents from `web/.env.example`. Modify the values of these environment variables according to your requirements: ```bash -cp .env.example .env.local +cp web/.env.example web/.env.local ``` > [!IMPORTANT] @@ -46,16 +52,16 @@ cp .env.example .env.local Finally, run the development server: ```bash -pnpm run dev +pnpm -C web run dev # or if you are using vinext which provides a better development experience -pnpm run dev:vinext +pnpm -C web run dev:vinext # (optional) start the dev proxy server so that you can use online API in development -pnpm run dev:proxy +pnpm -C web run dev:proxy ``` Open with your browser to see the result. -You can start editing the file under folder `app`. +You can start editing the files under `web/app`. The page auto-updates as you edit the file. ## Deploy @@ -65,19 +71,25 @@ The page auto-updates as you edit the file. First, build the app for production: ```bash -pnpm run build +pnpm -C web run build ``` Then, start the server: ```bash -pnpm run start +pnpm -C web run start +``` + +If you build the Docker image manually, use the repository root as the build context: + +```bash +docker build -f web/Dockerfile -t dify-web . ``` If you want to customize the host and port: ```bash -pnpm run start --port=3001 --host=0.0.0.0 +pnpm -C web run start --port=3001 --host=0.0.0.0 ``` ## Storybook @@ -87,7 +99,7 @@ This project uses [Storybook] for UI component development. To start the storybook server, run: ```bash -pnpm storybook +pnpm -C web storybook ``` Open with your browser to see the result. @@ -112,7 +124,7 @@ We use [Vitest] and [React Testing Library] for Unit Testing. Run test: ```bash -pnpm test +pnpm -C web test ``` > [!NOTE] diff --git a/web/app/components/app/configuration/config/config-audio.spec.tsx b/web/app/components/app/configuration/config/config-audio.spec.tsx index a3e5c7c149..cad0b40b95 100644 --- a/web/app/components/app/configuration/config/config-audio.spec.tsx +++ b/web/app/components/app/configuration/config/config-audio.spec.tsx @@ -1,4 +1,3 @@ -import type { Mock } from 'vitest' import type { FeatureStoreState } from '@/app/components/base/features/store' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' @@ -28,7 +27,7 @@ type SetupOptions = { } let mockFeatureStoreState: FeatureStoreState -let mockSetFeatures: Mock +let mockSetFeatures = vi.fn() const mockStore = { getState: vi.fn<() => FeatureStoreState>(() => mockFeatureStoreState), } diff --git a/web/app/components/app/configuration/config/config-document.spec.tsx b/web/app/components/app/configuration/config/config-document.spec.tsx index 2aa87717fc..300acb7ce7 100644 --- a/web/app/components/app/configuration/config/config-document.spec.tsx +++ b/web/app/components/app/configuration/config/config-document.spec.tsx @@ -1,4 +1,3 @@ -import type { Mock } from 'vitest' import type { FeatureStoreState } from '@/app/components/base/features/store' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' @@ -28,7 +27,7 @@ type SetupOptions = { } let mockFeatureStoreState: FeatureStoreState -let mockSetFeatures: Mock +let mockSetFeatures = vi.fn() const mockStore = { getState: vi.fn<() => FeatureStoreState>(() => mockFeatureStoreState), } diff --git a/web/app/components/app/configuration/config/index.spec.tsx b/web/app/components/app/configuration/config/index.spec.tsx index 875e583397..b24c719b99 100644 --- a/web/app/components/app/configuration/config/index.spec.tsx +++ b/web/app/components/app/configuration/config/index.spec.tsx @@ -1,4 +1,3 @@ -import type { Mock } from 'vitest' import type { ModelConfig, PromptVariable } from '@/models/debug' import type { ToolItem } from '@/types/app' import { render, screen } from '@testing-library/react' @@ -74,10 +73,10 @@ type MockContext = { history: boolean query: boolean } - showHistoryModal: Mock + showHistoryModal: () => void modelConfig: ModelConfig - setModelConfig: Mock - setPrevPromptConfig: Mock + setModelConfig: (modelConfig: ModelConfig) => void + setPrevPromptConfig: (configs: ModelConfig['configs']) => void } const createPromptVariable = (overrides: Partial = {}): PromptVariable => ({ @@ -142,7 +141,7 @@ const createContextValue = (overrides: Partial = {}): MockContext = ...overrides, }) -const mockUseContext = useContextSelector.useContext as Mock +const mockUseContext = vi.mocked(useContextSelector.useContext) const renderConfig = (contextOverrides: Partial = {}) => { const contextValue = createContextValue(contextOverrides) diff --git a/web/app/components/apps/hooks/__tests__/use-dsl-drag-drop.spec.ts b/web/app/components/apps/hooks/__tests__/use-dsl-drag-drop.spec.ts index 58fed4caa8..00e2d69ab2 100644 --- a/web/app/components/apps/hooks/__tests__/use-dsl-drag-drop.spec.ts +++ b/web/app/components/apps/hooks/__tests__/use-dsl-drag-drop.spec.ts @@ -1,16 +1,15 @@ -import type { Mock } from 'vitest' import { act, renderHook } from '@testing-library/react' import { useDSLDragDrop } from '../use-dsl-drag-drop' describe('useDSLDragDrop', () => { let container: HTMLDivElement - let mockOnDSLFileDropped: Mock + let mockOnDSLFileDropped = vi.fn<(file: File) => void>() beforeEach(() => { vi.clearAllMocks() container = document.createElement('div') document.body.appendChild(container) - mockOnDSLFileDropped = vi.fn() + mockOnDSLFileDropped = vi.fn<(file: File) => void>() }) afterEach(() => { diff --git a/web/app/components/base/carousel/__tests__/index.spec.tsx b/web/app/components/base/carousel/__tests__/index.spec.tsx index cc45256937..e409b85757 100644 --- a/web/app/components/base/carousel/__tests__/index.spec.tsx +++ b/web/app/components/base/carousel/__tests__/index.spec.tsx @@ -11,15 +11,15 @@ type EmblaEventName = 'reInit' | 'select' type EmblaListener = (api: MockEmblaApi | undefined) => void type MockEmblaApi = { - scrollPrev: Mock - scrollNext: Mock - scrollTo: Mock - selectedScrollSnap: Mock - canScrollPrev: Mock - canScrollNext: Mock - slideNodes: Mock - on: Mock - off: Mock + scrollPrev: Mock<() => void> + scrollNext: Mock<() => void> + scrollTo: Mock<(index: number) => void> + selectedScrollSnap: Mock<() => number> + canScrollPrev: Mock<() => boolean> + canScrollNext: Mock<() => boolean> + slideNodes: Mock<() => HTMLDivElement[]> + on: Mock<(event: EmblaEventName, callback: EmblaListener) => void> + off: Mock<(event: EmblaEventName, callback: EmblaListener) => void> } let mockCanScrollPrev = false @@ -33,19 +33,19 @@ const mockCarouselRef = vi.fn() const mockedUseEmblaCarousel = vi.mocked(useEmblaCarousel) const createMockEmblaApi = (): MockEmblaApi => ({ - scrollPrev: vi.fn(), - scrollNext: vi.fn(), - scrollTo: vi.fn(), - selectedScrollSnap: vi.fn(() => mockSelectedIndex), - canScrollPrev: vi.fn(() => mockCanScrollPrev), - canScrollNext: vi.fn(() => mockCanScrollNext), - slideNodes: vi.fn(() => - Array.from({ length: mockSlideCount }).fill(document.createElement('div')), + scrollPrev: vi.fn<() => void>(), + scrollNext: vi.fn<() => void>(), + scrollTo: vi.fn<(index: number) => void>(), + selectedScrollSnap: vi.fn<() => number>(() => mockSelectedIndex), + canScrollPrev: vi.fn<() => boolean>(() => mockCanScrollPrev), + canScrollNext: vi.fn<() => boolean>(() => mockCanScrollNext), + slideNodes: vi.fn<() => HTMLDivElement[]>(() => + Array.from({ length: mockSlideCount }, () => document.createElement('div')), ), - on: vi.fn((event: EmblaEventName, callback: EmblaListener) => { + on: vi.fn<(event: EmblaEventName, callback: EmblaListener) => void>((event, callback) => { listeners[event].push(callback) }), - off: vi.fn((event: EmblaEventName, callback: EmblaListener) => { + off: vi.fn<(event: EmblaEventName, callback: EmblaListener) => void>((event, callback) => { listeners[event] = listeners[event].filter(listener => listener !== callback) }), }) diff --git a/web/app/components/billing/upgrade-btn/__tests__/index.spec.tsx b/web/app/components/billing/upgrade-btn/__tests__/index.spec.tsx index 1840f1d33c..7eda24b944 100644 --- a/web/app/components/billing/upgrade-btn/__tests__/index.spec.tsx +++ b/web/app/components/billing/upgrade-btn/__tests__/index.spec.tsx @@ -1,4 +1,3 @@ -import type { Mock } from 'vitest' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import UpgradeBtn from '../index' @@ -14,14 +13,16 @@ vi.mock('@/context/modal-context', () => ({ }), })) +type GtagHandler = (command: string, action: string, payload: { loc: string }) => void + // Typed window accessor for gtag tracking tests -const gtagWindow = window as unknown as Record -let mockGtag: Mock | undefined +const gtagWindow = window as unknown as { gtag?: GtagHandler } +let mockGtag = vi.fn() describe('UpgradeBtn', () => { beforeEach(() => { vi.clearAllMocks() - mockGtag = vi.fn() + mockGtag = vi.fn() gtagWindow.gtag = mockGtag }) diff --git a/web/app/components/datasets/documents/detail/index.tsx b/web/app/components/datasets/documents/detail/index.tsx index 891c177169..cf9aa62fab 100644 --- a/web/app/components/datasets/documents/detail/index.tsx +++ b/web/app/components/datasets/documents/detail/index.tsx @@ -1,8 +1,8 @@ 'use client' import type { FC } from 'react' -import type { DataSourceInfo, FileItem, FullDocumentDetail, LegacyDataSourceInfo } from '@/models/datasets' +import type { DataSourceInfo, DocumentDisplayStatus, FileItem, FullDocumentDetail, LegacyDataSourceInfo } from '@/models/datasets' import * as React from 'react' -import { useMemo, useState } from 'react' +import { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import Divider from '@/app/components/base/divider' import FloatRightContainer from '@/app/components/base/float-right-container' @@ -11,7 +11,7 @@ import Toast from '@/app/components/base/toast' import Metadata from '@/app/components/datasets/metadata/metadata-document' import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' -import { ChunkingMode } from '@/models/datasets' +import { ChunkingMode, DisplayStatusList } from '@/models/datasets' import { useRouter, useSearchParams } from '@/next/navigation' import { useDocumentDetail, useDocumentMetadata, useInvalidDocumentList } from '@/service/knowledge/use-document' import { useCheckSegmentBatchImportProgress, useChildSegmentListKey, useSegmentBatchImport, useSegmentListKey } from '@/service/knowledge/use-segment' @@ -32,6 +32,14 @@ type DocumentDetailProps = { documentId: string } +const NON_TERMINAL_DISPLAY_STATUSES = new Set( + DisplayStatusList.filter(s => s === 'queuing' || s === 'indexing' || s === 'paused'), +) + +const isLegacyDataSourceInfo = (info?: DataSourceInfo): info is LegacyDataSourceInfo => { + return !!info && 'upload_file' in info +} + const DocumentDetail: FC = ({ datasetId, documentId }) => { const router = useRouter() const searchParams = useSearchParams() @@ -89,6 +97,12 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { datasetId, documentId, params: { metadata: 'without' }, + refetchInterval: (query) => { + const status = query.state.data?.display_status + if (!status || NON_TERMINAL_DISPLAY_STATUSES.has(status)) + return 2500 + return false + }, }) const { data: documentMetadata } = useDocumentMetadata({ @@ -97,19 +111,15 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { params: { metadata: 'only' }, }) - const backToPrev = () => { + const backToPrev = useCallback(() => { const queryString = searchParams.toString() const backPath = `/datasets/${datasetId}/documents${queryString ? `?${queryString}` : ''}` router.push(backPath) - } + }, [searchParams, datasetId, router]) const isDetailLoading = !documentDetail && !error - const embedding = ['queuing', 'indexing', 'paused'].includes((documentDetail?.display_status || '').toLowerCase()) - - const isLegacyDataSourceInfo = (info?: DataSourceInfo): info is LegacyDataSourceInfo => { - return !!info && 'upload_file' in info - } + const embedding = NON_TERMINAL_DISPLAY_STATUSES.has(documentDetail?.display_status as DocumentDisplayStatus) const documentUploadFile = useMemo(() => { if (!documentDetail?.data_source_info) @@ -123,7 +133,7 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { const invalidChildChunkList = useInvalid(useChildSegmentListKey) const invalidDocumentList = useInvalidDocumentList(datasetId) - const handleOperate = (operateName?: string) => { + const handleOperate = useCallback((operateName?: string) => { invalidDocumentList() if (operateName === 'delete') { backToPrev() @@ -138,7 +148,7 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { }, 5000) } } - } + }, [invalidDocumentList, backToPrev, detailMutate, invalidChunkList, invalidChildChunkList]) const parentMode = useMemo(() => { return documentDetail?.document_process_rule?.rules?.parent_mode || documentDetail?.dataset_process_rule?.rules?.parent_mode || 'paragraph' @@ -149,19 +159,41 @@ const DocumentDetail: FC = ({ datasetId, documentId }) => { return chunkMode === ChunkingMode.parentChild && parentMode === 'full-doc' }, [documentDetail?.doc_form, parentMode]) + const contextValue = useMemo(() => ({ + datasetId, + documentId, + docForm: documentDetail?.doc_form as ChunkingMode, + parentMode, + }), [datasetId, documentId, documentDetail?.doc_form, parentMode]) + + const statusDetail = useMemo(() => ({ + enabled: documentDetail?.enabled || false, + archived: documentDetail?.archived || false, + id: documentId, + }), [documentDetail?.enabled, documentDetail?.archived, documentId]) + + const operationsDetail = useMemo(() => ({ + name: documentDetail?.name || '', + enabled: documentDetail?.enabled || false, + archived: documentDetail?.archived || false, + id: documentId, + data_source_type: documentDetail?.data_source_type || '', + doc_form: documentDetail?.doc_form || '', + }), [documentDetail?.name, documentDetail?.enabled, documentDetail?.archived, documentId, documentDetail?.data_source_type, documentDetail?.doc_form]) + + const docDetail = useMemo(() => ({ + ...documentDetail, + ...documentMetadata, + doc_type: documentMetadata?.doc_type === 'others' ? '' : documentMetadata?.doc_type, + } as FullDocumentDetail), [documentDetail, documentMetadata]) + const backButtonLabel = t('operation.back', { ns: 'common' }) const metadataToggleLabel = `${showMetadata ? t('operation.close', { ns: 'common' }) : t('operation.view', { ns: 'common' })} ${t('metadata.title', { ns: 'datasetDocuments' })}` return ( - +
diff --git a/web/app/components/workflow/dsl-export-confirm-modal.tsx b/web/app/components/workflow/dsl-export-confirm-modal.tsx index e698de722e..a92698c8b7 100644 --- a/web/app/components/workflow/dsl-export-confirm-modal.tsx +++ b/web/app/components/workflow/dsl-export-confirm-modal.tsx @@ -45,8 +45,8 @@ const DSLExportConfirmModal = ({ - - + + @@ -56,7 +56,7 @@ const DSLExportConfirmModal = ({
{env.name}
-
Secret
+
{t('env.export.secret', { ns: 'workflow' })}
diff --git a/web/app/components/workflow/hooks/__tests__/use-workflow-interactions.spec.tsx b/web/app/components/workflow/hooks/__tests__/use-workflow-interactions.spec.tsx index 457b54e763..95dc3dff00 100644 --- a/web/app/components/workflow/hooks/__tests__/use-workflow-interactions.spec.tsx +++ b/web/app/components/workflow/hooks/__tests__/use-workflow-interactions.spec.tsx @@ -28,7 +28,7 @@ const mockHandleEdgeCancelRunningStatus = vi.hoisted(() => vi.fn()) const mockHandleSyncWorkflowDraft = vi.hoisted(() => vi.fn()) const mockSaveStateToHistory = vi.hoisted(() => vi.fn()) const mockGetLayoutForChildNodes = vi.hoisted(() => vi.fn()) -const mockGetLayoutByDagre = vi.hoisted(() => vi.fn()) +const mockGetLayoutByELK = vi.hoisted(() => vi.fn()) const mockInitialNodes = vi.hoisted(() => vi.fn((nodes: unknown[], _edges: unknown[]) => nodes)) const mockInitialEdges = vi.hoisted(() => vi.fn((edges: unknown[], _nodes: unknown[]) => edges)) @@ -112,7 +112,7 @@ vi.mock('../use-workflow-history', () => ({ vi.mock('../../utils', async importOriginal => ({ ...(await importOriginal()), getLayoutForChildNodes: (...args: unknown[]) => mockGetLayoutForChildNodes(...args), - getLayoutByDagre: (...args: unknown[]) => mockGetLayoutByDagre(...args), + getLayoutByELK: (...args: unknown[]) => mockGetLayoutByELK(...args), initialNodes: (nodes: unknown[], edges: unknown[]) => mockInitialNodes(nodes, edges), initialEdges: (edges: unknown[], nodes: unknown[]) => mockInitialEdges(edges, nodes), })) @@ -203,7 +203,7 @@ describe('use-workflow-interactions exports', () => { ['loop-child', { x: 40, y: 60, width: 100, height: 60 }], ]), }) - mockGetLayoutByDagre.mockResolvedValue({ + mockGetLayoutByELK.mockResolvedValue({ nodes: new Map([ ['loop-node', { x: 10, y: 20, width: 360, height: 260, layer: 0 }], ['top-node', { x: 500, y: 30, width: 240, height: 100, layer: 0 }], diff --git a/web/app/components/workflow/hooks/use-workflow-organize.ts b/web/app/components/workflow/hooks/use-workflow-organize.ts index 284fb2261c..da158a4214 100644 --- a/web/app/components/workflow/hooks/use-workflow-organize.ts +++ b/web/app/components/workflow/hooks/use-workflow-organize.ts @@ -2,7 +2,7 @@ import { useCallback } from 'react' import { useReactFlow, useStoreApi } from 'reactflow' import { useWorkflowStore } from '../store' import { - getLayoutByDagre, + getLayoutByELK, getLayoutForChildNodes, } from '../utils' import { useNodesSyncDraft } from './use-nodes-sync-draft' @@ -49,7 +49,7 @@ export const useWorkflowOrganize = () => { nodes, getContainerSizeChanges(parentNodes, childLayoutsMap), ) - const layout = await getLayoutByDagre(nodesWithUpdatedSizes, edges) + const layout = await getLayoutByELK(nodesWithUpdatedSizes, edges) const nextNodes = applyLayoutToNodes({ nodes: nodesWithUpdatedSizes, layout, diff --git a/web/app/components/workflow/nodes/http/components/edit-body/index.spec.tsx b/web/app/components/workflow/nodes/http/components/edit-body/index.spec.tsx new file mode 100644 index 0000000000..a3078464b8 --- /dev/null +++ b/web/app/components/workflow/nodes/http/components/edit-body/index.spec.tsx @@ -0,0 +1,30 @@ +import { describe, expect, it } from 'vitest' +import { VarType } from '@/app/components/workflow/types' +import { + HTTP_BODY_VARIABLE_TYPES, + isSupportedHttpBodyVariable, +} from './supported-body-vars' + +describe('HTTP body variable support', () => { + it('should include structured variables in the selector', () => { + expect(HTTP_BODY_VARIABLE_TYPES).toEqual([ + VarType.string, + VarType.number, + VarType.secret, + VarType.object, + VarType.arrayNumber, + VarType.arrayString, + VarType.arrayObject, + ]) + }) + + it('should accept object and array object variables', () => { + expect(isSupportedHttpBodyVariable(VarType.object)).toBe(true) + expect(isSupportedHttpBodyVariable(VarType.arrayObject)).toBe(true) + }) + + it('should keep unsupported file variables excluded', () => { + expect(isSupportedHttpBodyVariable(VarType.file)).toBe(false) + expect(isSupportedHttpBodyVariable(VarType.arrayFile)).toBe(false) + }) +}) diff --git a/web/app/components/workflow/nodes/http/components/edit-body/index.tsx b/web/app/components/workflow/nodes/http/components/edit-body/index.tsx index 90c230b6bb..7e44ad5aeb 100644 --- a/web/app/components/workflow/nodes/http/components/edit-body/index.tsx +++ b/web/app/components/workflow/nodes/http/components/edit-body/index.tsx @@ -13,6 +13,7 @@ import VarReferencePicker from '../../../_base/components/variable/var-reference import useAvailableVarList from '../../../_base/hooks/use-available-var-list' import { BodyPayloadValueType, BodyType } from '../../types' import KeyValue from '../key-value' +import { isSupportedHttpBodyVariable } from './supported-body-vars' const UNIQUE_ID_PREFIX = 'key-value-' @@ -58,7 +59,7 @@ const EditBody: FC = ({ const { availableVars, availableNodes } = useAvailableVarList(nodeId, { onlyLeafNodeVar: false, filterVar: (varPayload: Var) => { - return [VarType.string, VarType.number, VarType.secret, VarType.arrayNumber, VarType.arrayString].includes(varPayload.type) + return isSupportedHttpBodyVariable(varPayload.type) }, }) diff --git a/web/app/components/workflow/nodes/http/components/edit-body/supported-body-vars.ts b/web/app/components/workflow/nodes/http/components/edit-body/supported-body-vars.ts new file mode 100644 index 0000000000..416777abfa --- /dev/null +++ b/web/app/components/workflow/nodes/http/components/edit-body/supported-body-vars.ts @@ -0,0 +1,15 @@ +import { VarType } from '@/app/components/workflow/types' + +export const HTTP_BODY_VARIABLE_TYPES: VarType[] = [ + VarType.string, + VarType.number, + VarType.secret, + VarType.object, + VarType.arrayNumber, + VarType.arrayString, + VarType.arrayObject, +] + +export const isSupportedHttpBodyVariable = (type: VarType) => { + return HTTP_BODY_VARIABLE_TYPES.includes(type) +} diff --git a/web/app/components/workflow/utils/__tests__/elk-layout.spec.ts b/web/app/components/workflow/utils/__tests__/elk-layout.spec.ts index 662b380f5d..1a3c52ec2d 100644 --- a/web/app/components/workflow/utils/__tests__/elk-layout.spec.ts +++ b/web/app/components/workflow/utils/__tests__/elk-layout.spec.ts @@ -5,7 +5,7 @@ import { CUSTOM_ITERATION_START_NODE } from '../../nodes/iteration-start/constan import { CUSTOM_LOOP_START_NODE } from '../../nodes/loop-start/constants' import { BlockEnum } from '../../types' -type ElkChild = Record & { id: string, width?: number, height?: number, x?: number, y?: number, children?: ElkChild[], ports?: Array<{ id: string }>, layoutOptions?: Record } +type ElkChild = Record & { id: string, width?: number, height?: number, x?: number, y?: number, children?: ElkChild[], ports?: Array<{ id: string, layoutOptions?: Record }>, layoutOptions?: Record } type ElkGraph = Record & { id: string, children?: ElkChild[], edges?: Array> } let layoutCallArgs: ElkGraph | null = null @@ -32,7 +32,7 @@ vi.mock('elkjs/lib/elk.bundled.js', () => { } }) -const { getLayoutByDagre, getLayoutForChildNodes } = await import('../elk-layout') +const { getLayoutByELK, getLayoutForChildNodes } = await import('../elk-layout') function makeWorkflowNode(overrides: Omit, 'data'> & { data?: Partial & Record } = {}): Node { return createNode({ @@ -51,7 +51,7 @@ beforeEach(() => { mockReturnOverride = null }) -describe('getLayoutByDagre', () => { +describe('getLayoutByELK', () => { it('should return layout for simple linear graph', async () => { const nodes = [ makeWorkflowNode({ id: 'a', data: { type: BlockEnum.Start, title: '', desc: '' } }), @@ -59,7 +59,7 @@ describe('getLayoutByDagre', () => { ] const edges = [makeWorkflowEdge({ source: 'a', target: 'b' })] - const result = await getLayoutByDagre(nodes, edges) + const result = await getLayoutByELK(nodes, edges) expect(result.nodes.size).toBe(2) expect(result.nodes.has('a')).toBe(true) @@ -74,7 +74,7 @@ describe('getLayoutByDagre', () => { makeWorkflowNode({ id: 'child', data: { type: BlockEnum.Code, title: '', desc: '' }, parentId: 'a' }), ] - const result = await getLayoutByDagre(nodes, []) + const result = await getLayoutByELK(nodes, []) expect(result.nodes.size).toBe(1) expect(result.nodes.has('child')).toBe(false) }) @@ -85,7 +85,7 @@ describe('getLayoutByDagre', () => { makeWorkflowNode({ id: 'iter-start', type: CUSTOM_ITERATION_START_NODE, data: { type: BlockEnum.IterationStart, title: '', desc: '' } }), ] - const result = await getLayoutByDagre(nodes, []) + const result = await getLayoutByELK(nodes, []) expect(result.nodes.size).toBe(1) }) @@ -98,7 +98,7 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ source: 'a', target: 'b', data: { isInIteration: true, iteration_id: 'iter-1' } }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) expect(layoutCallArgs!.edges).toHaveLength(0) }) @@ -107,7 +107,7 @@ describe('getLayoutByDagre', () => { Reflect.deleteProperty(node, 'width') Reflect.deleteProperty(node, 'height') - const result = await getLayoutByDagre([node], []) + const result = await getLayoutByELK([node], []) expect(result.nodes.size).toBe(1) const info = result.nodes.get('a')! expect(info.width).toBe(244) @@ -133,13 +133,13 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ id: 'e2', source: 'if-1', target: 'c', sourceHandle: 'false' }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const ifElkNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'if-1')! expect(ifElkNode.ports).toHaveLength(2) expect(ifElkNode.layoutOptions!['elk.portConstraints']).toBe('FIXED_ORDER') }) - it('should use normal node for IfElse with single branch', async () => { + it('should build ports for IfElse even with single branch', async () => { const nodes = [ makeWorkflowNode({ id: 'if-1', @@ -149,9 +149,10 @@ describe('getLayoutByDagre', () => { ] const edges = [makeWorkflowEdge({ source: 'if-1', target: 'b', sourceHandle: 'case-1' })] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const ifElkNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'if-1')! - expect(ifElkNode.ports).toBeUndefined() + expect(ifElkNode.ports).toHaveLength(1) + expect(ifElkNode.ports![0].layoutOptions!['elk.port.side']).toBe('EAST') }) it('should build ports for HumanInput nodes with multiple branches', async () => { @@ -168,12 +169,12 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ id: 'e2', source: 'hi-1', target: 'c', sourceHandle: '__timeout' }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const hiElkNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'hi-1')! expect(hiElkNode.ports).toHaveLength(2) }) - it('should use normal node for HumanInput with single branch', async () => { + it('should build ports for HumanInput even with single branch', async () => { const nodes = [ makeWorkflowNode({ id: 'hi-1', @@ -183,20 +184,21 @@ describe('getLayoutByDagre', () => { ] const edges = [makeWorkflowEdge({ source: 'hi-1', target: 'b', sourceHandle: 'action-1' })] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const hiElkNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'hi-1')! - expect(hiElkNode.ports).toBeUndefined() + expect(hiElkNode.ports).toHaveLength(1) + expect(hiElkNode.ports![0].layoutOptions!['elk.port.side']).toBe('EAST') }) it('should normalise bounds so minX and minY start at 0', async () => { const nodes = [makeWorkflowNode({ id: 'a', data: { type: BlockEnum.Start, title: '', desc: '' } })] - const result = await getLayoutByDagre(nodes, []) + const result = await getLayoutByELK(nodes, []) expect(result.bounds.minX).toBe(0) expect(result.bounds.minY).toBe(0) }) it('should return empty layout when no nodes match filter', async () => { - const result = await getLayoutByDagre([], []) + const result = await getLayoutByELK([], []) expect(result.nodes.size).toBe(0) expect(result.bounds).toEqual({ minX: 0, minY: 0, maxX: 0, maxY: 0 }) }) @@ -225,7 +227,7 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ id: 'e-b', source: 'if-1', target: 'y', sourceHandle: 'case-b' }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const ifNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'if-1')! const portIds = ifNode.ports!.map((p: { id: string }) => p.id) expect(portIds[portIds.length - 1]).toContain('false') @@ -247,7 +249,7 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ id: 'e-a2', source: 'hi-1', target: 'y', sourceHandle: 'a2' }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const hiNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'hi-1')! const portIds = hiNode.ports!.map((p: { id: string }) => p.id) expect(portIds[portIds.length - 1]).toContain('__timeout') @@ -267,7 +269,7 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ id: 'e2', source: 'if-1', target: 'c', sourceHandle: 'false' }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const portEdges = layoutCallArgs!.edges!.filter((e: Record) => e.sourcePort) expect(portEdges.length).toBeGreaterThan(0) }) @@ -286,7 +288,7 @@ describe('getLayoutByDagre', () => { Reflect.deleteProperty(e1, 'sourceHandle') Reflect.deleteProperty(e2, 'sourceHandle') - const result = await getLayoutByDagre(nodes, [e1, e2]) + const result = await getLayoutByELK(nodes, [e1, e2]) expect(result.nodes.size).toBeGreaterThan(0) }) @@ -299,7 +301,7 @@ describe('getLayoutByDagre', () => { }) const nodes = [makeWorkflowNode({ id: 'a', data: { type: BlockEnum.Start, title: '', desc: '' } })] - const result = await getLayoutByDagre(nodes, []) + const result = await getLayoutByELK(nodes, []) const info = result.nodes.get('a')! expect(info.x).toBe(0) expect(info.y).toBe(0) @@ -326,7 +328,7 @@ describe('getLayoutByDagre', () => { makeWorkflowNode({ id: 'a', data: { type: BlockEnum.Start, title: '', desc: '' } }), makeWorkflowNode({ id: 'b', data: { type: BlockEnum.Code, title: '', desc: '' } }), ] - const result = await getLayoutByDagre(nodes, []) + const result = await getLayoutByELK(nodes, []) expect(result.nodes.get('a')!.layer).toBe(0) expect(result.nodes.get('b')!.layer).toBe(1) }) @@ -354,7 +356,7 @@ describe('getLayoutByDagre', () => { makeWorkflowNode({ id: 'nested-1', data: { type: BlockEnum.Code, title: '', desc: '' } }), makeWorkflowNode({ id: 'nested-2', data: { type: BlockEnum.Code, title: '', desc: '' } }), ] - const result = await getLayoutByDagre(nodes, []) + const result = await getLayoutByELK(nodes, []) expect(result.nodes.has('nested-1')).toBe(true) expect(result.nodes.has('nested-2')).toBe(true) }) @@ -372,7 +374,7 @@ describe('getLayoutByDagre', () => { makeWorkflowNode({ id: 'visible', data: { type: BlockEnum.Start, title: '', desc: '' } }), makeWorkflowNode({ id: 'also-visible', data: { type: BlockEnum.Code, title: '', desc: '' } }), ] - const result = await getLayoutByDagre(nodes, []) + const result = await getLayoutByELK(nodes, []) expect(result.nodes.size).toBe(2) }) @@ -390,7 +392,7 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ id: 'e2', source: 'if-1', target: 'c', sourceHandle: 'other-unknown' }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const ifNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'if-1')! expect(ifNode.ports).toHaveLength(2) }) @@ -409,7 +411,7 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ id: 'e2', source: 'hi-1', target: 'c', sourceHandle: 'another-unknown' }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const hiNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'hi-1')! expect(hiNode.ports).toHaveLength(2) }) @@ -428,7 +430,7 @@ describe('getLayoutByDagre', () => { Reflect.deleteProperty(e1, 'sourceHandle') Reflect.deleteProperty(e2, 'sourceHandle') - await getLayoutByDagre(nodes, [e1, e2]) + await getLayoutByELK(nodes, [e1, e2]) const ifNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'if-1')! expect(ifNode.ports).toHaveLength(2) }) @@ -447,7 +449,7 @@ describe('getLayoutByDagre', () => { Reflect.deleteProperty(e1, 'sourceHandle') Reflect.deleteProperty(e2, 'sourceHandle') - await getLayoutByDagre(nodes, [e1, e2]) + await getLayoutByELK(nodes, [e1, e2]) const hiNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'hi-1')! expect(hiNode.ports).toHaveLength(2) }) @@ -463,7 +465,7 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ id: 'e2', source: 'if-1', target: 'c', sourceHandle: 'false' }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const ifNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'if-1')! expect(ifNode.ports).toHaveLength(2) }) @@ -479,7 +481,7 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ id: 'e2', source: 'hi-1', target: 'c', sourceHandle: '__timeout' }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) const hiNode = layoutCallArgs!.children!.find((c: ElkChild) => c.id === 'hi-1')! expect(hiNode.ports).toHaveLength(2) }) @@ -492,7 +494,7 @@ describe('getLayoutByDagre', () => { makeWorkflowEdge({ source: 'x', target: 'y', data: { isInLoop: true, loop_id: 'loop-1' } }), ] - await getLayoutByDagre(nodes, edges) + await getLayoutByELK(nodes, edges) expect(layoutCallArgs!.edges).toHaveLength(0) }) }) diff --git a/web/app/components/workflow/utils/elk-layout.ts b/web/app/components/workflow/utils/elk-layout.ts index 280d0f7b1d..9860bbc770 100644 --- a/web/app/components/workflow/utils/elk-layout.ts +++ b/web/app/components/workflow/utils/elk-layout.ts @@ -18,9 +18,6 @@ import { BlockEnum, } from '@/app/components/workflow/types' -// Although the file name refers to Dagre, the implementation now relies on ELK's layered algorithm. -// Keep the export signatures unchanged to minimise the blast radius while we migrate the layout stack. - const elk = new ELK() const DEFAULT_NODE_WIDTH = 244 @@ -41,7 +38,6 @@ const ROOT_LAYOUT_OPTIONS = { // === Port Configuration === 'elk.portConstraints': 'FIXED_ORDER', 'elk.layered.considerModelOrder.strategy': 'PREFER_EDGES', - 'elk.port.side': 'SOUTH', // === Node Placement - Best quality === 'elk.layered.nodePlacement.strategy': 'NETWORK_SIMPLEX', @@ -278,32 +274,16 @@ const collectLayout = (graph: ElkNode, predicate: (id: string) => boolean): Layo } } -/** - * Build If/Else node with ELK native Ports instead of dummy nodes - * This is the recommended approach for handling multiple branches - */ -const buildIfElseWithPorts = ( - ifElseNode: Node, - edges: Edge[], -): { node: ElkNodeShape, portMap: Map } | null => { - const childEdges = edges.filter(edge => edge.source === ifElseNode.id) - - if (childEdges.length <= 1) - return null - - // Sort child edges according to case order - const sortedChildEdges = [...childEdges].sort((edgeA, edgeB) => { +const sortIfElseOutEdges = (ifElseNode: Node, outEdges: Edge[]): Edge[] => { + return [...outEdges].sort((edgeA, edgeB) => { const handleA = edgeA.sourceHandle const handleB = edgeB.sourceHandle if (handleA && handleB) { const cases = (ifElseNode.data as IfElseNodeType).cases || [] - const isAElse = handleA === 'false' - const isBElse = handleB === 'false' - - if (isAElse) + if (handleA === 'false') return 1 - if (isBElse) + if (handleB === 'false') return -1 const indexA = cases.findIndex((c: CaseItem) => c.case_id === handleA) @@ -315,67 +295,20 @@ const buildIfElseWithPorts = ( return 0 }) - - // Create ELK ports for each branch - const ports: ElkPortShape[] = sortedChildEdges.map((edge, index) => ({ - id: `${ifElseNode.id}-port-${edge.sourceHandle || index}`, - layoutOptions: { - 'port.side': 'EAST', // Ports on the right side (matching 'RIGHT' direction) - 'port.index': String(index), - }, - })) - - // Build port mapping: sourceHandle -> portId - const portMap = new Map() - sortedChildEdges.forEach((edge, index) => { - const portId = `${ifElseNode.id}-port-${edge.sourceHandle || index}` - portMap.set(edge.id, portId) - }) - - return { - node: { - id: ifElseNode.id, - width: ifElseNode.width ?? DEFAULT_NODE_WIDTH, - height: ifElseNode.height ?? DEFAULT_NODE_HEIGHT, - ports, - layoutOptions: { - 'elk.portConstraints': 'FIXED_ORDER', - }, - }, - portMap, - } } -/** - * Build Human Input node with ELK native Ports for multiple branches - * Handles user actions as branches with __timeout as the last fixed branch - */ -const buildHumanInputWithPorts = ( - humanInputNode: Node, - edges: Edge[], -): { node: ElkNodeShape, portMap: Map } | null => { - const childEdges = edges.filter(edge => edge.source === humanInputNode.id) - - if (childEdges.length <= 1) - return null - - // Sort child edges: user actions first (by order), then __timeout last - const sortedChildEdges = [...childEdges].sort((edgeA, edgeB) => { +const sortHumanInputOutEdges = (humanInputNode: Node, outEdges: Edge[]): Edge[] => { + return [...outEdges].sort((edgeA, edgeB) => { const handleA = edgeA.sourceHandle const handleB = edgeB.sourceHandle if (handleA && handleB) { const userActions = (humanInputNode.data as HumanInputNodeType).user_actions || [] - const isATimeout = handleA === '__timeout' - const isBTimeout = handleB === '__timeout' - - // __timeout should always be last - if (isATimeout) + if (handleA === '__timeout') return 1 - if (isBTimeout) + if (handleB === '__timeout') return -1 - // Sort by user_actions order const indexA = userActions.findIndex(action => action.id === handleA) const indexB = userActions.findIndex(action => action.id === handleB) @@ -385,35 +318,6 @@ const buildHumanInputWithPorts = ( return 0 }) - - // Create ELK ports for each branch - const ports: ElkPortShape[] = sortedChildEdges.map((edge, index) => ({ - id: `${humanInputNode.id}-port-${edge.sourceHandle || index}`, - layoutOptions: { - 'port.side': 'EAST', - 'port.index': String(index), - }, - })) - - // Build port mapping: edge.id -> portId - const portMap = new Map() - sortedChildEdges.forEach((edge, index) => { - const portId = `${humanInputNode.id}-port-${edge.sourceHandle || index}` - portMap.set(edge.id, portId) - }) - - return { - node: { - id: humanInputNode.id, - width: humanInputNode.width ?? DEFAULT_NODE_WIDTH, - height: humanInputNode.height ?? DEFAULT_NODE_HEIGHT, - ports, - layoutOptions: { - 'elk.portConstraints': 'FIXED_ORDER', - }, - }, - portMap, - } } const normaliseBounds = (layout: LayoutResult): LayoutResult => { @@ -448,58 +352,87 @@ const normaliseBounds = (layout: LayoutResult): LayoutResult => { } } -export const getLayoutByDagre = async (originNodes: Node[], originEdges: Edge[]): Promise => { +export const getLayoutByELK = async (originNodes: Node[], originEdges: Edge[]): Promise => { edgeCounter = 0 const nodes = cloneDeep(originNodes).filter(node => !node.parentId && node.type === CUSTOM_NODE) const edges = cloneDeep(originEdges).filter(edge => (!edge.data?.isInIteration && !edge.data?.isInLoop)) - const elkNodes: ElkNodeShape[] = [] - const elkEdges: ElkEdgeShape[] = [] - - // Track which edges have been processed for If/Else nodes with ports - const edgeToPortMap = new Map() - - // Build nodes with ports for If/Else and Human Input nodes - nodes.forEach((node) => { - if (node.data.type === BlockEnum.IfElse) { - const portsResult = buildIfElseWithPorts(node, edges) - if (portsResult) { - // Use node with ports - elkNodes.push(portsResult.node) - // Store port mappings for edges - portsResult.portMap.forEach((portId, edgeId) => { - edgeToPortMap.set(edgeId, portId) - }) - } - else { - // No multiple branches, use normal node - elkNodes.push(toElkNode(node)) - } - } - else if (node.data.type === BlockEnum.HumanInput) { - const portsResult = buildHumanInputWithPorts(node, edges) - if (portsResult) { - // Use node with ports - elkNodes.push(portsResult.node) - // Store port mappings for edges - portsResult.portMap.forEach((portId, edgeId) => { - edgeToPortMap.set(edgeId, portId) - }) - } - else { - // No multiple branches, use normal node - elkNodes.push(toElkNode(node)) - } - } - else { - elkNodes.push(toElkNode(node)) - } + const outEdgesByNode = new Map() + const inEdgesByNode = new Map() + edges.forEach((edge) => { + if (!outEdgesByNode.has(edge.source)) + outEdgesByNode.set(edge.source, []) + outEdgesByNode.get(edge.source)!.push(edge) + if (!inEdgesByNode.has(edge.target)) + inEdgesByNode.set(edge.target, []) + inEdgesByNode.get(edge.target)!.push(edge) }) - // Build edges with port connections - edges.forEach((edge) => { - const sourcePort = edgeToPortMap.get(edge.id) - elkEdges.push(createEdge(edge.source, edge.target, sourcePort)) + const elkNodes: ElkNodeShape[] = [] + const elkEdges: ElkEdgeShape[] = [] + const sourcePortMap = new Map() + const targetPortMap = new Map() + const sortedOutEdgesByNode = new Map() + + nodes.forEach((node) => { + const inEdges = inEdgesByNode.get(node.id) || [] + let outEdges = outEdgesByNode.get(node.id) || [] + + if (node.data.type === BlockEnum.IfElse) + outEdges = sortIfElseOutEdges(node, outEdges) + else if (node.data.type === BlockEnum.HumanInput) + outEdges = sortHumanInputOutEdges(node, outEdges) + + sortedOutEdgesByNode.set(node.id, outEdges) + + const ports: ElkPortShape[] = [] + + inEdges.forEach((edge, index) => { + const portId = `${node.id}-in-${index}` + ports.push({ + id: portId, + layoutOptions: { + 'elk.port.side': 'WEST', + 'elk.port.index': String(index), + }, + }) + targetPortMap.set(edge.id, portId) + }) + + outEdges.forEach((edge, index) => { + const portId = `${node.id}-out-${edge.sourceHandle || index}` + ports.push({ + id: portId, + layoutOptions: { + 'elk.port.side': 'EAST', + 'elk.port.index': String(index), + }, + }) + sourcePortMap.set(edge.id, portId) + }) + + elkNodes.push({ + id: node.id, + width: node.width ?? DEFAULT_NODE_WIDTH, + height: node.height ?? DEFAULT_NODE_HEIGHT, + ...(ports.length > 0 && { + ports, + layoutOptions: { 'elk.portConstraints': 'FIXED_ORDER' }, + }), + }) + }) + + // Build edges in sorted per-node order so PREFER_EDGES aligns with port order + nodes.forEach((node) => { + const outEdges = sortedOutEdgesByNode.get(node.id) || [] + outEdges.forEach((edge) => { + elkEdges.push(createEdge( + edge.source, + edge.target, + sourcePortMap.get(edge.id), + targetPortMap.get(edge.id), + )) + }) }) const graph = { diff --git a/web/app/styles/markdown.css b/web/app/styles/markdown.css index 368c3718af..48aaf965ab 100644 --- a/web/app/styles/markdown.css +++ b/web/app/styles/markdown.css @@ -582,6 +582,44 @@ background-color: var(--color-components-menu-item-bg-hover); } +[data-streamdown="table-fullscreen"] { + background-color: var(--color-components-panel-bg); + color: var(--color-text-primary); +} + +[data-streamdown="table-fullscreen"] button { + color: var(--color-text-tertiary); +} + +[data-streamdown="table-fullscreen"] button:hover { + color: var(--color-text-primary); + background-color: var(--color-background-section-burn); +} + +[data-streamdown="table-fullscreen"] table[data-streamdown="table"] { + border-color: var(--color-divider-regular); +} + +[data-streamdown="table-fullscreen"] [data-streamdown="table-header"] { + background-color: var(--color-background-section-burn); +} + +[data-streamdown="table-fullscreen"] [data-streamdown="table-header"] th { + color: var(--color-text-tertiary); +} + +[data-streamdown="table-fullscreen"] [data-streamdown="table-body"] { + border-color: var(--color-divider-subtle); +} + +[data-streamdown="table-fullscreen"] [data-streamdown="table-body"] > tr { + border-color: var(--color-divider-subtle); +} + +[data-streamdown="table-fullscreen"] [data-streamdown="table-body"] td { + color: var(--color-text-secondary); +} + .markdown-body table img { background-color: transparent; } diff --git a/web/eslint-suppressions.json b/web/eslint-suppressions.json index d787164407..7a714f2151 100644 --- a/web/eslint-suppressions.json +++ b/web/eslint-suppressions.json @@ -9,14 +9,6 @@ "count": 1 } }, - "__tests__/check-i18n.test.ts": { - "regexp/no-unused-capturing-group": { - "count": 1 - }, - "ts/no-explicit-any": { - "count": 2 - } - }, "__tests__/document-detail-navigation-fix.test.tsx": { "no-console": { "count": 10 diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index 940aad9f4c..020e960d73 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -56,6 +56,7 @@ export default antfu( }, }, e18e: false, + pnpm: false, }, { plugins: { diff --git a/web/i18n/ar-TN/app-debug.json b/web/i18n/ar-TN/app-debug.json index c35983397a..99c510dcb5 100644 --- a/web/i18n/ar-TN/app-debug.json +++ b/web/i18n/ar-TN/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "تشغيل", "inputs.title": "تصحيح ومعاينة", "inputs.userInputField": "حقل إدخال المستخدم", + "manageModels": "إدارة النماذج", "modelConfig.modeType.chat": "دردشة", "modelConfig.modeType.completion": "إكمال", "modelConfig.model": "نموذج", "modelConfig.setTone": "تعيين نبرة الاستجابات", "modelConfig.title": "النموذج والمعلمات", + "noModelProviderConfigured": "لم يتم تكوين أي مزوّد نماذج", + "noModelProviderConfiguredTip": "قم بتثبيت أو تكوين مزوّد نماذج للبدء.", + "noModelSelected": "لم يتم اختيار أي نموذج", + "noModelSelectedTip": "قم بتكوين نموذج أعلاه للمتابعة.", "noResult": "سيتم عرض الإخراج هنا.", "notSetAPIKey.description": "لم يتم تعيين مفتاح مزود LLM، ويجب تعيينه قبل تصحيح الأخطاء.", "notSetAPIKey.settingBtn": "الذهاب إلى الإعدادات", diff --git a/web/i18n/ar-TN/common.json b/web/i18n/ar-TN/common.json index 74fe80bcff..3bc7c05564 100644 --- a/web/i18n/ar-TN/common.json +++ b/web/i18n/ar-TN/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "غير مصرح به", "modelProvider.buyQuota": "شراء حصة", "modelProvider.callTimes": "أوقات الاتصال", + "modelProvider.card.aiCreditsInUse": "أرصدة الذكاء الاصطناعي قيد الاستخدام", + "modelProvider.card.aiCreditsOption": "أرصدة الذكاء الاصطناعي", + "modelProvider.card.apiKeyOption": "مفتاح API", + "modelProvider.card.apiKeyRequired": "مفتاح API مطلوب", + "modelProvider.card.apiKeyUnavailableFallback": "مفتاح API غير متاح، يتم الآن استخدام أرصدة الذكاء الاصطناعي", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "تحقق من تكوين مفتاح API الخاص بك للتبديل مرة أخرى", "modelProvider.card.buyQuota": "شراء حصة", "modelProvider.card.callTimes": "أوقات الاتصال", + "modelProvider.card.creditsExhaustedDescription": "يرجى ترقية خطتك أو تكوين مفتاح API", + "modelProvider.card.creditsExhaustedFallback": "نفدت أرصدة الذكاء الاصطناعي، يتم الآن استخدام مفتاح API", + "modelProvider.card.creditsExhaustedFallbackDescription": "قم بترقية خطتك لاستئناف أولوية أرصدة الذكاء الاصطناعي.", + "modelProvider.card.creditsExhaustedMessage": "نفدت أرصدة الذكاء الاصطناعي", "modelProvider.card.modelAPI": "نماذج {{modelName}} تستخدم مفتاح API.", "modelProvider.card.modelNotSupported": "نماذج {{modelName}} غير مثبتة.", "modelProvider.card.modelSupported": "نماذج {{modelName}} تستخدم هذا الحصة.", + "modelProvider.card.noApiKeysDescription": "أضف مفتاح API لبدء استخدام بيانات اعتماد النموذج الخاصة بك.", + "modelProvider.card.noApiKeysFallback": "لا توجد مفاتيح API، يتم استخدام أرصدة الذكاء الاصطناعي بدلاً من ذلك", + "modelProvider.card.noApiKeysTitle": "لم يتم تكوين أي مفاتيح API بعد", + "modelProvider.card.noAvailableUsage": "لا يوجد استخدام متاح", "modelProvider.card.onTrial": "في التجربة", "modelProvider.card.paid": "مدفوع", "modelProvider.card.priorityUse": "أولوية الاستخدام", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "إزالة مفتاح API", "modelProvider.card.tip": "تدعم أرصدة الرسائل نماذج من {{modelNames}}. ستعطى الأولوية للحصة المدفوعة. سيتم استخدام الحصة المجانية بعد نفاد الحصة المدفوعة.", "modelProvider.card.tokens": "رموز", + "modelProvider.card.unavailable": "غير متاح", + "modelProvider.card.upgradePlan": "ترقية خطتك", + "modelProvider.card.usageLabel": "الاستخدام", + "modelProvider.card.usagePriority": "أولوية الاستخدام", + "modelProvider.card.usagePriorityTip": "تعيين المورد الذي يجب استخدامه أولاً عند تشغيل النماذج.", "modelProvider.collapse": "طي", "modelProvider.config": "تكوين", "modelProvider.configLoadBalancing": "تكوين موازنة التحميل", @@ -387,9 +406,11 @@ "modelProvider.model": "النموذج", "modelProvider.modelAndParameters": "النموذج والمعلمات", "modelProvider.modelHasBeenDeprecated": "تم إهمال هذا النموذج", + "modelProvider.modelSettings": "إعدادات النموذج", "modelProvider.models": "النماذج", "modelProvider.modelsNum": "{{num}} نماذج", "modelProvider.noModelFound": "لم يتم العثور على نموذج لـ {{model}}", + "modelProvider.noneConfigured": "قم بتكوين نموذج نظام افتراضي لتشغيل التطبيقات", "modelProvider.notConfigured": "لم يتم تكوين نموذج النظام بالكامل بعد", "modelProvider.parameters": "المعلمات", "modelProvider.parametersInvalidRemoved": "بعض المعلمات غير صالحة وتمت إزالتها", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "إعادة التعيين في {{date}}", "modelProvider.searchModel": "نموذج البحث", "modelProvider.selectModel": "اختر نموذجك", + "modelProvider.selector.aiCredits": "أرصدة الذكاء الاصطناعي", + "modelProvider.selector.apiKeyUnavailable": "مفتاح API غير متاح", + "modelProvider.selector.apiKeyUnavailableTip": "تمت إزالة مفتاح API. يرجى تكوين مفتاح API جديد.", + "modelProvider.selector.configure": "تكوين", + "modelProvider.selector.configureRequired": "التكوين مطلوب", + "modelProvider.selector.creditsExhausted": "نفدت الأرصدة", + "modelProvider.selector.creditsExhaustedTip": "نفدت أرصدة الذكاء الاصطناعي الخاصة بك. يرجى ترقية خطتك أو إضافة مفتاح API.", + "modelProvider.selector.disabled": "معطل", + "modelProvider.selector.discoverMoreInMarketplace": "اكتشف المزيد في السوق", "modelProvider.selector.emptySetting": "يرجى الانتقال إلى الإعدادات للتكوين", "modelProvider.selector.emptyTip": "لا توجد نماذج متاحة", + "modelProvider.selector.fromMarketplace": "من السوق", + "modelProvider.selector.incompatible": "غير متوافق", + "modelProvider.selector.incompatibleTip": "هذا النموذج غير متاح في الإصدار الحالي. يرجى تحديد نموذج متاح آخر.", + "modelProvider.selector.install": "تثبيت", + "modelProvider.selector.modelProviderSettings": "إعدادات مزود النموذج", + "modelProvider.selector.noProviderConfigured": "لم يتم تكوين أي مزود نموذج", + "modelProvider.selector.noProviderConfiguredDesc": "تصفح السوق لتثبيت مزود، أو قم بتكوين المزودين في الإعدادات.", + "modelProvider.selector.onlyCompatibleModelsShown": "يتم عرض النماذج المتوافقة فقط", "modelProvider.selector.rerankTip": "يرجى إعداد نموذج إعادة الترتيب", "modelProvider.selector.tip": "تمت إزالة هذا النموذج. يرجى إضافة نموذج أو تحديد نموذج آخر.", "modelProvider.setupModelFirst": "يرجى إعداد نموذجك أولاً", diff --git a/web/i18n/ar-TN/plugin.json b/web/i18n/ar-TN/plugin.json index 39052f4295..c48a15fb24 100644 --- a/web/i18n/ar-TN/plugin.json +++ b/web/i18n/ar-TN/plugin.json @@ -3,6 +3,7 @@ "action.delete": "إزالة الإضافة", "action.deleteContentLeft": "هل ترغب في إزالة ", "action.deleteContentRight": " الإضافة؟", + "action.deleteSuccess": "تم حذف الإضافة بنجاح", "action.pluginInfo": "معلومات الإضافة", "action.usedInApps": "يتم استخدام هذه الإضافة في {{num}} تطبيقات.", "allCategories": "جميع الفئات", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "تثبيت", "detailPanel.operation.remove": "إزالة", "detailPanel.operation.update": "تحديث", + "detailPanel.operation.updateTooltip": "قم بالتحديث للوصول إلى أحدث النماذج.", "detailPanel.operation.viewDetail": "عرض التفاصيل", "detailPanel.serviceOk": "الخدمة جيدة", "detailPanel.strategyNum": "{{num}} {{strategy}} متضمن", @@ -231,12 +233,18 @@ "source.local": "ملف الحزمة المحلية", "source.marketplace": "السوق", "task.clearAll": "مسح الكل", + "task.errorMsg.github": "لم يتم تثبيت هذه الإضافة تلقائيًا.\nيرجى تثبيتها من GitHub.", + "task.errorMsg.marketplace": "لم يتم تثبيت هذه الإضافة تلقائيًا.\nيرجى تثبيتها من السوق.", + "task.errorMsg.unknown": "لم يتم تثبيت هذه الإضافة.\nتعذر التعرف على مصدر الإضافة.", "task.errorPlugins": "فشل في تثبيت الإضافات", "task.installError": "{{errorLength}} إضافات فشل تثبيتها، انقر للعرض", + "task.installFromGithub": "التثبيت من GitHub", + "task.installFromMarketplace": "التثبيت من السوق", "task.installSuccess": "تم تثبيت {{successLength}} من الإضافات بنجاح", "task.installed": "مثبت", "task.installedError": "{{errorLength}} إضافات فشل تثبيتها", "task.installing": "جارٍ تثبيت الإضافات.", + "task.installingHint": "جارٍ التثبيت... قد يستغرق هذا بضع دقائق.", "task.installingWithError": "تثبيت {{installingLength}} إضافات، {{successLength}} نجاح، {{errorLength}} فشل", "task.installingWithSuccess": "تثبيت {{installingLength}} إضافات، {{successLength}} نجاح.", "task.runningPlugins": "تثبيت الإضافات", diff --git a/web/i18n/ar-TN/workflow.json b/web/i18n/ar-TN/workflow.json index 1bb5237ff7..2487538071 100644 --- a/web/i18n/ar-TN/workflow.json +++ b/web/i18n/ar-TN/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "تحديث سير العمل", "error.startNodeRequired": "الرجاء إضافة عقدة البداية أولاً قبل {{operation}}", "errorMsg.authRequired": "الترخيص مطلوب", + "errorMsg.configureModel": "قم بتكوين نموذج", "errorMsg.fieldRequired": "{{field}} مطلوب", "errorMsg.fields.code": "الكود", "errorMsg.fields.model": "النموذج", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "متغير الرؤية", "errorMsg.invalidJson": "{{field}} هو JSON غير صالح", "errorMsg.invalidVariable": "متغير غير صالح", + "errorMsg.modelPluginNotInstalled": "متغير غير صالح. قم بتكوين نموذج لتمكين هذا المتغير.", "errorMsg.noValidTool": "{{field}} لا توجد أداة صالحة محددة", "errorMsg.rerankModelRequired": "مطلوب تكوين نموذج Rerank", "errorMsg.startNodeRequired": "الرجاء إضافة عقدة البداية أولاً قبل {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "حجم النافذة", "nodes.common.outputVars": "متغيرات الإخراج", "nodes.common.pluginNotInstalled": "الإضافة غير مثبتة", + "nodes.common.pluginsNotInstalled": "{{count}} إضافات غير مثبتة", "nodes.common.retry.maxRetries": "الحد الأقصى لإعادة المحاولة", "nodes.common.retry.ms": "مللي ثانية", "nodes.common.retry.retries": "{{num}} إعادة محاولة", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "القطع", "nodes.knowledgeBase.chunksInputTip": "متغير الإدخال لعقدة قاعدة المعرفة هو Pieces. نوع المتغير هو كائن بمخطط JSON محدد يجب أن يكون متسقًا مع هيكل القطعة المحدد.", "nodes.knowledgeBase.chunksVariableIsRequired": "متغير القطع مطلوب", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "مفتاح API غير متاح", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "نفدت الأرصدة", + "nodes.knowledgeBase.embeddingModelIncompatible": "غير متوافق", "nodes.knowledgeBase.embeddingModelIsInvalid": "نموذج التضمين غير صالح", "nodes.knowledgeBase.embeddingModelIsRequired": "نموذج التضمين مطلوب", + "nodes.knowledgeBase.embeddingModelNotConfigured": "نموذج التضمين غير مكوّن", "nodes.knowledgeBase.indexMethodIsRequired": "طريقة الفهرسة مطلوبة", + "nodes.knowledgeBase.notConfigured": "غير مكوّن", "nodes.knowledgeBase.rerankingModelIsInvalid": "نموذج إعادة الترتيب غير صالح", "nodes.knowledgeBase.rerankingModelIsRequired": "نموذج إعادة الترتيب مطلوب", "nodes.knowledgeBase.retrievalSettingIsRequired": "إعداد الاسترجاع مطلوب", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "يدعم Jinja2 فقط", "nodes.templateTransform.inputVars": "متغيرات الإدخال", "nodes.templateTransform.outputVars.output": "المحتوى المحول", + "nodes.tool.authorizationRequired": "التفويض مطلوب", "nodes.tool.authorize": "تخويل", "nodes.tool.inputVars": "متغيرات الإدخال", "nodes.tool.insertPlaceholder1": "اكتب أو اضغط", @@ -1062,10 +1071,12 @@ "panel.change": "تغيير", "panel.changeBlock": "تغيير العقدة", "panel.checklist": "قائمة المراجعة", + "panel.checklistDescription": "حل المشكلات التالية قبل النشر", "panel.checklistResolved": "تم حل جميع المشكلات", "panel.checklistTip": "تأكد من حل جميع المشكلات قبل النشر", "panel.createdBy": "تم الإنشاء بواسطة ", "panel.goTo": "الذهاب إلى", + "panel.goToFix": "الذهاب إلى الإصلاح", "panel.helpLink": "عرض المستندات", "panel.maximize": "تكبير القماش", "panel.minimize": "خروج من وضع ملء الشاشة", diff --git a/web/i18n/de-DE/app-debug.json b/web/i18n/de-DE/app-debug.json index f75982bee9..0e067e20eb 100644 --- a/web/i18n/de-DE/app-debug.json +++ b/web/i18n/de-DE/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "AUSFÜHREN", "inputs.title": "Debug und Vorschau", "inputs.userInputField": "Benutzereingabefeld", + "manageModels": "Modelle verwalten", "modelConfig.modeType.chat": "Chat", "modelConfig.modeType.completion": "Vollständig", "modelConfig.model": "Modell", "modelConfig.setTone": "Ton der Antworten festlegen", "modelConfig.title": "Modell und Parameter", + "noModelProviderConfigured": "Kein Modellanbieter konfiguriert", + "noModelProviderConfiguredTip": "Installieren oder konfigurieren Sie einen Modellanbieter, um zu beginnen.", + "noModelSelected": "Kein Modell ausgewählt", + "noModelSelectedTip": "Konfigurieren Sie oben ein Modell, um fortzufahren.", "noResult": "Hier wird die Ausgabe angezeigt.", "notSetAPIKey.description": "Der LLM-Anbieterschlüssel wurde nicht festgelegt und muss vor dem Debuggen festgelegt werden.", "notSetAPIKey.settingBtn": "Zu den Einstellungen gehen", diff --git a/web/i18n/de-DE/common.json b/web/i18n/de-DE/common.json index a7aaf55086..8639a24f3e 100644 --- a/web/i18n/de-DE/common.json +++ b/web/i18n/de-DE/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Unbefugt", "modelProvider.buyQuota": "Kontingent kaufen", "modelProvider.callTimes": "Anrufzeiten", + "modelProvider.card.aiCreditsInUse": "AI Credits werden verwendet", + "modelProvider.card.aiCreditsOption": "AI Credits", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "API Key erforderlich", + "modelProvider.card.apiKeyUnavailableFallback": "API Key nicht verfügbar, AI Credits werden verwendet", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Überprüfen Sie Ihre API-Key-Konfiguration, um zurückzuwechseln", "modelProvider.card.buyQuota": "Kontingent kaufen", "modelProvider.card.callTimes": "Anrufzeiten", + "modelProvider.card.creditsExhaustedDescription": "Bitte upgraden Sie Ihren Plan oder konfigurieren Sie einen API Key", + "modelProvider.card.creditsExhaustedFallback": "AI Credits aufgebraucht, API Key wird verwendet", + "modelProvider.card.creditsExhaustedFallbackDescription": "Upgraden Sie Ihren Plan, um die AI-Credit-Priorität wiederherzustellen.", + "modelProvider.card.creditsExhaustedMessage": "AI Credits wurden aufgebraucht", "modelProvider.card.modelAPI": "{{modelName}}-Modelle verwenden den API-Schlüssel.", "modelProvider.card.modelNotSupported": "{{modelName}}-Modelle sind nicht installiert.", "modelProvider.card.modelSupported": "{{modelName}}-Modelle verwenden dieses Kontingent.", + "modelProvider.card.noApiKeysDescription": "Fügen Sie einen API Key hinzu, um Ihre eigenen Modell-Zugangsdaten zu verwenden.", + "modelProvider.card.noApiKeysFallback": "Keine API Keys, AI Credits werden verwendet", + "modelProvider.card.noApiKeysTitle": "Noch keine API Keys konfiguriert", + "modelProvider.card.noAvailableUsage": "Kein verfügbares Guthaben", "modelProvider.card.onTrial": "In Probe", "modelProvider.card.paid": "Bezahlt", "modelProvider.card.priorityUse": "Priorisierte Nutzung", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "API-Schlüssel entfernen", "modelProvider.card.tip": "Nachrichtenguthaben unterstützen Modelle von {{modelNames}}. Der bezahlten Kontingent wird Vorrang gegeben. Das kostenlose Kontingent wird nach dem Verbrauch des bezahlten Kontingents verwendet.", "modelProvider.card.tokens": "Token", + "modelProvider.card.unavailable": "Nicht verfügbar", + "modelProvider.card.upgradePlan": "Plan upgraden", + "modelProvider.card.usageLabel": "Verbrauch", + "modelProvider.card.usagePriority": "Nutzungspriorität", + "modelProvider.card.usagePriorityTip": "Legen Sie fest, welche Ressource beim Ausführen von Modellen zuerst verwendet wird.", "modelProvider.collapse": "Einklappen", "modelProvider.config": "Konfigurieren", "modelProvider.configLoadBalancing": "Lastenausgleich für die Konfiguration", @@ -387,9 +406,11 @@ "modelProvider.model": "Modell", "modelProvider.modelAndParameters": "Modell und Parameter", "modelProvider.modelHasBeenDeprecated": "Dieses Modell ist veraltet", + "modelProvider.modelSettings": "Modelleinstellungen", "modelProvider.models": "Modelle", "modelProvider.modelsNum": "{{num}} Modelle", "modelProvider.noModelFound": "Kein Modell für {{model}} gefunden", + "modelProvider.noneConfigured": "Konfigurieren Sie ein Standard-Systemmodell, um Anwendungen auszuführen", "modelProvider.notConfigured": "Das Systemmodell wurde noch nicht vollständig konfiguriert, und einige Funktionen sind möglicherweise nicht verfügbar.", "modelProvider.parameters": "PARAMETER", "modelProvider.parametersInvalidRemoved": "Einige Parameter sind ungültig und wurden entfernt.", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Zurücksetzen am {{date}}", "modelProvider.searchModel": "Suchmodell", "modelProvider.selectModel": "Wählen Sie Ihr Modell", + "modelProvider.selector.aiCredits": "AI Credits", + "modelProvider.selector.apiKeyUnavailable": "API Key nicht verfügbar", + "modelProvider.selector.apiKeyUnavailableTip": "Der API Key wurde entfernt. Bitte konfigurieren Sie einen neuen API Key.", + "modelProvider.selector.configure": "Konfigurieren", + "modelProvider.selector.configureRequired": "Konfiguration erforderlich", + "modelProvider.selector.creditsExhausted": "Guthaben aufgebraucht", + "modelProvider.selector.creditsExhaustedTip": "Ihre AI Credits wurden aufgebraucht. Bitte upgraden Sie Ihren Plan oder fügen Sie einen API Key hinzu.", + "modelProvider.selector.disabled": "Deaktiviert", + "modelProvider.selector.discoverMoreInMarketplace": "Mehr im Marketplace entdecken", "modelProvider.selector.emptySetting": "Bitte gehen Sie zu den Einstellungen, um zu konfigurieren", "modelProvider.selector.emptyTip": "Keine verfügbaren Modelle", + "modelProvider.selector.fromMarketplace": "Vom Marketplace", + "modelProvider.selector.incompatible": "Inkompatibel", + "modelProvider.selector.incompatibleTip": "Dieses Modell ist in der aktuellen Version nicht verfügbar. Bitte wählen Sie ein anderes verfügbares Modell.", + "modelProvider.selector.install": "Installieren", + "modelProvider.selector.modelProviderSettings": "Modellanbieter-Einstellungen", + "modelProvider.selector.noProviderConfigured": "Kein Modellanbieter konfiguriert", + "modelProvider.selector.noProviderConfiguredDesc": "Durchsuchen Sie den Marketplace, um einen zu installieren, oder konfigurieren Sie Anbieter in den Einstellungen.", + "modelProvider.selector.onlyCompatibleModelsShown": "Es werden nur kompatible Modelle angezeigt", "modelProvider.selector.rerankTip": "Bitte richten Sie das Rerank-Modell ein", "modelProvider.selector.tip": "Dieses Modell wurde entfernt. Bitte fügen Sie ein Modell hinzu oder wählen Sie ein anderes Modell.", "modelProvider.setupModelFirst": "Bitte richten Sie zuerst Ihr Modell ein", diff --git a/web/i18n/de-DE/plugin.json b/web/i18n/de-DE/plugin.json index c0158be29b..e805f3fabd 100644 --- a/web/i18n/de-DE/plugin.json +++ b/web/i18n/de-DE/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Plugin entfernen", "action.deleteContentLeft": "Möchten Sie", "action.deleteContentRight": "Plugin?", + "action.deleteSuccess": "Plugin erfolgreich entfernt", "action.pluginInfo": "Plugin-Info", "action.usedInApps": "Dieses Plugin wird in {{num}} Apps verwendet.", "allCategories": "Alle Kategorien", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Installieren", "detailPanel.operation.remove": "Entfernen", "detailPanel.operation.update": "Aktualisieren", + "detailPanel.operation.updateTooltip": "Aktualisieren Sie, um auf die neuesten Modelle zuzugreifen.", "detailPanel.operation.viewDetail": "Im Detail sehen", "detailPanel.serviceOk": "Service in Ordnung", "detailPanel.strategyNum": "{{num}} {{strategy}} IINKLUSIVE", @@ -231,12 +233,18 @@ "source.local": "Lokale Paketdatei", "source.marketplace": "Marktplatz", "task.clearAll": "Alle löschen", + "task.errorMsg.github": "Dieses Plugin konnte nicht automatisch installiert werden.\nBitte installieren Sie es von GitHub.", + "task.errorMsg.marketplace": "Dieses Plugin konnte nicht automatisch installiert werden.\nBitte installieren Sie es vom Marketplace.", + "task.errorMsg.unknown": "Dieses Plugin konnte nicht installiert werden.\nDie Plugin-Quelle konnte nicht identifiziert werden.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} Plugins konnten nicht installiert werden, klicken Sie hier, um sie anzusehen", + "task.installFromGithub": "Von GitHub installieren", + "task.installFromMarketplace": "Vom Marketplace installieren", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} Plugins konnten nicht installiert werden", "task.installing": "Plugins werden installiert.", + "task.installingHint": "Installation läuft... Dies kann einige Minuten dauern.", "task.installingWithError": "Installation von {{installingLength}} Plugins, {{successLength}} erfolgreich, {{errorLength}} fehlgeschlagen", "task.installingWithSuccess": "Installation von {{installingLength}} Plugins, {{successLength}} erfolgreich.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/de-DE/workflow.json b/web/i18n/de-DE/workflow.json index 48037ce006..362eac19b6 100644 --- a/web/i18n/de-DE/workflow.json +++ b/web/i18n/de-DE/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "Arbeitsablauf aktualisieren", "error.startNodeRequired": "Bitte füge zuerst einen Startknoten hinzu, bevor du {{operation}}.", "errorMsg.authRequired": "Autorisierung ist erforderlich", + "errorMsg.configureModel": "Modell konfigurieren", "errorMsg.fieldRequired": "{{field}} ist erforderlich", "errorMsg.fields.code": "Code", "errorMsg.fields.model": "Modell", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Vision variabel", "errorMsg.invalidJson": "{{field}} ist ein ungültiges JSON", "errorMsg.invalidVariable": "Ungültige Variable", + "errorMsg.modelPluginNotInstalled": "Ungültige Variable. Konfigurieren Sie ein Modell, um diese Variable zu aktivieren.", "errorMsg.noValidTool": "{{field}} kein gültiges Werkzeug ausgewählt", "errorMsg.rerankModelRequired": "Bevor Sie das Rerank-Modell aktivieren, bestätigen Sie bitte, dass das Modell in den Einstellungen erfolgreich konfiguriert wurde.", "errorMsg.startNodeRequired": "Bitte füge zuerst einen Startknoten hinzu, bevor du {{operation}}.", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Fenstergröße", "nodes.common.outputVars": "Ausgabevariablen", "nodes.common.pluginNotInstalled": "Plugin ist nicht installiert", + "nodes.common.pluginsNotInstalled": "{{count}} Plugins nicht installiert", "nodes.common.retry.maxRetries": "Max. Wiederholungen", "nodes.common.retry.ms": "Frau", "nodes.common.retry.retries": "{{num}} Wiederholungen", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Stücke", "nodes.knowledgeBase.chunksInputTip": "Die Eingangsvariable des Wissensbasis-Knotens sind Chunks. Der Variablentyp ist ein Objekt mit einem spezifischen JSON-Schema, das konsistent mit der ausgewählten Chunk-Struktur sein muss.", "nodes.knowledgeBase.chunksVariableIsRequired": "Die Variable 'Chunks' ist erforderlich", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API Key nicht verfügbar", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Guthaben aufgebraucht", + "nodes.knowledgeBase.embeddingModelIncompatible": "Inkompatibel", "nodes.knowledgeBase.embeddingModelIsInvalid": "Einbettungsmodell ist ungültig", "nodes.knowledgeBase.embeddingModelIsRequired": "Ein Einbettungsmodell ist erforderlich", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Embedding-Modell nicht konfiguriert", "nodes.knowledgeBase.indexMethodIsRequired": "Index-Methode ist erforderlich", + "nodes.knowledgeBase.notConfigured": "Nicht konfiguriert", "nodes.knowledgeBase.rerankingModelIsInvalid": "Das Reranking-Modell ist ungültig", "nodes.knowledgeBase.rerankingModelIsRequired": "Ein Reranking-Modell ist erforderlich", "nodes.knowledgeBase.retrievalSettingIsRequired": "Abrufeinstellung ist erforderlich", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Unterstützt nur Jinja2", "nodes.templateTransform.inputVars": "Eingabevariablen", "nodes.templateTransform.outputVars.output": "Transformierter Inhalt", + "nodes.tool.authorizationRequired": "Autorisierung erforderlich", "nodes.tool.authorize": "Autorisieren", "nodes.tool.inputVars": "Eingabevariablen", "nodes.tool.insertPlaceholder1": "Tippen oder drücken", @@ -1062,10 +1071,12 @@ "panel.change": "Ändern", "panel.changeBlock": "Knoten ändern", "panel.checklist": "Checkliste", + "panel.checklistDescription": "Beheben Sie die folgenden Probleme vor der Veröffentlichung", "panel.checklistResolved": "Alle Probleme wurden gelöst", "panel.checklistTip": "Stellen Sie sicher, dass alle Probleme vor der Veröffentlichung gelöst sind", "panel.createdBy": "Erstellt von ", "panel.goTo": "Gehe zu", + "panel.goToFix": "Zur Behebung", "panel.helpLink": "Hilfe", "panel.maximize": "Maximiere die Leinwand", "panel.minimize": "Vollbildmodus beenden", diff --git a/web/i18n/en-US/workflow.json b/web/i18n/en-US/workflow.json index 586db51ad5..8d590627de 100644 --- a/web/i18n/en-US/workflow.json +++ b/web/i18n/en-US/workflow.json @@ -287,7 +287,10 @@ "env.export.checkbox": "Export secret values", "env.export.export": "Export DSL with secret values ", "env.export.ignore": "Export DSL", + "env.export.name": "Name", + "env.export.secret": "Secret", "env.export.title": "Export Secret environment variables?", + "env.export.value": "Value", "env.modal.description": "Description", "env.modal.descriptionPlaceholder": "Describe the variable", "env.modal.editTitle": "Edit Environment Variable", diff --git a/web/i18n/es-ES/app-debug.json b/web/i18n/es-ES/app-debug.json index 8245f2b325..cfb8a0643e 100644 --- a/web/i18n/es-ES/app-debug.json +++ b/web/i18n/es-ES/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "EJECUTAR", "inputs.title": "Depurar y Previsualizar", "inputs.userInputField": "Campo de Entrada del Usuario", + "manageModels": "Gestionar modelos", "modelConfig.modeType.chat": "Chat", "modelConfig.modeType.completion": "Completar", "modelConfig.model": "Modelo", "modelConfig.setTone": "Establecer tono de respuestas", "modelConfig.title": "Modelo y Parámetros", + "noModelProviderConfigured": "Ningún proveedor de modelos configurado", + "noModelProviderConfiguredTip": "Instala o configura un proveedor de modelos para comenzar.", + "noModelSelected": "Ningún modelo seleccionado", + "noModelSelectedTip": "Configura un modelo arriba para continuar.", "noResult": "La salida se mostrará aquí.", "notSetAPIKey.description": "La clave del proveedor LLM no se ha establecido, y debe configurarse antes de depurar.", "notSetAPIKey.settingBtn": "Ir a configuración", diff --git a/web/i18n/es-ES/common.json b/web/i18n/es-ES/common.json index 595124496b..1b97ce680d 100644 --- a/web/i18n/es-ES/common.json +++ b/web/i18n/es-ES/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "No autorizado", "modelProvider.buyQuota": "Comprar Cuota", "modelProvider.callTimes": "Tiempos de llamada", + "modelProvider.card.aiCreditsInUse": "AI credits en uso", + "modelProvider.card.aiCreditsOption": "AI credits", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "Se requiere API Key", + "modelProvider.card.apiKeyUnavailableFallback": "API Key no disponible, usando AI credits", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Comprueba la configuración de tu API Key para volver a usarla", "modelProvider.card.buyQuota": "Comprar Cuota", "modelProvider.card.callTimes": "Tiempos de llamada", + "modelProvider.card.creditsExhaustedDescription": "Por favor, mejora tu plan o configura una API Key", + "modelProvider.card.creditsExhaustedFallback": "AI credits agotados, usando API Key", + "modelProvider.card.creditsExhaustedFallbackDescription": "Mejora tu plan para restablecer la prioridad de AI credits.", + "modelProvider.card.creditsExhaustedMessage": "Los AI credits se han agotado", "modelProvider.card.modelAPI": "Los modelos {{modelName}} están usando la clave API.", "modelProvider.card.modelNotSupported": "Los modelos {{modelName}} no están instalados.", "modelProvider.card.modelSupported": "Los modelos {{modelName}} están usando esta cuota.", + "modelProvider.card.noApiKeysDescription": "Añade una API Key para usar tus propias credenciales de modelo.", + "modelProvider.card.noApiKeysFallback": "Sin API Keys, usando AI credits", + "modelProvider.card.noApiKeysTitle": "No hay API Keys configuradas", + "modelProvider.card.noAvailableUsage": "Sin uso disponible", "modelProvider.card.onTrial": "En prueba", "modelProvider.card.paid": "Pagado", "modelProvider.card.priorityUse": "Uso prioritario", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Eliminar CLAVE API", "modelProvider.card.tip": "Créditos de mensajes admite modelos de {{modelNames}}. Se dará prioridad a la cuota pagada. La cuota gratuita se utilizará después de que se agote la cuota pagada.", "modelProvider.card.tokens": "Tokens", + "modelProvider.card.unavailable": "No disponible", + "modelProvider.card.upgradePlan": "mejora tu plan", + "modelProvider.card.usageLabel": "Uso", + "modelProvider.card.usagePriority": "Prioridad de uso", + "modelProvider.card.usagePriorityTip": "Establece qué recurso usar primero al ejecutar modelos.", "modelProvider.collapse": "Colapsar", "modelProvider.config": "Configurar", "modelProvider.configLoadBalancing": "Configurar Balanceo de Carga", @@ -387,9 +406,11 @@ "modelProvider.model": "Modelo", "modelProvider.modelAndParameters": "Modelo y Parámetros", "modelProvider.modelHasBeenDeprecated": "Este modelo ha sido desaprobado", + "modelProvider.modelSettings": "Configuración de modelos", "modelProvider.models": "Modelos", "modelProvider.modelsNum": "{{num}} Modelos", "modelProvider.noModelFound": "No se encontró modelo para {{model}}", + "modelProvider.noneConfigured": "Configura un modelo de sistema predeterminado para ejecutar aplicaciones", "modelProvider.notConfigured": "El modelo del sistema aún no ha sido completamente configurado, y algunas funciones pueden no estar disponibles.", "modelProvider.parameters": "PARÁMETROS", "modelProvider.parametersInvalidRemoved": "Algunos parámetros son inválidos y han sido eliminados", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Restablecer el {{date}}", "modelProvider.searchModel": "Modelo de búsqueda", "modelProvider.selectModel": "Selecciona tu modelo", + "modelProvider.selector.aiCredits": "AI credits", + "modelProvider.selector.apiKeyUnavailable": "API Key no disponible", + "modelProvider.selector.apiKeyUnavailableTip": "La API Key ha sido eliminada. Por favor, configura una nueva API Key.", + "modelProvider.selector.configure": "Configurar", + "modelProvider.selector.configureRequired": "Configuración requerida", + "modelProvider.selector.creditsExhausted": "Créditos agotados", + "modelProvider.selector.creditsExhaustedTip": "Tus AI credits se han agotado. Por favor, mejora tu plan o añade una API Key.", + "modelProvider.selector.disabled": "Desactivado", + "modelProvider.selector.discoverMoreInMarketplace": "Descubre más en el Marketplace", "modelProvider.selector.emptySetting": "Por favor ve a configuraciones para configurar", "modelProvider.selector.emptyTip": "No hay modelos disponibles", + "modelProvider.selector.fromMarketplace": "Desde el Marketplace", + "modelProvider.selector.incompatible": "Incompatible", + "modelProvider.selector.incompatibleTip": "Este modelo no está disponible en la versión actual. Por favor, selecciona otro modelo disponible.", + "modelProvider.selector.install": "Instalar", + "modelProvider.selector.modelProviderSettings": "Configuración del proveedor de modelos", + "modelProvider.selector.noProviderConfigured": "Ningún proveedor de modelos configurado", + "modelProvider.selector.noProviderConfiguredDesc": "Explora el Marketplace para instalar uno, o configura proveedores en los ajustes.", + "modelProvider.selector.onlyCompatibleModelsShown": "Solo se muestran los modelos compatibles", "modelProvider.selector.rerankTip": "Por favor configura el modelo de Reordenar", "modelProvider.selector.tip": "Este modelo ha sido eliminado. Por favor agrega un modelo o selecciona otro modelo.", "modelProvider.setupModelFirst": "Por favor configura tu modelo primero", diff --git a/web/i18n/es-ES/plugin.json b/web/i18n/es-ES/plugin.json index 297b86606d..c7d5855f24 100644 --- a/web/i18n/es-ES/plugin.json +++ b/web/i18n/es-ES/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Eliminar plugin", "action.deleteContentLeft": "¿Le gustaría eliminar", "action.deleteContentRight": "¿Complemento?", + "action.deleteSuccess": "Plugin eliminado correctamente", "action.pluginInfo": "Información del plugin", "action.usedInApps": "Este plugin se está utilizando en las aplicaciones {{num}}.", "allCategories": "Todas las categorías", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Instalar", "detailPanel.operation.remove": "Eliminar", "detailPanel.operation.update": "Actualizar", + "detailPanel.operation.updateTooltip": "Actualiza para acceder a los modelos más recientes.", "detailPanel.operation.viewDetail": "Ver Detalle", "detailPanel.serviceOk": "Servicio OK", "detailPanel.strategyNum": "{{num}} {{strategy}} INCLUIDO", @@ -231,12 +233,18 @@ "source.local": "Archivo de paquete local", "source.marketplace": "Mercado", "task.clearAll": "Borrar todo", + "task.errorMsg.github": "Este plugin no se pudo instalar automáticamente.\nPor favor, instálalo desde GitHub.", + "task.errorMsg.marketplace": "Este plugin no se pudo instalar automáticamente.\nPor favor, instálalo desde el Marketplace.", + "task.errorMsg.unknown": "Este plugin no se pudo instalar.\nNo se pudo identificar el origen del plugin.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "Los complementos {{errorLength}} no se pudieron instalar, haga clic para ver", + "task.installFromGithub": "Instalar desde GitHub", + "task.installFromMarketplace": "Instalar desde el Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "Los complementos {{errorLength}} no se pudieron instalar", "task.installing": "Instalando plugins.", + "task.installingHint": "Instalando... Esto puede tardar unos minutos.", "task.installingWithError": "Instalando plugins {{installingLength}}, {{successLength}} éxito, {{errorLength}} fallido", "task.installingWithSuccess": "Instalando plugins {{installingLength}}, {{successLength}} éxito.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/es-ES/workflow.json b/web/i18n/es-ES/workflow.json index d91cbd7cb2..393859a36f 100644 --- a/web/i18n/es-ES/workflow.json +++ b/web/i18n/es-ES/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "actualizando flujo de trabajo", "error.startNodeRequired": "Por favor, agregue primero un nodo de inicio antes de {{operation}}", "errorMsg.authRequired": "Se requiere autorización", + "errorMsg.configureModel": "Configura un modelo", "errorMsg.fieldRequired": "Se requiere {{field}}", "errorMsg.fields.code": "Código", "errorMsg.fields.model": "Modelo", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Variable de visión", "errorMsg.invalidJson": "{{field}} no es un JSON válido", "errorMsg.invalidVariable": "Variable no válida", + "errorMsg.modelPluginNotInstalled": "Variable no válida. Configura un modelo para habilitar esta variable.", "errorMsg.noValidTool": "{{field}} no se ha seleccionado ninguna herramienta válida", "errorMsg.rerankModelRequired": "Antes de activar el modelo de reclasificación, confirme que el modelo se ha configurado correctamente en la configuración.", "errorMsg.startNodeRequired": "Por favor, agregue primero un nodo de inicio antes de {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Tamaño de ventana", "nodes.common.outputVars": "Variables de salida", "nodes.common.pluginNotInstalled": "El complemento no está instalado", + "nodes.common.pluginsNotInstalled": "{{count}} plugins no instalados", "nodes.common.retry.maxRetries": "Número máximo de reintentos", "nodes.common.retry.ms": "Sra.", "nodes.common.retry.retries": "{{num}} Reintentos", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Trozo", "nodes.knowledgeBase.chunksInputTip": "La variable de entrada del nodo de la base de conocimientos es Chunks. El tipo de variable es un objeto con un esquema JSON específico que debe ser consistente con la estructura del fragmento seleccionado.", "nodes.knowledgeBase.chunksVariableIsRequired": "La variable Chunks es obligatoria", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API Key no disponible", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Créditos agotados", + "nodes.knowledgeBase.embeddingModelIncompatible": "Incompatible", "nodes.knowledgeBase.embeddingModelIsInvalid": "El modelo de incrustación no es válido", "nodes.knowledgeBase.embeddingModelIsRequired": "Se requiere un modelo de incrustación", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Modelo de embedding no configurado", "nodes.knowledgeBase.indexMethodIsRequired": "Se requiere el método de índice", + "nodes.knowledgeBase.notConfigured": "No configurado", "nodes.knowledgeBase.rerankingModelIsInvalid": "El modelo de reordenación no es válido", "nodes.knowledgeBase.rerankingModelIsRequired": "Se requiere un modelo de reordenamiento", "nodes.knowledgeBase.retrievalSettingIsRequired": "Se requiere configuración de recuperación", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Solo admite Jinja2", "nodes.templateTransform.inputVars": "Variables de entrada", "nodes.templateTransform.outputVars.output": "Contenido transformado", + "nodes.tool.authorizationRequired": "Autorización requerida", "nodes.tool.authorize": "autorizar", "nodes.tool.inputVars": "Variables de entrada", "nodes.tool.insertPlaceholder1": "Escribe o presiona", @@ -1062,10 +1071,12 @@ "panel.change": "Cambiar", "panel.changeBlock": "Cambiar Nodo", "panel.checklist": "Lista de verificación", + "panel.checklistDescription": "Resuelve los siguientes problemas antes de publicar", "panel.checklistResolved": "Se resolvieron todos los problemas", "panel.checklistTip": "Asegúrate de resolver todos los problemas antes de publicar", "panel.createdBy": "Creado por ", "panel.goTo": "Ir a", + "panel.goToFix": "Ir a corregir", "panel.helpLink": "Ayuda", "panel.maximize": "Maximizar Canvas", "panel.minimize": "Salir de pantalla completa", diff --git a/web/i18n/fa-IR/app-debug.json b/web/i18n/fa-IR/app-debug.json index 5427ebb72a..a612105f35 100644 --- a/web/i18n/fa-IR/app-debug.json +++ b/web/i18n/fa-IR/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "اجرا", "inputs.title": "اشکال زدایی و پیش نمایش", "inputs.userInputField": "فیلد ورودی کاربر", + "manageModels": "مدیریت مدل‌ها", "modelConfig.modeType.chat": "چت", "modelConfig.modeType.completion": "کامل", "modelConfig.model": "مدل", "modelConfig.setTone": "لحن پاسخ ها را تنظیم کنید", "modelConfig.title": "مدل و پارامترها", + "noModelProviderConfigured": "هیچ ارائه‌دهنده مدلی پیکربندی نشده است", + "noModelProviderConfiguredTip": "برای شروع، یک ارائه‌دهنده مدل نصب یا پیکربندی کنید.", + "noModelSelected": "هیچ مدلی انتخاب نشده است", + "noModelSelectedTip": "برای ادامه، یک مدل را در بالا پیکربندی کنید.", "noResult": "خروجی در اینجا نمایش داده می شود.", "notSetAPIKey.description": "کلید ارائه‌دهنده LLM تنظیم نشده است و باید قبل از دیباگ تنظیم شود.", "notSetAPIKey.settingBtn": "به تنظیمات بروید", diff --git a/web/i18n/fa-IR/common.json b/web/i18n/fa-IR/common.json index ec535138a4..d2b1e8158c 100644 --- a/web/i18n/fa-IR/common.json +++ b/web/i18n/fa-IR/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "بدون مجوز", "modelProvider.buyQuota": "خرید سهمیه", "modelProvider.callTimes": "تعداد فراخوانی", + "modelProvider.card.aiCreditsInUse": "اعتبار هوش مصنوعی در حال استفاده", + "modelProvider.card.aiCreditsOption": "اعتبار هوش مصنوعی", + "modelProvider.card.apiKeyOption": "کلید API", + "modelProvider.card.apiKeyRequired": "کلید API الزامی است", + "modelProvider.card.apiKeyUnavailableFallback": "کلید API در دسترس نیست، در حال استفاده از اعتبار هوش مصنوعی", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "پیکربندی کلید API خود را بررسی کنید تا بازگردید", "modelProvider.card.buyQuota": "خرید سهمیه", "modelProvider.card.callTimes": "تعداد فراخوانی", + "modelProvider.card.creditsExhaustedDescription": "لطفاً طرح خود را ارتقا دهید یا یک کلید API پیکربندی کنید", + "modelProvider.card.creditsExhaustedFallback": "اعتبار هوش مصنوعی تمام شده، در حال استفاده از کلید API", + "modelProvider.card.creditsExhaustedFallbackDescription": "طرح خود را ارتقا دهید تا اولویت اعتبار هوش مصنوعی از سر گرفته شود.", + "modelProvider.card.creditsExhaustedMessage": "اعتبار هوش مصنوعی تمام شده است", "modelProvider.card.modelAPI": "مدل‌های {{modelName}} از کلید API استفاده می‌کنند.", "modelProvider.card.modelNotSupported": "مدل‌های {{modelName}} نصب نشده‌اند.", "modelProvider.card.modelSupported": "مدل‌های {{modelName}} از این سهمیه استفاده می‌کنند.", + "modelProvider.card.noApiKeysDescription": "یک کلید API اضافه کنید تا از اعتبارنامه‌های مدل خود استفاده کنید.", + "modelProvider.card.noApiKeysFallback": "بدون کلید API، در حال استفاده از اعتبار هوش مصنوعی", + "modelProvider.card.noApiKeysTitle": "هنوز کلید API پیکربندی نشده است", + "modelProvider.card.noAvailableUsage": "هیچ مصرفی در دسترس نیست", "modelProvider.card.onTrial": "در حال آزمایش", "modelProvider.card.paid": "پرداخت شده", "modelProvider.card.priorityUse": "استفاده با اولویت", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "حذف کلید API", "modelProvider.card.tip": "اعتبار پیام از مدل‌های {{modelNames}} پشتیبانی می‌کند. اولویت به سهمیه پرداخت شده داده می‌شود. سهمیه رایگان پس از اتمام سهمیه پرداخت شده استفاده خواهد شد.", "modelProvider.card.tokens": "توکن‌ها", + "modelProvider.card.unavailable": "در دسترس نیست", + "modelProvider.card.upgradePlan": "طرح خود را ارتقا دهید", + "modelProvider.card.usageLabel": "مصرف", + "modelProvider.card.usagePriority": "اولویت مصرف", + "modelProvider.card.usagePriorityTip": "تعیین کنید که هنگام اجرای مدل‌ها کدام منبع اول استفاده شود.", "modelProvider.collapse": "جمع کردن", "modelProvider.config": "پیکربندی", "modelProvider.configLoadBalancing": "پیکربندی تعادل بار", @@ -387,9 +406,11 @@ "modelProvider.model": "مدل", "modelProvider.modelAndParameters": "مدل و پارامترها", "modelProvider.modelHasBeenDeprecated": "این مدل منسوخ شده است", + "modelProvider.modelSettings": "تنظیمات مدل", "modelProvider.models": "مدل‌ها", "modelProvider.modelsNum": "{{num}} مدل", "modelProvider.noModelFound": "هیچ مدلی برای {{model}} یافت نشد", + "modelProvider.noneConfigured": "یک مدل سیستم پیش‌فرض برای اجرای برنامه‌ها پیکربندی کنید", "modelProvider.notConfigured": "مدل سیستم هنوز به طور کامل پیکربندی نشده است و برخی از عملکردها ممکن است در دسترس نباشند.", "modelProvider.parameters": "پارامترها", "modelProvider.parametersInvalidRemoved": "برخی پارامترها نامعتبر هستند و حذف شده‌اند", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "بازنشانی در {{date}}", "modelProvider.searchModel": "جستجوی مدل", "modelProvider.selectModel": "مدل خود را انتخاب کنید", + "modelProvider.selector.aiCredits": "اعتبار هوش مصنوعی", + "modelProvider.selector.apiKeyUnavailable": "کلید API در دسترس نیست", + "modelProvider.selector.apiKeyUnavailableTip": "کلید API حذف شده است. لطفاً یک کلید API جدید پیکربندی کنید.", + "modelProvider.selector.configure": "پیکربندی", + "modelProvider.selector.configureRequired": "پیکربندی الزامی است", + "modelProvider.selector.creditsExhausted": "اعتبار تمام شده", + "modelProvider.selector.creditsExhaustedTip": "اعتبار هوش مصنوعی شما تمام شده است. لطفاً طرح خود را ارتقا دهید یا یک کلید API اضافه کنید.", + "modelProvider.selector.disabled": "غیرفعال", + "modelProvider.selector.discoverMoreInMarketplace": "اطلاعات بیشتر در Marketplace", "modelProvider.selector.emptySetting": "لطفاً به تنظیمات بروید تا پیکربندی کنید", "modelProvider.selector.emptyTip": "هیچ مدل موجودی وجود ندارد", + "modelProvider.selector.fromMarketplace": "از Marketplace", + "modelProvider.selector.incompatible": "ناسازگار", + "modelProvider.selector.incompatibleTip": "این مدل در نسخه فعلی موجود نیست. لطفاً مدل دیگری انتخاب کنید.", + "modelProvider.selector.install": "نصب", + "modelProvider.selector.modelProviderSettings": "تنظیمات ارائه‌دهنده مدل", + "modelProvider.selector.noProviderConfigured": "هیچ ارائه‌دهنده مدلی پیکربندی نشده است", + "modelProvider.selector.noProviderConfiguredDesc": "در Marketplace جستجو کنید تا یکی نصب کنید، یا ارائه‌دهندگان را در تنظیمات پیکربندی کنید.", + "modelProvider.selector.onlyCompatibleModelsShown": "فقط مدل‌های سازگار نمایش داده می‌شوند", "modelProvider.selector.rerankTip": "لطفاً مدل رتبه‌بندی مجدد را تنظیم کنید", "modelProvider.selector.tip": "این مدل حذف شده است. لطفاً یک مدل اضافه کنید یا مدل دیگری را انتخاب کنید.", "modelProvider.setupModelFirst": "لطفاً ابتدا مدل خود را تنظیم کنید", diff --git a/web/i18n/fa-IR/plugin.json b/web/i18n/fa-IR/plugin.json index a1bbc8ee63..bee2111b44 100644 --- a/web/i18n/fa-IR/plugin.json +++ b/web/i18n/fa-IR/plugin.json @@ -3,6 +3,7 @@ "action.delete": "حذف افزونه", "action.deleteContentLeft": "آیا می خواهید", "action.deleteContentRight": "افزونه?", + "action.deleteSuccess": "افزونه با موفقیت حذف شد", "action.pluginInfo": "اطلاعات پلاگین", "action.usedInApps": "این افزونه در برنامه های {{num}} استفاده می شود.", "allCategories": "همه دسته بندی ها", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "نصب", "detailPanel.operation.remove": "حذف", "detailPanel.operation.update": "روز رسانی", + "detailPanel.operation.updateTooltip": "به‌روزرسانی کنید تا به جدیدترین مدل‌ها دسترسی پیدا کنید.", "detailPanel.operation.viewDetail": "نمایش جزئیات", "detailPanel.serviceOk": "خدمات خوب", "detailPanel.strategyNum": "{{num}} {{strategy}} شامل", @@ -231,12 +233,18 @@ "source.local": "فایل بسته محلی", "source.marketplace": "بازار", "task.clearAll": "پاک کردن همه", + "task.errorMsg.github": "این افزونه به‌صورت خودکار نصب نشد.\nلطفاً آن را از GitHub نصب کنید.", + "task.errorMsg.marketplace": "این افزونه به‌صورت خودکار نصب نشد.\nلطفاً آن را از Marketplace نصب کنید.", + "task.errorMsg.unknown": "این افزونه نصب نشد.\nمنبع افزونه قابل شناسایی نبود.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "پلاگین های {{errorLength}} نصب نشدند، برای مشاهده کلیک کنید", + "task.installFromGithub": "نصب از GitHub", + "task.installFromMarketplace": "نصب از Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "افزونه های {{errorLength}} نصب نشدند", "task.installing": "در حال نصب پلاگین‌ها.", + "task.installingHint": "در حال نصب... این ممکن است چند دقیقه طول بکشد.", "task.installingWithError": "نصب پلاگین های {{installingLength}}، {{successLength}} با موفقیت مواجه شد، {{errorLength}} ناموفق بود", "task.installingWithSuccess": "نصب پلاگین های {{installingLength}}، {{successLength}} موفقیت آمیز است.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/fa-IR/workflow.json b/web/i18n/fa-IR/workflow.json index 676179e6d4..7a8fca11f1 100644 --- a/web/i18n/fa-IR/workflow.json +++ b/web/i18n/fa-IR/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "به‌روزرسانی گردش کار", "error.startNodeRequired": "لطفاً قبل از {{operation}} ابتدا یک گره شروع اضافه کنید", "errorMsg.authRequired": "احراز هویت الزامی است", + "errorMsg.configureModel": "یک مدل پیکربندی کنید", "errorMsg.fieldRequired": "{{field}} الزامی است", "errorMsg.fields.code": "کد", "errorMsg.fields.model": "مدل", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "متغیر بینایی", "errorMsg.invalidJson": "{{field}} یک JSON معتبر نیست", "errorMsg.invalidVariable": "متغیر نامعتبر", + "errorMsg.modelPluginNotInstalled": "متغیر نامعتبر. برای فعال‌سازی این متغیر، یک مدل پیکربندی کنید.", "errorMsg.noValidTool": "{{field}} هیچ ابزار معتبری انتخاب نشده است", "errorMsg.rerankModelRequired": "قبل از فعال‌سازی Rerank Model، لطفاً مطمئن شوید که مدل در تنظیمات با موفقیت پیکربندی شده است.", "errorMsg.startNodeRequired": "لطفاً قبل از {{operation}} ابتدا یک گره شروع اضافه کنید", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "اندازه پنجره", "nodes.common.outputVars": "متغیرهای خروجی", "nodes.common.pluginNotInstalled": "افزونه نصب نشده است", + "nodes.common.pluginsNotInstalled": "{{count}} افزونه نصب نشده است", "nodes.common.retry.maxRetries": "حداکثر تلاش مجدد", "nodes.common.retry.ms": "ms", "nodes.common.retry.retries": "{{num}} تلاش مجدد", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "چانک‌ها", "nodes.knowledgeBase.chunksInputTip": "متغیر ورودی گره پایگاه دانش چانک‌ها است. نوع متغیر یک شیء با طرح JSON خاص است که باید با ساختار چانک انتخاب‌شده سازگار باشد.", "nodes.knowledgeBase.chunksVariableIsRequired": "متغیر چانک‌ها الزامی است", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "کلید API در دسترس نیست", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "اعتبار تمام شده", + "nodes.knowledgeBase.embeddingModelIncompatible": "ناسازگار", "nodes.knowledgeBase.embeddingModelIsInvalid": "مدل Embedding نامعتبر است", "nodes.knowledgeBase.embeddingModelIsRequired": "مدل Embedding الزامی است", + "nodes.knowledgeBase.embeddingModelNotConfigured": "مدل Embedding پیکربندی نشده است", "nodes.knowledgeBase.indexMethodIsRequired": "روش ایندکس‌گذاری الزامی است", + "nodes.knowledgeBase.notConfigured": "پیکربندی نشده", "nodes.knowledgeBase.rerankingModelIsInvalid": "مدل بازرتبه‌بندی نامعتبر است", "nodes.knowledgeBase.rerankingModelIsRequired": "مدل بازرتبه‌بندی الزامی است", "nodes.knowledgeBase.retrievalSettingIsRequired": "تنظیمات بازیابی الزامی است", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "فقط از Jinja2 پشتیبانی می‌شود", "nodes.templateTransform.inputVars": "متغیرهای ورودی", "nodes.templateTransform.outputVars.output": "محتوای تبدیل‌شده", + "nodes.tool.authorizationRequired": "احراز هویت الزامی است", "nodes.tool.authorize": "مجوزدهی", "nodes.tool.inputVars": "متغیرهای ورودی", "nodes.tool.insertPlaceholder1": "تایپ کنید یا فشار دهید", @@ -1062,10 +1071,12 @@ "panel.change": "تغییر", "panel.changeBlock": "تغییر گره", "panel.checklist": "چک‌لیست", + "panel.checklistDescription": "مشکلات زیر را پیش از انتشار برطرف کنید", "panel.checklistResolved": "تمام مشکلات برطرف شده‌اند", "panel.checklistTip": "قبل از انتشار، مطمئن شوید که تمام مشکلات برطرف شده‌اند", "panel.createdBy": "ساخته شده توسط", "panel.goTo": "برو به", + "panel.goToFix": "برو به رفع", "panel.helpLink": "راهنما", "panel.maximize": "تمام‌صفحه", "panel.minimize": "خروج از تمام‌صفحه", diff --git a/web/i18n/fr-FR/app-debug.json b/web/i18n/fr-FR/app-debug.json index 88f75f5136..711959c323 100644 --- a/web/i18n/fr-FR/app-debug.json +++ b/web/i18n/fr-FR/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "EXÉCUTER", "inputs.title": "Déboguer et Aperçu", "inputs.userInputField": "Champ de saisie utilisateur", + "manageModels": "Gérer les modèles", "modelConfig.modeType.chat": "Discussion", "modelConfig.modeType.completion": "Complet", "modelConfig.model": "Modèle", "modelConfig.setTone": "Définir le ton des réponses", "modelConfig.title": "Modèle et Paramètres", + "noModelProviderConfigured": "Aucun fournisseur de modèle configuré", + "noModelProviderConfiguredTip": "Installez ou configurez un fournisseur de modèle pour commencer.", + "noModelSelected": "Aucun modèle sélectionné", + "noModelSelectedTip": "Configurez un modèle ci-dessus pour continuer.", "noResult": "La sortie sera affichée ici.", "notSetAPIKey.description": "La clé du fournisseur LLM n'a pas été définie, et elle doit être définie avant le débogage.", "notSetAPIKey.settingBtn": "Aller aux paramètres", diff --git a/web/i18n/fr-FR/common.json b/web/i18n/fr-FR/common.json index 42b40b2a2a..8710c04c44 100644 --- a/web/i18n/fr-FR/common.json +++ b/web/i18n/fr-FR/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Non autorisé", "modelProvider.buyQuota": "Acheter Quota", "modelProvider.callTimes": "Temps d'appel", + "modelProvider.card.aiCreditsInUse": "AI credits en cours d'utilisation", + "modelProvider.card.aiCreditsOption": "AI credits", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "API Key requise", + "modelProvider.card.apiKeyUnavailableFallback": "API Key indisponible, utilisation des AI credits", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Vérifiez la configuration de votre API Key pour revenir en arrière", "modelProvider.card.buyQuota": "Acheter Quota", "modelProvider.card.callTimes": "Temps d'appel", + "modelProvider.card.creditsExhaustedDescription": "Veuillez mettre à niveau votre forfait ou configurer une API Key", + "modelProvider.card.creditsExhaustedFallback": "AI credits épuisés, utilisation de l'API Key", + "modelProvider.card.creditsExhaustedFallbackDescription": "Mettez à niveau votre forfait pour rétablir la priorité des AI credits.", + "modelProvider.card.creditsExhaustedMessage": "Les AI credits ont été épuisés", "modelProvider.card.modelAPI": "Les modèles {{modelName}} utilisent la clé API.", "modelProvider.card.modelNotSupported": "Les modèles {{modelName}} ne sont pas installés.", "modelProvider.card.modelSupported": "Les modèles {{modelName}} utilisent ce quota.", + "modelProvider.card.noApiKeysDescription": "Ajoutez une API Key pour utiliser vos propres identifiants de modèle.", + "modelProvider.card.noApiKeysFallback": "Aucune API Key, utilisation des AI credits", + "modelProvider.card.noApiKeysTitle": "Aucune API Key configurée", + "modelProvider.card.noAvailableUsage": "Aucune utilisation disponible", "modelProvider.card.onTrial": "En Essai", "modelProvider.card.paid": "Payé", "modelProvider.card.priorityUse": "Utilisation prioritaire", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Supprimer la clé API", "modelProvider.card.tip": "Les crédits de messages prennent en charge les modèles de {{modelNames}}. La priorité sera donnée au quota payant. Le quota gratuit sera utilisé après épuisement du quota payant.", "modelProvider.card.tokens": "Jetons", + "modelProvider.card.unavailable": "Indisponible", + "modelProvider.card.upgradePlan": "mettre à niveau votre forfait", + "modelProvider.card.usageLabel": "Utilisation", + "modelProvider.card.usagePriority": "Priorité d'utilisation", + "modelProvider.card.usagePriorityTip": "Définissez la ressource à utiliser en priorité lors de l'exécution des modèles.", "modelProvider.collapse": "Effondrer", "modelProvider.config": "Configuration", "modelProvider.configLoadBalancing": "Équilibrage de charge de configuration", @@ -387,9 +406,11 @@ "modelProvider.model": "Modèle", "modelProvider.modelAndParameters": "Modèle et Paramètres", "modelProvider.modelHasBeenDeprecated": "Ce modèle est obsolète", + "modelProvider.modelSettings": "Paramètres du modèle", "modelProvider.models": "Modèles", "modelProvider.modelsNum": "{{num}} Modèles", "modelProvider.noModelFound": "Aucun modèle trouvé pour {{model}}", + "modelProvider.noneConfigured": "Configurez un modèle système par défaut pour exécuter les applications", "modelProvider.notConfigured": "Le modèle du système n'a pas encore été entièrement configuré, et certaines fonctions peuvent être indisponibles.", "modelProvider.parameters": "PARAMÈTRES", "modelProvider.parametersInvalidRemoved": "Certains paramètres sont invalides et ont été supprimés.", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Réinitialiser le {{date}}", "modelProvider.searchModel": "Modèle de recherche", "modelProvider.selectModel": "Sélectionnez votre modèle", + "modelProvider.selector.aiCredits": "AI credits", + "modelProvider.selector.apiKeyUnavailable": "API Key indisponible", + "modelProvider.selector.apiKeyUnavailableTip": "L'API Key a été supprimée. Veuillez configurer une nouvelle API Key.", + "modelProvider.selector.configure": "Configurer", + "modelProvider.selector.configureRequired": "Configuration requise", + "modelProvider.selector.creditsExhausted": "Crédits épuisés", + "modelProvider.selector.creditsExhaustedTip": "Vos AI credits ont été épuisés. Veuillez mettre à niveau votre forfait ou ajouter une API Key.", + "modelProvider.selector.disabled": "Désactivé", + "modelProvider.selector.discoverMoreInMarketplace": "Découvrir plus sur le Marketplace", "modelProvider.selector.emptySetting": "Veuillez aller dans les paramètres pour configurer", "modelProvider.selector.emptyTip": "Aucun modèle disponible", + "modelProvider.selector.fromMarketplace": "Depuis le Marketplace", + "modelProvider.selector.incompatible": "Incompatible", + "modelProvider.selector.incompatibleTip": "Ce modèle n'est pas disponible dans la version actuelle. Veuillez sélectionner un autre modèle disponible.", + "modelProvider.selector.install": "Installer", + "modelProvider.selector.modelProviderSettings": "Paramètres du fournisseur de modèle", + "modelProvider.selector.noProviderConfigured": "Aucun fournisseur de modèle configuré", + "modelProvider.selector.noProviderConfiguredDesc": "Parcourez le Marketplace pour en installer un, ou configurez les fournisseurs dans les paramètres.", + "modelProvider.selector.onlyCompatibleModelsShown": "Seuls les modèles compatibles sont affichés", "modelProvider.selector.rerankTip": "Veuillez configurer le modèle Rerank", "modelProvider.selector.tip": "Ce modèle a été supprimé. Veuillez ajouter un modèle ou sélectionner un autre modèle.", "modelProvider.setupModelFirst": "Veuillez d'abord configurer votre modèle", diff --git a/web/i18n/fr-FR/plugin.json b/web/i18n/fr-FR/plugin.json index 79f43acb8e..cbea19646d 100644 --- a/web/i18n/fr-FR/plugin.json +++ b/web/i18n/fr-FR/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Supprimer le plugin", "action.deleteContentLeft": "Souhaitez-vous supprimer", "action.deleteContentRight": "Plug-in ?", + "action.deleteSuccess": "Plugin supprimé avec succès", "action.pluginInfo": "Informations sur le plugin", "action.usedInApps": "Ce plugin est utilisé dans les applications {{num}}.", "allCategories": "Toutes les catégories", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Installer", "detailPanel.operation.remove": "Enlever", "detailPanel.operation.update": "Mettre à jour", + "detailPanel.operation.updateTooltip": "Mettez à jour pour accéder aux derniers modèles.", "detailPanel.operation.viewDetail": "Voir les détails", "detailPanel.serviceOk": "Service OK", "detailPanel.strategyNum": "{{num}} {{strategy}} INCLUS", @@ -231,12 +233,18 @@ "source.local": "Fichier de package local", "source.marketplace": "Marché", "task.clearAll": "Effacer tout", + "task.errorMsg.github": "Ce plugin n'a pas pu être installé automatiquement.\nVeuillez l'installer depuis GitHub.", + "task.errorMsg.marketplace": "Ce plugin n'a pas pu être installé automatiquement.\nVeuillez l'installer depuis le Marketplace.", + "task.errorMsg.unknown": "Ce plugin n'a pas pu être installé.\nLa source du plugin n'a pas pu être identifiée.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} les plugins n’ont pas pu être installés, cliquez pour voir", + "task.installFromGithub": "Installer depuis GitHub", + "task.installFromMarketplace": "Installer depuis le Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} les plugins n’ont pas pu être installés", "task.installing": "Installation des plugins.", + "task.installingHint": "Installation en cours... Cela peut prendre quelques minutes.", "task.installingWithError": "Installation des plugins {{installingLength}}, succès de {{successLength}}, échec de {{errorLength}}", "task.installingWithSuccess": "Installation des plugins {{installingLength}}, succès de {{successLength}}.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/fr-FR/workflow.json b/web/i18n/fr-FR/workflow.json index b5f67f74b3..09d140445e 100644 --- a/web/i18n/fr-FR/workflow.json +++ b/web/i18n/fr-FR/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "mise à jour du flux de travail", "error.startNodeRequired": "Veuillez d'abord ajouter un nœud de départ avant {{operation}}", "errorMsg.authRequired": "Autorisation requise", + "errorMsg.configureModel": "Configurez un modèle", "errorMsg.fieldRequired": "{{field}} est requis", "errorMsg.fields.code": "Code", "errorMsg.fields.model": "Modèle", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Vision Variable", "errorMsg.invalidJson": "{{field}} est un JSON invalide", "errorMsg.invalidVariable": "Variable invalide", + "errorMsg.modelPluginNotInstalled": "Variable invalide. Configurez un modèle pour activer cette variable.", "errorMsg.noValidTool": "{{field}} aucun outil valide sélectionné", "errorMsg.rerankModelRequired": "Avant d’activer le modèle de reclassement, veuillez confirmer que le modèle a été correctement configuré dans les paramètres.", "errorMsg.startNodeRequired": "Veuillez d'abord ajouter un nœud de départ avant {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Taille de la fenêtre", "nodes.common.outputVars": "Variables de sortie", "nodes.common.pluginNotInstalled": "Le plugin n'est pas installé", + "nodes.common.pluginsNotInstalled": "{{count}} plugins non installés", "nodes.common.retry.maxRetries": "Nombre maximal de tentatives", "nodes.common.retry.ms": "ms", "nodes.common.retry.retries": "{{num}} Tentatives", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Morceaux", "nodes.knowledgeBase.chunksInputTip": "La variable d'entrée du nœud de la base de connaissances est Chunks. Le type de variable est un objet avec un schéma JSON spécifique qui doit être cohérent avec la structure de morceau sélectionnée.", "nodes.knowledgeBase.chunksVariableIsRequired": "La variable Chunks est requise", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API Key indisponible", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Crédits épuisés", + "nodes.knowledgeBase.embeddingModelIncompatible": "Incompatible", "nodes.knowledgeBase.embeddingModelIsInvalid": "Le modèle d'intégration est invalide", - "nodes.knowledgeBase.embeddingModelIsRequired": "Un modèle d'intégration est requis", + "nodes.knowledgeBase.embeddingModelIsRequired": "Un modèle d’intégration est requis", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Modèle d’embedding non configuré", "nodes.knowledgeBase.indexMethodIsRequired": "La méthode d’indexation est requise", + "nodes.knowledgeBase.notConfigured": "Non configuré", "nodes.knowledgeBase.rerankingModelIsInvalid": "Le modèle de rerank est invalide", "nodes.knowledgeBase.rerankingModelIsRequired": "Un modèle de rerankage est requis", "nodes.knowledgeBase.retrievalSettingIsRequired": "Le paramètre de récupération est requis", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Prend en charge uniquement Jinja2", "nodes.templateTransform.inputVars": "Variables de saisie", "nodes.templateTransform.outputVars.output": "Contenu transformé", + "nodes.tool.authorizationRequired": "Autorisation requise", "nodes.tool.authorize": "Autoriser", "nodes.tool.inputVars": "Variables de saisie", "nodes.tool.insertPlaceholder1": "Tapez ou appuyez", @@ -1062,10 +1071,12 @@ "panel.change": "Modifier", "panel.changeBlock": "Changer de nœud", "panel.checklist": "Liste de contrôle", + "panel.checklistDescription": "Résolvez les problèmes suivants avant de publier", "panel.checklistResolved": "Tous les problèmes ont été résolus", "panel.checklistTip": "Assurez-vous que tous les problèmes sont résolus avant de publier", "panel.createdBy": "Créé par", "panel.goTo": "Aller à", + "panel.goToFix": "Aller corriger", "panel.helpLink": "Aide", "panel.maximize": "Maximiser le Canvas", "panel.minimize": "Sortir du mode plein écran", diff --git a/web/i18n/hi-IN/app-debug.json b/web/i18n/hi-IN/app-debug.json index 97e733e167..f9d438f0b1 100644 --- a/web/i18n/hi-IN/app-debug.json +++ b/web/i18n/hi-IN/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "चालू करें", "inputs.title": "डिबग और पूर्वावलोकन", "inputs.userInputField": "उपयोगकर्ता इनपुट फ़ील्ड", + "manageModels": "मॉडल प्रबंधित करें", "modelConfig.modeType.chat": "चैट", "modelConfig.modeType.completion": "पूर्ण", "modelConfig.model": "मॉडल", "modelConfig.setTone": "प्रतिक्रियाओं की टोन सेट करें", "modelConfig.title": "मॉडल और पैरामीटर", + "noModelProviderConfigured": "कोई मॉडल प्रदाता कॉन्फ़िगर नहीं है", + "noModelProviderConfiguredTip": "शुरू करने के लिए एक मॉडल प्रदाता इंस्टॉल या कॉन्फ़िगर करें।", + "noModelSelected": "कोई मॉडल चयनित नहीं है", + "noModelSelectedTip": "जारी रखने के लिए ऊपर एक मॉडल कॉन्फ़िगर करें।", "noResult": "प्रदर्शन यहाँ होगा।", "notSetAPIKey.description": "एलएलएम प्रदाता कुंजी सेट नहीं की गई है, और डीबग करने से पहले इसे सेट करने की आवश्यकता है।", "notSetAPIKey.settingBtn": "सेटिंग्स पर जाएं", diff --git a/web/i18n/hi-IN/common.json b/web/i18n/hi-IN/common.json index 75ac76add8..e61c96ca45 100644 --- a/web/i18n/hi-IN/common.json +++ b/web/i18n/hi-IN/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "अअनधिकारित", "modelProvider.buyQuota": "कोटा खरीदें", "modelProvider.callTimes": "कॉल समय", + "modelProvider.card.aiCreditsInUse": "AI credits उपयोग में हैं", + "modelProvider.card.aiCreditsOption": "AI credits", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "API key आवश्यक है", + "modelProvider.card.apiKeyUnavailableFallback": "API Key अनुपलब्ध, AI credits का उपयोग हो रहा है", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "वापस स्विच करने के लिए अपना API key कॉन्फ़िगरेशन जाँचें", "modelProvider.card.buyQuota": "कोटा खरीदें", "modelProvider.card.callTimes": "कॉल समय", + "modelProvider.card.creditsExhaustedDescription": "कृपया अपना प्लान अपग्रेड करें या API key कॉन्फ़िगर करें", + "modelProvider.card.creditsExhaustedFallback": "AI credits समाप्त, API Key का उपयोग हो रहा है", + "modelProvider.card.creditsExhaustedFallbackDescription": "AI credit प्राथमिकता फिर से शुरू करने के लिए अपना प्लान अपग्रेड करें।", + "modelProvider.card.creditsExhaustedMessage": "AI credits समाप्त हो गए हैं", "modelProvider.card.modelAPI": "{{modelName}} मॉडल API कुंजी का उपयोग कर रहे हैं।", "modelProvider.card.modelNotSupported": "{{modelName}} मॉडल इंस्टॉल नहीं हैं।", "modelProvider.card.modelSupported": "{{modelName}} मॉडल इस कोटा का उपयोग कर रहे हैं।", + "modelProvider.card.noApiKeysDescription": "अपने स्वयं के मॉडल क्रेडेंशियल का उपयोग शुरू करने के लिए API key जोड़ें।", + "modelProvider.card.noApiKeysFallback": "कोई API key नहीं, AI credits का उपयोग हो रहा है", + "modelProvider.card.noApiKeysTitle": "अभी तक कोई API key कॉन्फ़िगर नहीं है", + "modelProvider.card.noAvailableUsage": "कोई उपलब्ध उपयोग नहीं", "modelProvider.card.onTrial": "परीक्षण पर", "modelProvider.card.paid": "भुगतान किया हुआ", "modelProvider.card.priorityUse": "प्राथमिकता उपयोग", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "API कुंजी निकालें", "modelProvider.card.tip": "संदेश क्रेडिट {{modelNames}} के मॉडल का समर्थन करते हैं। भुगतान किए गए कोटा को प्राथमिकता दी जाएगी। भुगतान किए गए कोटा के समाप्त होने के बाद मुफ्त कोटा का उपयोग किया जाएगा।", "modelProvider.card.tokens": "टोकन", + "modelProvider.card.unavailable": "अनुपलब्ध", + "modelProvider.card.upgradePlan": "अपना प्लान अपग्रेड करें", + "modelProvider.card.usageLabel": "उपयोग", + "modelProvider.card.usagePriority": "उपयोग प्राथमिकता", + "modelProvider.card.usagePriorityTip": "मॉडल चलाते समय पहले किस संसाधन का उपयोग करना है, यह सेट करें।", "modelProvider.collapse": "संक्षिप्त करें", "modelProvider.config": "कॉन्फ़िग", "modelProvider.configLoadBalancing": "लोड बैलेंसिंग कॉन्फ़िग करें", @@ -387,9 +406,11 @@ "modelProvider.model": "मॉडल", "modelProvider.modelAndParameters": "मॉडल और पैरामीटर", "modelProvider.modelHasBeenDeprecated": "यह मॉडल अप्रचलित हो गया है", + "modelProvider.modelSettings": "मॉडल सेटिंग्स", "modelProvider.models": "मॉडल्स", "modelProvider.modelsNum": "{{num}} मॉडल्स", "modelProvider.noModelFound": "{{model}} के लिए कोई मॉडल नहीं मिला", + "modelProvider.noneConfigured": "एप्लिकेशन चलाने के लिए एक डिफ़ॉल्ट सिस्टम मॉडल कॉन्फ़िगर करें", "modelProvider.notConfigured": "सिस्टम मॉडल को अभी पूरी तरह से कॉन्फ़िगर नहीं किया गया है, और कुछ कार्य उपलब्ध नहीं हो सकते हैं।", "modelProvider.parameters": "पैरामीटर", "modelProvider.parametersInvalidRemoved": "कुछ पैरामीटर अमान्य हैं और हटा दिए गए हैं", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "{{date}} को रीसेट करें", "modelProvider.searchModel": "खोज मॉडल", "modelProvider.selectModel": "अपने मॉडल का चयन करें", + "modelProvider.selector.aiCredits": "AI credits", + "modelProvider.selector.apiKeyUnavailable": "API Key अनुपलब्ध", + "modelProvider.selector.apiKeyUnavailableTip": "API key हटा दी गई है। कृपया एक नई API key कॉन्फ़िगर करें।", + "modelProvider.selector.configure": "कॉन्फ़िगर करें", + "modelProvider.selector.configureRequired": "कॉन्फ़िगरेशन आवश्यक", + "modelProvider.selector.creditsExhausted": "क्रेडिट समाप्त", + "modelProvider.selector.creditsExhaustedTip": "आपके AI credits समाप्त हो गए हैं। कृपया अपना प्लान अपग्रेड करें या API key जोड़ें।", + "modelProvider.selector.disabled": "अक्षम", + "modelProvider.selector.discoverMoreInMarketplace": "Marketplace में और खोजें", "modelProvider.selector.emptySetting": "कॉन्फ़िगर करने के लिए कृपया सेटिंग्स पर जाएं", "modelProvider.selector.emptyTip": "कोई उपलब्ध मॉडल नहीं", + "modelProvider.selector.fromMarketplace": "Marketplace से", + "modelProvider.selector.incompatible": "असंगत", + "modelProvider.selector.incompatibleTip": "यह मॉडल वर्तमान संस्करण में उपलब्ध नहीं है। कृपया कोई अन्य उपलब्ध मॉडल चुनें।", + "modelProvider.selector.install": "इंस्टॉल करें", + "modelProvider.selector.modelProviderSettings": "मॉडल प्रदाता सेटिंग्स", + "modelProvider.selector.noProviderConfigured": "कोई मॉडल प्रदाता कॉन्फ़िगर नहीं है", + "modelProvider.selector.noProviderConfiguredDesc": "इंस्टॉल करने के लिए Marketplace ब्राउज़ करें, या सेटिंग्स में प्रदाता कॉन्फ़िगर करें।", + "modelProvider.selector.onlyCompatibleModelsShown": "केवल संगत मॉडल दिखाए गए हैं", "modelProvider.selector.rerankTip": "कृपया रीरैंक मॉडल सेट करें", "modelProvider.selector.tip": "इस मॉडल को हटा दिया गया है। कृपया एक मॉडल जोड़ें या किसी अन्य मॉडल का चयन करें।", "modelProvider.setupModelFirst": "कृपया पहले अपना मॉडल सेट करें", diff --git a/web/i18n/hi-IN/plugin.json b/web/i18n/hi-IN/plugin.json index 5a16c2676e..8d3a1c2d1d 100644 --- a/web/i18n/hi-IN/plugin.json +++ b/web/i18n/hi-IN/plugin.json @@ -3,6 +3,7 @@ "action.delete": "प्लगइन हटाएं", "action.deleteContentLeft": "क्या आप हटाना चाहेंगे", "action.deleteContentRight": "प्लगइन?", + "action.deleteSuccess": "प्लगइन सफलतापूर्वक हटाया गया", "action.pluginInfo": "प्लगइन जानकारी", "action.usedInApps": "यह प्लगइन {{num}} ऐप्स में उपयोग किया जा रहा है।", "allCategories": "सभी श्रेणियाँ", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "स्थापित करें", "detailPanel.operation.remove": "हटाएं", "detailPanel.operation.update": "अपडेट", + "detailPanel.operation.updateTooltip": "नवीनतम मॉडल तक पहुँचने के लिए अपडेट करें।", "detailPanel.operation.viewDetail": "विवरण देखें", "detailPanel.serviceOk": "सेवा ठीक है", "detailPanel.strategyNum": "{{num}} {{strategy}} शामिल", @@ -231,12 +233,18 @@ "source.local": "स्थानीय पैकेज फ़ाइल", "source.marketplace": "बाजार", "task.clearAll": "सभी साफ करें", + "task.errorMsg.github": "यह प्लगइन स्वचालित रूप से इंस्टॉल नहीं हो सका।\nकृपया इसे GitHub से इंस्टॉल करें।", + "task.errorMsg.marketplace": "यह प्लगइन स्वचालित रूप से इंस्टॉल नहीं हो सका।\nकृपया इसे Marketplace से इंस्टॉल करें।", + "task.errorMsg.unknown": "यह प्लगइन इंस्टॉल नहीं हो सका।\nप्लगइन स्रोत की पहचान नहीं हो सकी।", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} प्लगइन्स स्थापित करने में विफल रहे, देखने के लिए क्लिक करें", + "task.installFromGithub": "GitHub से इंस्टॉल करें", + "task.installFromMarketplace": "Marketplace से इंस्टॉल करें", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} प्लगइन्स स्थापित करने में विफल रहे", "task.installing": "प्लगइन्स स्थापित कर रहे हैं।", + "task.installingHint": "इंस्टॉल हो रहा है... इसमें कुछ मिनट लग सकते हैं।", "task.installingWithError": "{{installingLength}} प्लगइन्स स्थापित कर रहे हैं, {{successLength}} सफल, {{errorLength}} विफल", "task.installingWithSuccess": "{{installingLength}} प्लगइन्स स्थापित कर रहे हैं, {{successLength}} सफल।", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/hi-IN/workflow.json b/web/i18n/hi-IN/workflow.json index 31a3d4627f..fb9256536e 100644 --- a/web/i18n/hi-IN/workflow.json +++ b/web/i18n/hi-IN/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "वर्कफ़्लो को अपडेट करना", "error.startNodeRequired": "कृपया {{operation}} से पहले एक प्रारंभ नोड जोड़ें", "errorMsg.authRequired": "प्राधिकरण आवश्यक है", + "errorMsg.configureModel": "एक मॉडल कॉन्फ़िगर करें", "errorMsg.fieldRequired": "{{field}} आवश्यक है", "errorMsg.fields.code": "कोड", "errorMsg.fields.model": "मॉडल", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "दृष्टि चर", "errorMsg.invalidJson": "{{field}} अमान्य JSON है", "errorMsg.invalidVariable": "अमान्य वेरिएबल", + "errorMsg.modelPluginNotInstalled": "अमान्य वेरिएबल। इस वेरिएबल को सक्षम करने के लिए एक मॉडल कॉन्फ़िगर करें।", "errorMsg.noValidTool": "{{field}} कोई मान्य उपकरण चयनित नहीं किया गया", "errorMsg.rerankModelRequired": "Rerank मॉडल चालू करने से पहले, कृपया पुष्टि करें कि मॉडल को सेटिंग्स में सफलतापूर्वक कॉन्फ़िगर किया गया है।", "errorMsg.startNodeRequired": "कृपया {{operation}} से पहले पहले एक स्टार्ट नोड जोड़ें", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "विंडो साइज", "nodes.common.outputVars": "आउटपुट वेरिएबल्स", "nodes.common.pluginNotInstalled": "प्लगइन इंस्टॉल नहीं है", + "nodes.common.pluginsNotInstalled": "{{count}} प्लगइन इंस्टॉल नहीं हैं", "nodes.common.retry.maxRetries": "अधिकतम पुनः प्रयास करता है", "nodes.common.retry.ms": "सुश्री", "nodes.common.retry.retries": "{{num}} पुनर्प्रयास", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "टुकड़े", "nodes.knowledgeBase.chunksInputTip": "ज्ञान आधार नोड का इनपुट वेरिएबल टुकड़े है। वेरिएबल प्रकार एक ऑब्जेक्ट है जिसमें एक विशेष JSON स्कीमा है जो चयनित चंक संरचना के साथ सुसंगत होना चाहिए।", "nodes.knowledgeBase.chunksVariableIsRequired": "टुकड़े चर आवश्यक है", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API key अनुपलब्ध", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "क्रेडिट समाप्त", + "nodes.knowledgeBase.embeddingModelIncompatible": "असंगत", "nodes.knowledgeBase.embeddingModelIsInvalid": "एम्बेडिंग मॉडल अमान्य है", "nodes.knowledgeBase.embeddingModelIsRequired": "एम्बेडिंग मॉडल आवश्यक है", + "nodes.knowledgeBase.embeddingModelNotConfigured": "एम्बेडिंग मॉडल कॉन्फ़िगर नहीं है", "nodes.knowledgeBase.indexMethodIsRequired": "सूची विधि आवश्यक है", + "nodes.knowledgeBase.notConfigured": "कॉन्फ़िगर नहीं है", "nodes.knowledgeBase.rerankingModelIsInvalid": "पुनः क्रमांकन मॉडल अमान्य है", "nodes.knowledgeBase.rerankingModelIsRequired": "पुनः क्रमांकन मॉडल की आवश्यकता है", "nodes.knowledgeBase.retrievalSettingIsRequired": "पुनप्राप्ति सेटिंग आवश्यक है", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "केवल Jinja2 का समर्थन करता है", "nodes.templateTransform.inputVars": "इनपुट वेरिएबल्स", "nodes.templateTransform.outputVars.output": "रूपांतरित सामग्री", + "nodes.tool.authorizationRequired": "प्राधिकरण आवश्यक", "nodes.tool.authorize": "अधिकृत करें", "nodes.tool.inputVars": "इनपुट वेरिएबल्स", "nodes.tool.insertPlaceholder1": "टाइप करें या दबाएँ", @@ -1062,10 +1071,12 @@ "panel.change": "बदलें", "panel.changeBlock": "नोड बदलें", "panel.checklist": "चेकलिस्ट", + "panel.checklistDescription": "प्रकाशित करने से पहले निम्नलिखित समस्याएँ हल करें", "panel.checklistResolved": "सभी समस्याएं हल हो गई हैं", "panel.checklistTip": "प्रकाशित करने से पहले सुनिश्चित करें कि सभी समस्याएं हल हो गई हैं", "panel.createdBy": "द्वारा बनाया गया ", "panel.goTo": "जाओ", + "panel.goToFix": "ठीक करने जाएँ", "panel.helpLink": "सहायता", "panel.maximize": "कैनवास का अधिकतम लाभ उठाएँ", "panel.minimize": "पूर्ण स्क्रीन से बाहर निकलें", diff --git a/web/i18n/id-ID/app-debug.json b/web/i18n/id-ID/app-debug.json index 21651349ba..feb0f0a296 100644 --- a/web/i18n/id-ID/app-debug.json +++ b/web/i18n/id-ID/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "Jalankan", "inputs.title": "Debug & Pratinjau", "inputs.userInputField": "Bidang Input Pengguna", + "manageModels": "Kelola model", "modelConfig.modeType.chat": "Mengobrol", "modelConfig.modeType.completion": "Lengkap", "modelConfig.model": "Pola", "modelConfig.setTone": "Atur nada respons", "modelConfig.title": "Model dan Parameter", + "noModelProviderConfigured": "Belum ada penyedia model yang dikonfigurasi", + "noModelProviderConfiguredTip": "Instal atau konfigurasi penyedia model untuk memulai.", + "noModelSelected": "Belum ada model yang dipilih", + "noModelSelectedTip": "Konfigurasi model di atas untuk melanjutkan.", "noResult": "Output akan ditampilkan di sini.", "notSetAPIKey.description": "Kunci penyedia LLM belum diatur, dan perlu diatur sebelum debugging.", "notSetAPIKey.settingBtn": "Buka pengaturan", diff --git a/web/i18n/id-ID/common.json b/web/i18n/id-ID/common.json index 90531af712..51cd429992 100644 --- a/web/i18n/id-ID/common.json +++ b/web/i18n/id-ID/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Sah", "modelProvider.buyQuota": "Beli Kuota", "modelProvider.callTimes": "Waktu panggilan", + "modelProvider.card.aiCreditsInUse": "Kredit AI sedang digunakan", + "modelProvider.card.aiCreditsOption": "Kredit AI", + "modelProvider.card.apiKeyOption": "Kunci API", + "modelProvider.card.apiKeyRequired": "Kunci API diperlukan", + "modelProvider.card.apiKeyUnavailableFallback": "Kunci API tidak tersedia, kini menggunakan kredit AI", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Periksa konfigurasi kunci API Anda untuk beralih kembali", "modelProvider.card.buyQuota": "Beli Kuota", "modelProvider.card.callTimes": "Waktu panggilan", + "modelProvider.card.creditsExhaustedDescription": "Silakan tingkatkan paket Anda atau konfigurasikan kunci API", + "modelProvider.card.creditsExhaustedFallback": "Kredit AI habis, kini menggunakan kunci API", + "modelProvider.card.creditsExhaustedFallbackDescription": "Tingkatkan paket Anda untuk melanjutkan prioritas kredit AI.", + "modelProvider.card.creditsExhaustedMessage": "Kredit AI telah habis", "modelProvider.card.modelAPI": "Model {{modelName}} menggunakan Kunci API.", "modelProvider.card.modelNotSupported": "Model {{modelName}} tidak terpasang.", "modelProvider.card.modelSupported": "Model {{modelName}} menggunakan kuota ini.", + "modelProvider.card.noApiKeysDescription": "Tambahkan kunci API untuk mulai menggunakan kredensial model Anda sendiri.", + "modelProvider.card.noApiKeysFallback": "Tidak ada kunci API, menggunakan kredit AI sebagai gantinya", + "modelProvider.card.noApiKeysTitle": "Belum ada kunci API yang dikonfigurasi", + "modelProvider.card.noAvailableUsage": "Tidak ada penggunaan yang tersedia", "modelProvider.card.onTrial": "Sedang Diadili", "modelProvider.card.paid": "Dibayar", "modelProvider.card.priorityUse": "Penggunaan prioritas", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Menghapus Kunci API", "modelProvider.card.tip": "Kredit pesan mendukung model dari {{modelNames}}. Prioritas akan diberikan pada kuota yang dibayarkan. Kuota gratis akan digunakan setelah kuota yang dibayarkan habis.", "modelProvider.card.tokens": "Token", + "modelProvider.card.unavailable": "Tidak tersedia", + "modelProvider.card.upgradePlan": "tingkatkan paket Anda", + "modelProvider.card.usageLabel": "Penggunaan", + "modelProvider.card.usagePriority": "Prioritas Penggunaan", + "modelProvider.card.usagePriorityTip": "Tentukan sumber daya mana yang digunakan terlebih dahulu saat menjalankan model.", "modelProvider.collapse": "Roboh", "modelProvider.config": "Konfigurasi", "modelProvider.configLoadBalancing": "Penyeimbangan Beban Konfigurasi", @@ -387,9 +406,11 @@ "modelProvider.model": "Pola", "modelProvider.modelAndParameters": "Model dan Parameter", "modelProvider.modelHasBeenDeprecated": "Model ini tidak digunakan lagi", + "modelProvider.modelSettings": "Pengaturan Model", "modelProvider.models": "Model", "modelProvider.modelsNum": "Model {{num}}", "modelProvider.noModelFound": "Tidak ditemukan model untuk {{model}}", + "modelProvider.noneConfigured": "Konfigurasikan model sistem default untuk menjalankan aplikasi", "modelProvider.notConfigured": "Model sistem belum sepenuhnya dikonfigurasi", "modelProvider.parameters": "PARAMETER", "modelProvider.parametersInvalidRemoved": "Beberapa parameter tidak valid dan telah dihapus", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Setel ulang pada {{date}}", "modelProvider.searchModel": "Model pencarian", "modelProvider.selectModel": "Pilih model Anda", + "modelProvider.selector.aiCredits": "Kredit AI", + "modelProvider.selector.apiKeyUnavailable": "Kunci API tidak tersedia", + "modelProvider.selector.apiKeyUnavailableTip": "Kunci API telah dihapus. Silakan konfigurasikan kunci API baru.", + "modelProvider.selector.configure": "Konfigurasikan", + "modelProvider.selector.configureRequired": "Konfigurasi diperlukan", + "modelProvider.selector.creditsExhausted": "Kredit habis", + "modelProvider.selector.creditsExhaustedTip": "Kredit AI Anda telah habis. Silakan tingkatkan paket Anda atau tambahkan kunci API.", + "modelProvider.selector.disabled": "Dinonaktifkan", + "modelProvider.selector.discoverMoreInMarketplace": "Temukan lebih banyak di Marketplace", "modelProvider.selector.emptySetting": "Silakan buka pengaturan untuk mengonfigurasi", "modelProvider.selector.emptyTip": "Tidak ada model yang tersedia", + "modelProvider.selector.fromMarketplace": "Dari Marketplace", + "modelProvider.selector.incompatible": "Tidak kompatibel", + "modelProvider.selector.incompatibleTip": "Model ini tidak tersedia dalam versi saat ini. Silakan pilih model lain yang tersedia.", + "modelProvider.selector.install": "Instal", + "modelProvider.selector.modelProviderSettings": "Pengaturan Penyedia Model", + "modelProvider.selector.noProviderConfigured": "Belum ada penyedia model yang dikonfigurasi", + "modelProvider.selector.noProviderConfiguredDesc": "Jelajahi Marketplace untuk menginstal, atau konfigurasikan penyedia di pengaturan.", + "modelProvider.selector.onlyCompatibleModelsShown": "Hanya model yang kompatibel yang ditampilkan", "modelProvider.selector.rerankTip": "Silakan atur model Rerank", "modelProvider.selector.tip": "Model ini telah dihapus. Silakan tambahkan model atau pilih model lain.", "modelProvider.setupModelFirst": "Silakan atur model Anda terlebih dahulu", diff --git a/web/i18n/id-ID/plugin.json b/web/i18n/id-ID/plugin.json index 486de762f8..6b9c8f51af 100644 --- a/web/i18n/id-ID/plugin.json +++ b/web/i18n/id-ID/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Hapus plugin", "action.deleteContentLeft": "Apakah Anda ingin menghapus", "action.deleteContentRight": "Plugin?", + "action.deleteSuccess": "Plugin berhasil dihapus", "action.pluginInfo": "Info plugin", "action.usedInApps": "Plugin ini digunakan di {{num}} aplikasi.", "allCategories": "Semua Kategori", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Pasang", "detailPanel.operation.remove": "Hapus", "detailPanel.operation.update": "Pemutakhiran", + "detailPanel.operation.updateTooltip": "Perbarui untuk mengakses model terbaru.", "detailPanel.operation.viewDetail": "Lihat Detail", "detailPanel.serviceOk": "Layanan OK", "detailPanel.strategyNum": "{{num}} {{strategy}} TERMASUK", @@ -231,12 +233,18 @@ "source.local": "File Paket Lokal", "source.marketplace": "Pasar", "task.clearAll": "Hapus semua", + "task.errorMsg.github": "Plugin ini tidak terinstal secara otomatis.\nSilakan instal dari GitHub.", + "task.errorMsg.marketplace": "Plugin ini tidak terinstal secara otomatis.\nSilakan instal dari Marketplace.", + "task.errorMsg.unknown": "Plugin ini tidak terinstal.\nSumber plugin tidak dapat diidentifikasi.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "Gagal menginstal plugin {{errorLength}}, klik untuk melihat", + "task.installFromGithub": "Instal dari GitHub", + "task.installFromMarketplace": "Instal dari Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "Gagal menginstal {{errorLength}} plugin", "task.installing": "Memasang plugin.", + "task.installingHint": "Menginstal... Ini mungkin memerlukan beberapa menit.", "task.installingWithError": "Memasang {{installingLength}} plugin, {{successLength}} berhasil, {{errorLength}} gagal", "task.installingWithSuccess": "Memasang plugin {{installingLength}}, {{successLength}} berhasil.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/id-ID/workflow.json b/web/i18n/id-ID/workflow.json index 4f8e01b7f1..76e80be7d7 100644 --- a/web/i18n/id-ID/workflow.json +++ b/web/i18n/id-ID/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "memperbarui alur kerja", "error.startNodeRequired": "Silakan tambahkan node awal terlebih dahulu sebelum {{operation}}", "errorMsg.authRequired": "Otorisasi diperlukan", + "errorMsg.configureModel": "Konfigurasikan model", "errorMsg.fieldRequired": "{{field}} wajib diisi", "errorMsg.fields.code": "Kode", "errorMsg.fields.model": "Model", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Variabel Penglihatan", "errorMsg.invalidJson": "{{field}} adalah JSON yang tidak valid", "errorMsg.invalidVariable": "Variabel tidak valid", + "errorMsg.modelPluginNotInstalled": "Variabel tidak valid. Konfigurasikan model untuk mengaktifkan variabel ini.", "errorMsg.noValidTool": "{{field}} tidak ada alat yang valid dipilih", "errorMsg.rerankModelRequired": "Model Rerank yang dikonfigurasi diperlukan", "errorMsg.startNodeRequired": "Silakan tambahkan node awal terlebih dahulu sebelum {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Ukuran Jendela", "nodes.common.outputVars": "Variabel Keluaran", "nodes.common.pluginNotInstalled": "Plugin tidak terpasang", + "nodes.common.pluginsNotInstalled": "{{count}} plugin tidak terpasang", "nodes.common.retry.maxRetries": "percobaan ulang maks", "nodes.common.retry.ms": "Ms", "nodes.common.retry.retries": "{{num}} Percobaan Ulang", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Potongan", "nodes.knowledgeBase.chunksInputTip": "Variabel input dari node basis pengetahuan adalah Chunks. Tipe variabel adalah objek dengan Skema JSON tertentu yang harus konsisten dengan struktur chunk yang dipilih.", "nodes.knowledgeBase.chunksVariableIsRequired": "Variabel Chunks diperlukan", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "Kunci API tidak tersedia", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Kredit habis", + "nodes.knowledgeBase.embeddingModelIncompatible": "Tidak kompatibel", "nodes.knowledgeBase.embeddingModelIsInvalid": "Model embedding tidak valid", "nodes.knowledgeBase.embeddingModelIsRequired": "Model embedding diperlukan", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Model embedding belum dikonfigurasi", "nodes.knowledgeBase.indexMethodIsRequired": "Metode indeks diperlukan", + "nodes.knowledgeBase.notConfigured": "Belum dikonfigurasi", "nodes.knowledgeBase.rerankingModelIsInvalid": "Model reranking tidak valid", "nodes.knowledgeBase.rerankingModelIsRequired": "Model reranking diperlukan", "nodes.knowledgeBase.retrievalSettingIsRequired": "Pengaturan pengambilan diperlukan", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Hanya mendukung Jinja2", "nodes.templateTransform.inputVars": "Variabel Masukan", "nodes.templateTransform.outputVars.output": "Konten yang diubah", + "nodes.tool.authorizationRequired": "Otorisasi diperlukan", "nodes.tool.authorize": "Otorisasi", "nodes.tool.inputVars": "Variabel Masukan", "nodes.tool.insertPlaceholder1": "Ketik atau tekan", @@ -1062,10 +1071,12 @@ "panel.change": "Ubah", "panel.changeBlock": "Ubah Node", "panel.checklist": "Checklist", + "panel.checklistDescription": "Selesaikan masalah berikut sebelum menerbitkan", "panel.checklistResolved": "Semua masalah terselesaikan", "panel.checklistTip": "Pastikan semua masalah diselesaikan sebelum dipublikasikan", "panel.createdBy": "Dibuat oleh", "panel.goTo": "Pergi ke", + "panel.goToFix": "Pergi ke perbaikan", "panel.helpLink": "Docs", "panel.maximize": "Maksimalkan Kanvas", "panel.minimize": "Keluar dari Layar Penuh", diff --git a/web/i18n/it-IT/app-debug.json b/web/i18n/it-IT/app-debug.json index 94e4c00894..b9aad1ff6b 100644 --- a/web/i18n/it-IT/app-debug.json +++ b/web/i18n/it-IT/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "ESEGUI", "inputs.title": "Debug e Anteprima", "inputs.userInputField": "Campo Input Utente", + "manageModels": "Gestisci modelli", "modelConfig.modeType.chat": "Chat", "modelConfig.modeType.completion": "Completamento", "modelConfig.model": "Modello", "modelConfig.setTone": "Imposta tono delle risposte", "modelConfig.title": "Modello e Parametri", + "noModelProviderConfigured": "Nessun fornitore di modelli configurato", + "noModelProviderConfiguredTip": "Installa o configura un fornitore di modelli per iniziare.", + "noModelSelected": "Nessun modello selezionato", + "noModelSelectedTip": "Configura un modello sopra per continuare.", "noResult": "L'output verrà visualizzato qui.", "notSetAPIKey.description": "La chiave del provider LLM non è stata impostata e deve essere impostata prima del debug.", "notSetAPIKey.settingBtn": "Vai alle impostazioni", diff --git a/web/i18n/it-IT/common.json b/web/i18n/it-IT/common.json index d7b57d6d08..283c090ea8 100644 --- a/web/i18n/it-IT/common.json +++ b/web/i18n/it-IT/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Non autorizzato", "modelProvider.buyQuota": "Acquista Quota", "modelProvider.callTimes": "Numero di chiamate", + "modelProvider.card.aiCreditsInUse": "Crediti AI in uso", + "modelProvider.card.aiCreditsOption": "Crediti AI", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "API Key richiesta", + "modelProvider.card.apiKeyUnavailableFallback": "API Key non disponibile, utilizzo dei crediti AI in corso", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Controlla la configurazione della tua API Key per tornare indietro", "modelProvider.card.buyQuota": "Acquista Quota", "modelProvider.card.callTimes": "Numero di chiamate", + "modelProvider.card.creditsExhaustedDescription": "Aggiorna il tuo piano o configura una API Key", + "modelProvider.card.creditsExhaustedFallback": "Crediti AI esauriti, utilizzo della API Key in corso", + "modelProvider.card.creditsExhaustedFallbackDescription": "Aggiorna il tuo piano per ripristinare la priorità dei crediti AI.", + "modelProvider.card.creditsExhaustedMessage": "I crediti AI sono esauriti", "modelProvider.card.modelAPI": "I modelli {{modelName}} stanno utilizzando la chiave API.", "modelProvider.card.modelNotSupported": "I modelli {{modelName}} non sono installati.", "modelProvider.card.modelSupported": "I modelli {{modelName}} stanno utilizzando questa quota.", + "modelProvider.card.noApiKeysDescription": "Aggiungi una API Key per iniziare a usare le tue credenziali del modello.", + "modelProvider.card.noApiKeysFallback": "Nessuna API Key, utilizzo dei crediti AI in corso", + "modelProvider.card.noApiKeysTitle": "Nessuna API Key ancora configurata", + "modelProvider.card.noAvailableUsage": "Nessun utilizzo disponibile", "modelProvider.card.onTrial": "In Prova", "modelProvider.card.paid": "Pagato", "modelProvider.card.priorityUse": "Uso prioritario", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Rimuovi API Key", "modelProvider.card.tip": "I crediti di messaggi supportano modelli di {{modelNames}}. Verrà data priorità alla quota pagata. La quota gratuita sarà utilizzata dopo l'esaurimento della quota pagata.", "modelProvider.card.tokens": "Token", + "modelProvider.card.unavailable": "Non disponibile", + "modelProvider.card.upgradePlan": "aggiorna il tuo piano", + "modelProvider.card.usageLabel": "Utilizzo", + "modelProvider.card.usagePriority": "Priorità di utilizzo", + "modelProvider.card.usagePriorityTip": "Imposta quale risorsa utilizzare per prima durante l'esecuzione dei modelli.", "modelProvider.collapse": "Comprimi", "modelProvider.config": "Configura", "modelProvider.configLoadBalancing": "Configura Bilanciamento del Carico", @@ -387,9 +406,11 @@ "modelProvider.model": "Modello", "modelProvider.modelAndParameters": "Modello e Parametri", "modelProvider.modelHasBeenDeprecated": "Questo modello è stato deprecato", + "modelProvider.modelSettings": "Impostazioni modello", "modelProvider.models": "Modelli", "modelProvider.modelsNum": "{{num}} Modelli", "modelProvider.noModelFound": "Nessun modello trovato per {{model}}", + "modelProvider.noneConfigured": "Configura un modello di sistema predefinito per eseguire le applicazioni", "modelProvider.notConfigured": "Il modello di sistema non è ancora stato completamente configurato e alcune funzioni potrebbero non essere disponibili.", "modelProvider.parameters": "PARAMETRI", "modelProvider.parametersInvalidRemoved": "Alcuni parametri non sono validi e sono stati rimossi.", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Ripristina il {{date}}", "modelProvider.searchModel": "Modello di ricerca", "modelProvider.selectModel": "Seleziona il tuo modello", + "modelProvider.selector.aiCredits": "Crediti AI", + "modelProvider.selector.apiKeyUnavailable": "API Key non disponibile", + "modelProvider.selector.apiKeyUnavailableTip": "La API Key è stata rimossa. Configura una nuova API Key.", + "modelProvider.selector.configure": "Configura", + "modelProvider.selector.configureRequired": "Configurazione richiesta", + "modelProvider.selector.creditsExhausted": "Crediti esauriti", + "modelProvider.selector.creditsExhaustedTip": "I tuoi crediti AI sono esauriti. Aggiorna il tuo piano o aggiungi una API Key.", + "modelProvider.selector.disabled": "Disabilitato", + "modelProvider.selector.discoverMoreInMarketplace": "Scopri di più nel Marketplace", "modelProvider.selector.emptySetting": "Per favore vai alle impostazioni per configurare", "modelProvider.selector.emptyTip": "Nessun modello disponibile", + "modelProvider.selector.fromMarketplace": "Dal Marketplace", + "modelProvider.selector.incompatible": "Incompatibile", + "modelProvider.selector.incompatibleTip": "Questo modello non è disponibile nella versione corrente. Seleziona un altro modello disponibile.", + "modelProvider.selector.install": "Installa", + "modelProvider.selector.modelProviderSettings": "Impostazioni fornitore modelli", + "modelProvider.selector.noProviderConfigured": "Nessun fornitore di modelli configurato", + "modelProvider.selector.noProviderConfiguredDesc": "Cerca nel Marketplace per installarne uno o configura i fornitori nelle impostazioni.", + "modelProvider.selector.onlyCompatibleModelsShown": "Vengono mostrati solo i modelli compatibili", "modelProvider.selector.rerankTip": "Per favore, configura il modello di Rerank", "modelProvider.selector.tip": "Questo modello è stato rimosso. Per favore aggiungi un modello o seleziona un altro modello.", "modelProvider.setupModelFirst": "Per favore, configura prima il tuo modello", diff --git a/web/i18n/it-IT/plugin.json b/web/i18n/it-IT/plugin.json index 06a2dfa4ab..296aa31d54 100644 --- a/web/i18n/it-IT/plugin.json +++ b/web/i18n/it-IT/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Rimuovi plugin", "action.deleteContentLeft": "Vorresti rimuovere", "action.deleteContentRight": "plugin?", + "action.deleteSuccess": "Plugin rimosso con successo", "action.pluginInfo": "Informazioni sul plugin", "action.usedInApps": "Questo plugin viene utilizzato nelle app {{num}}.", "allCategories": "Tutte le categorie", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Installare", "detailPanel.operation.remove": "Togliere", "detailPanel.operation.update": "Aggiornare", + "detailPanel.operation.updateTooltip": "Aggiorna per accedere ai modelli più recenti.", "detailPanel.operation.viewDetail": "vedi dettagli", "detailPanel.serviceOk": "Servizio OK", "detailPanel.strategyNum": "{{num}} {{strategy}} INCLUSO", @@ -231,12 +233,18 @@ "source.local": "File del pacchetto locale", "source.marketplace": "Mercato", "task.clearAll": "Cancella tutto", + "task.errorMsg.github": "Impossibile installare automaticamente questo plugin.\nInstallalo da GitHub.", + "task.errorMsg.marketplace": "Impossibile installare automaticamente questo plugin.\nInstallalo dal Marketplace.", + "task.errorMsg.unknown": "Impossibile installare questo plugin.\nNon è stato possibile identificare la fonte del plugin.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "Impossibile installare i plugin {{errorLength}}, clicca per visualizzare", + "task.installFromGithub": "Installa da GitHub", + "task.installFromMarketplace": "Installa dal Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "Impossibile installare i plugin di {{errorLength}}", "task.installing": "Installazione dei plugin.", + "task.installingHint": "Installazione in corso... Potrebbe richiedere qualche minuto.", "task.installingWithError": "Installazione dei plugin {{installingLength}}, {{successLength}} successo, {{errorLength}} fallito", "task.installingWithSuccess": "Installazione dei plugin {{installingLength}}, {{successLength}} successo.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/it-IT/workflow.json b/web/i18n/it-IT/workflow.json index 0184b85009..519d7d7e2a 100644 --- a/web/i18n/it-IT/workflow.json +++ b/web/i18n/it-IT/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "aggiornamento del flusso di lavoro", "error.startNodeRequired": "Per favore aggiungi prima un nodo iniziale prima di {{operation}}", "errorMsg.authRequired": "È richiesta l'autorizzazione", + "errorMsg.configureModel": "Configura un modello", "errorMsg.fieldRequired": "{{field}} è richiesto", "errorMsg.fields.code": "Codice", "errorMsg.fields.model": "Modello", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Visione variabile", "errorMsg.invalidJson": "{{field}} è un JSON non valido", "errorMsg.invalidVariable": "Variabile non valida", + "errorMsg.modelPluginNotInstalled": "Variabile non valida. Configura un modello per abilitare questa variabile.", "errorMsg.noValidTool": "{{field}} nessuno strumento valido selezionato", "errorMsg.rerankModelRequired": "Prima di attivare il modello di reranking, conferma che il modello è stato configurato correttamente nelle impostazioni.", "errorMsg.startNodeRequired": "Per favore aggiungi prima un nodo iniziale prima di {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Dimensione Finestra", "nodes.common.outputVars": "Variabili di Output", "nodes.common.pluginNotInstalled": "Il plugin non è installato", + "nodes.common.pluginsNotInstalled": "{{count}} plugin non installati", "nodes.common.retry.maxRetries": "Numero massimo di tentativi", "nodes.common.retry.ms": "ms", "nodes.common.retry.retries": "{{num}} Tentativi", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Pezzetti", "nodes.knowledgeBase.chunksInputTip": "La variabile di input del nodo della base di conoscenza è Chunks. Il tipo di variabile è un oggetto con uno specifico schema JSON che deve essere coerente con la struttura del chunk selezionato.", "nodes.knowledgeBase.chunksVariableIsRequired": "La variabile Chunks è richiesta", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API Key non disponibile", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Crediti esauriti", + "nodes.knowledgeBase.embeddingModelIncompatible": "Incompatibile", "nodes.knowledgeBase.embeddingModelIsInvalid": "Il modello di embedding non è valido", "nodes.knowledgeBase.embeddingModelIsRequired": "È necessario un modello di embedding", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Modello di embedding non configurato", "nodes.knowledgeBase.indexMethodIsRequired": "È necessario il metodo dell'indice", + "nodes.knowledgeBase.notConfigured": "Non configurato", "nodes.knowledgeBase.rerankingModelIsInvalid": "Il modello di riorganizzazione è non valido", "nodes.knowledgeBase.rerankingModelIsRequired": "È richiesto un modello di riordinamento", "nodes.knowledgeBase.retrievalSettingIsRequired": "È richiesta l'impostazione di recupero", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Supporta solo Jinja2", "nodes.templateTransform.inputVars": "Variabili di Input", "nodes.templateTransform.outputVars.output": "Contenuto trasformato", + "nodes.tool.authorizationRequired": "Autorizzazione richiesta", "nodes.tool.authorize": "Autorizza", "nodes.tool.inputVars": "Variabili di Input", "nodes.tool.insertPlaceholder1": "Digita o premi", @@ -1062,10 +1071,12 @@ "panel.change": "Cambia", "panel.changeBlock": "Cambia Nodo", "panel.checklist": "Checklist", + "panel.checklistDescription": "Risolvi i seguenti problemi prima della pubblicazione", "panel.checklistResolved": "Tutti i problemi sono risolti", "panel.checklistTip": "Assicurati che tutti i problemi siano risolti prima di pubblicare", "panel.createdBy": "Creato da ", "panel.goTo": "Vai a", + "panel.goToFix": "Vai a correggere", "panel.helpLink": "Aiuto", "panel.maximize": "Massimizza Canvas", "panel.minimize": "Esci dalla modalità schermo intero", diff --git a/web/i18n/ja-JP/common.json b/web/i18n/ja-JP/common.json index 98fe556ecf..a65d8e933c 100644 --- a/web/i18n/ja-JP/common.json +++ b/web/i18n/ja-JP/common.json @@ -358,6 +358,7 @@ "modelProvider.card.noApiKeysDescription": "独自のモデル認証情報を使用するには、API キーを追加してください。", "modelProvider.card.noApiKeysFallback": "API キーが未設定のため、AI クレジットを使用しています", "modelProvider.card.noApiKeysTitle": "API キーはまだ設定されていません", + "modelProvider.card.noAvailableUsage": "利用可能な使用量がありません", "modelProvider.card.onTrial": "トライアル中", "modelProvider.card.paid": "有料", "modelProvider.card.priorityUse": "優先利用", @@ -366,6 +367,9 @@ "modelProvider.card.removeKey": "API キーを削除", "modelProvider.card.tip": "メッセージ枠は{{modelNames}}のモデルを使用することをサポートしています。無料枠は有料枠が使い果たされた後に消費されます。", "modelProvider.card.tokens": "トークン", + "modelProvider.card.unavailable": "利用不可", + "modelProvider.card.upgradePlan": "プランをアップグレード", + "modelProvider.card.usageLabel": "使用量", "modelProvider.card.usagePriority": "使用優先順位", "modelProvider.card.usagePriorityTip": "モデル実行時に優先して使用するリソースを設定します。", "modelProvider.collapse": "折り畳み", @@ -402,9 +406,11 @@ "modelProvider.model": "モデル", "modelProvider.modelAndParameters": "モデルとパラメータ", "modelProvider.modelHasBeenDeprecated": "このモデルは廃止予定です", + "modelProvider.modelSettings": "モデル設定", "modelProvider.models": "モデル", "modelProvider.modelsNum": "{{num}}のモデル", "modelProvider.noModelFound": "{{model}}に対するモデルが見つかりません", + "modelProvider.noneConfigured": "アプリケーションを実行するためにデフォルトのシステムモデルを設定してください", "modelProvider.notConfigured": "システムモデルがまだ完全に設定されておらず、一部の機能が利用できない場合があります。", "modelProvider.parameters": "パラメータ", "modelProvider.parametersInvalidRemoved": "いくつかのパラメータが無効であり、削除されました。", @@ -421,14 +427,21 @@ "modelProvider.selector.aiCredits": "AI クレジット", "modelProvider.selector.apiKeyUnavailable": "API キーが利用できません", "modelProvider.selector.apiKeyUnavailableTip": "API キーは削除されました。新しい API キーを設定してください。", + "modelProvider.selector.configure": "設定", "modelProvider.selector.configureRequired": "設定が必要です", "modelProvider.selector.creditsExhausted": "クレジットを使い切りました", "modelProvider.selector.creditsExhaustedTip": "AI クレジットを使い切りました。プランをアップグレードするか、API キーを追加してください。", + "modelProvider.selector.disabled": "無効", + "modelProvider.selector.discoverMoreInMarketplace": "マーケットプレイスでもっと探す", "modelProvider.selector.emptySetting": "設定に移動して構成してください", "modelProvider.selector.emptyTip": "利用可能なモデルはありません", "modelProvider.selector.fromMarketplace": "マーケットプレイスから", "modelProvider.selector.incompatible": "非互換", "modelProvider.selector.incompatibleTip": "このモデルは現在のバージョンでは利用できません。別の利用可能なモデルを選択してください。", + "modelProvider.selector.install": "インストール", + "modelProvider.selector.modelProviderSettings": "モデルプロバイダー設定", + "modelProvider.selector.noProviderConfigured": "モデルプロバイダーが設定されていません", + "modelProvider.selector.noProviderConfiguredDesc": "マーケットプレイスでインストールするか、設定でプロバイダーを設定してください。", "modelProvider.selector.onlyCompatibleModelsShown": "互換性のあるモデルのみが表示されます", "modelProvider.selector.rerankTip": "Rerank モデルを設定してください", "modelProvider.selector.tip": "このモデルは削除されました。別のモデルを追加するか、別のモデルを選択してください。", diff --git a/web/i18n/ja-JP/plugin.json b/web/i18n/ja-JP/plugin.json index c51a0e4117..38645124fb 100644 --- a/web/i18n/ja-JP/plugin.json +++ b/web/i18n/ja-JP/plugin.json @@ -3,6 +3,7 @@ "action.delete": "プラグインを削除する", "action.deleteContentLeft": "削除しますか", "action.deleteContentRight": "プラグイン?", + "action.deleteSuccess": "プラグインが正常に削除されました", "action.pluginInfo": "プラグイン情報", "action.usedInApps": "このプラグインは{{num}}のアプリで使用されています。", "allCategories": "すべてのカテゴリ", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "インストール", "detailPanel.operation.remove": "削除", "detailPanel.operation.update": "更新", + "detailPanel.operation.updateTooltip": "最新のモデルにアクセスするために更新してください。", "detailPanel.operation.viewDetail": "詳細を見る", "detailPanel.serviceOk": "サービスは正常です", "detailPanel.strategyNum": "{{num}} {{strategy}} が含まれています", @@ -231,12 +233,18 @@ "source.local": "ローカルパッケージファイル", "source.marketplace": "マーケットプレイス", "task.clearAll": "すべてクリア", + "task.errorMsg.github": "このプラグインは自動インストールできませんでした。\nGitHub からインストールしてください。", + "task.errorMsg.marketplace": "このプラグインは自動インストールできませんでした。\nマーケットプレイスからインストールしてください。", + "task.errorMsg.unknown": "このプラグインをインストールできませんでした。\nプラグインのソースを特定できませんでした。", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} プラグインのインストールに失敗しました。表示するにはクリックしてください。", + "task.installFromGithub": "GitHub からインストール", + "task.installFromMarketplace": "マーケットプレイスからインストール", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} プラグインのインストールに失敗しました", "task.installing": "プラグインをインストール中。", + "task.installingHint": "インストール中...数分かかる場合があります。", "task.installingWithError": "{{installingLength}}個のプラグインをインストール中、{{successLength}}件成功、{{errorLength}}件失敗", "task.installingWithSuccess": "{{installingLength}}個のプラグインをインストール中、{{successLength}}個成功しました。", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/ja-JP/workflow.json b/web/i18n/ja-JP/workflow.json index a2fac68bad..acf43b8ce8 100644 --- a/web/i18n/ja-JP/workflow.json +++ b/web/i18n/ja-JP/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "ワークフロー更新", "error.startNodeRequired": "{{operation}}前に開始ノードを追加してください", "errorMsg.authRequired": "認証が必要です", + "errorMsg.configureModel": "モデルを設定してください", "errorMsg.fieldRequired": "{{field}} は必須です", "errorMsg.fields.code": "コード", "errorMsg.fields.model": "モデル", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "ビジョン変数", "errorMsg.invalidJson": "{{field}} は無効な JSON です", "errorMsg.invalidVariable": "無効な変数です", + "errorMsg.modelPluginNotInstalled": "無効な変数です。この変数を有効にするにはモデルを設定してください。", "errorMsg.noValidTool": "{{field}} に利用可能なツールがありません", "errorMsg.rerankModelRequired": "Rerank モデルが設定されていません", "errorMsg.startNodeRequired": "{{operation}}前に開始ノードを追加してください", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "メモリウィンドウサイズ", "nodes.common.outputVars": "出力変数", "nodes.common.pluginNotInstalled": "プラグインがインストールされていません", + "nodes.common.pluginsNotInstalled": "{{count}} 個のプラグインがインストールされていません", "nodes.common.retry.maxRetries": "最大試行回数", "nodes.common.retry.ms": "ミリ秒", "nodes.common.retry.retries": "再試行回数:{{num}}", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "チャンク", "nodes.knowledgeBase.chunksInputTip": "知識ベースノードの入力変数はチャンクです。変数のタイプは、選択されたチャンク構造と一貫性のある特定のJSONスキーマを持つオブジェクトです。", "nodes.knowledgeBase.chunksVariableIsRequired": "Chunks変数は必須です", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API キーが利用できません", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "クレジットを使い切りました", + "nodes.knowledgeBase.embeddingModelIncompatible": "非互換", "nodes.knowledgeBase.embeddingModelIsInvalid": "埋め込みモデルが無効です", "nodes.knowledgeBase.embeddingModelIsRequired": "埋め込みモデルが必要です", + "nodes.knowledgeBase.embeddingModelNotConfigured": "埋め込みモデルが設定されていません", "nodes.knowledgeBase.indexMethodIsRequired": "インデックスメソッドが必要です", + "nodes.knowledgeBase.notConfigured": "未設定", "nodes.knowledgeBase.rerankingModelIsInvalid": "リランキングモデルは無効です", "nodes.knowledgeBase.rerankingModelIsRequired": "再ランキングモデルが必要です", "nodes.knowledgeBase.retrievalSettingIsRequired": "リトリーバル設定が必要です", @@ -810,7 +818,7 @@ "nodes.loop.setLoopVariables": "ループスコープ内で変数を設定", "nodes.loop.totalLoopCount": "総ループ回数:{{count}}", "nodes.loop.variableName": "変数名", - "nodes.note.addNote": "コメントを追加", + "nodes.note.addNote": "メモを追加", "nodes.note.editor.bold": "太字", "nodes.note.editor.bulletList": "リスト", "nodes.note.editor.enterUrl": "リンク入力中...", @@ -1063,10 +1071,12 @@ "panel.change": "変更", "panel.changeBlock": "ノード変更", "panel.checklist": "チェックリスト", + "panel.checklistDescription": "公開前に以下の問題を解決してください", "panel.checklistResolved": "全てのチェックが完了しました", "panel.checklistTip": "公開前に全ての項目を確認してください", "panel.createdBy": "作成者", "panel.goTo": "移動", + "panel.goToFix": "修正する", "panel.helpLink": "ドキュメントを見る", "panel.maximize": "キャンバスを最大化する", "panel.minimize": "全画面を終了する", diff --git a/web/i18n/ko-KR/app-debug.json b/web/i18n/ko-KR/app-debug.json index 3cb295a3f7..1f9c1e2420 100644 --- a/web/i18n/ko-KR/app-debug.json +++ b/web/i18n/ko-KR/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "실행", "inputs.title": "디버그 및 미리보기", "inputs.userInputField": "사용자 입력 필드", + "manageModels": "모델 관리", "modelConfig.modeType.chat": "채팅", "modelConfig.modeType.completion": "완료", "modelConfig.model": "모델", "modelConfig.setTone": "응답 톤 설정", "modelConfig.title": "모델 및 매개변수", + "noModelProviderConfigured": "모델 공급자가 구성되지 않았습니다", + "noModelProviderConfiguredTip": "모델 공급자를 설치하거나 구성하여 시작하세요.", + "noModelSelected": "모델이 선택되지 않았습니다", + "noModelSelectedTip": "계속하려면 위에서 모델을 구성하세요.", "noResult": "출력이 여기에 표시됩니다.", "notSetAPIKey.description": "LLM 제공자 키가 설정되지 않았습니다. 디버깅하기 전에 설정해야 합니다.", "notSetAPIKey.settingBtn": "설정으로 이동", diff --git a/web/i18n/ko-KR/common.json b/web/i18n/ko-KR/common.json index 8fa351c517..e50a7c2428 100644 --- a/web/i18n/ko-KR/common.json +++ b/web/i18n/ko-KR/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "무단", "modelProvider.buyQuota": "할당량 구매", "modelProvider.callTimes": "호출 횟수", + "modelProvider.card.aiCreditsInUse": "AI 크레딧 사용 중", + "modelProvider.card.aiCreditsOption": "AI 크레딧", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "API 키 설정 필요", + "modelProvider.card.apiKeyUnavailableFallback": "API Key를 사용할 수 없어 AI 크레딧을 사용 중입니다", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "API Key 설정을 확인하여 다시 전환하세요", "modelProvider.card.buyQuota": "Buy Quota", "modelProvider.card.callTimes": "호출 횟수", + "modelProvider.card.creditsExhaustedDescription": "플랜을 업그레이드하거나 API 키를 설정하세요", + "modelProvider.card.creditsExhaustedFallback": "AI 크레딧이 소진되어 API Key를 사용 중입니다", + "modelProvider.card.creditsExhaustedFallbackDescription": "AI 크레딧 우선 사용을 재개하려면 플랜을 업그레이드하세요.", + "modelProvider.card.creditsExhaustedMessage": "AI 크레딧이 소진되었습니다", "modelProvider.card.modelAPI": "{{modelName}} 모델이 API 키를 사용하고 있습니다.", "modelProvider.card.modelNotSupported": "{{modelName}} 모델이 설치되지 않았습니다.", "modelProvider.card.modelSupported": "{{modelName}} 모델이 이 할당량을 사용하고 있습니다.", + "modelProvider.card.noApiKeysDescription": "자체 모델 자격 증명을 사용하려면 API 키를 추가하세요.", + "modelProvider.card.noApiKeysFallback": "API Key가 없어 AI 크레딧을 사용 중입니다", + "modelProvider.card.noApiKeysTitle": "아직 API 키가 구성되지 않았습니다", + "modelProvider.card.noAvailableUsage": "사용 가능한 용량 없음", "modelProvider.card.onTrial": "트라이얼 중", "modelProvider.card.paid": "유료", "modelProvider.card.priorityUse": "우선 사용", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "API 키 제거", "modelProvider.card.tip": "메시지 크레딧은 {{modelNames}}의 모델을 지원합니다. 유료 할당량에 우선순위가 부여됩니다. 무료 할당량은 유료 할당량이 소진된 후 사용됩니다.", "modelProvider.card.tokens": "토큰", + "modelProvider.card.unavailable": "사용 불가", + "modelProvider.card.upgradePlan": "플랜 업그레이드", + "modelProvider.card.usageLabel": "사용량", + "modelProvider.card.usagePriority": "사용 우선순위", + "modelProvider.card.usagePriorityTip": "모델 실행 시 우선 사용할 리소스를 설정합니다.", "modelProvider.collapse": "축소", "modelProvider.config": "설정", "modelProvider.configLoadBalancing": "Config 로드 밸런싱", @@ -387,9 +406,11 @@ "modelProvider.model": "모델", "modelProvider.modelAndParameters": "모델 및 매개변수", "modelProvider.modelHasBeenDeprecated": "이 모델은 더 이상 사용되지 않습니다", + "modelProvider.modelSettings": "모델 설정", "modelProvider.models": "모델", "modelProvider.modelsNum": "{{num}}개의 모델", "modelProvider.noModelFound": "{{model}}에 대한 모델을 찾을 수 없습니다", + "modelProvider.noneConfigured": "애플리케이션을 실행하려면 기본 시스템 모델을 구성하세요", "modelProvider.notConfigured": "시스템 모델이 아직 완전히 설정되지 않아 일부 기능을 사용할 수 없습니다.", "modelProvider.parameters": "매개변수", "modelProvider.parametersInvalidRemoved": "일부 매개변수가 유효하지 않아 제거되었습니다.", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "{{date}}에 재설정", "modelProvider.searchModel": "검색 모델", "modelProvider.selectModel": "모델 선택", + "modelProvider.selector.aiCredits": "AI 크레딧", + "modelProvider.selector.apiKeyUnavailable": "API Key 사용 불가", + "modelProvider.selector.apiKeyUnavailableTip": "API Key가 삭제되었습니다. 새 API Key를 설정하세요.", + "modelProvider.selector.configure": "구성", + "modelProvider.selector.configureRequired": "구성 필요", + "modelProvider.selector.creditsExhausted": "크레딧 소진", + "modelProvider.selector.creditsExhaustedTip": "AI 크레딧이 소진되었습니다. 플랜을 업그레이드하거나 API 키를 추가하세요.", + "modelProvider.selector.disabled": "비활성화됨", + "modelProvider.selector.discoverMoreInMarketplace": "마켓플레이스에서 더 찾아보기", "modelProvider.selector.emptySetting": "설정으로 이동하여 구성하세요", "modelProvider.selector.emptyTip": "사용 가능한 모델이 없습니다", + "modelProvider.selector.fromMarketplace": "마켓플레이스에서", + "modelProvider.selector.incompatible": "호환되지 않음", + "modelProvider.selector.incompatibleTip": "이 모델은 현재 버전에서 사용할 수 없습니다. 다른 사용 가능한 모델을 선택하세요.", + "modelProvider.selector.install": "설치", + "modelProvider.selector.modelProviderSettings": "모델 공급자 설정", + "modelProvider.selector.noProviderConfigured": "모델 공급자가 구성되지 않았습니다", + "modelProvider.selector.noProviderConfiguredDesc": "마켓플레이스에서 설치하거나 설정에서 공급자를 구성하세요.", + "modelProvider.selector.onlyCompatibleModelsShown": "호환되는 모델만 표시됩니다", "modelProvider.selector.rerankTip": "재랭크 모델을 설정하세요", "modelProvider.selector.tip": "이 모델은 삭제되었습니다. 다른 모델을 추가하거나 다른 모델을 선택하세요.", "modelProvider.setupModelFirst": "먼저 모델을 설정하세요", diff --git a/web/i18n/ko-KR/plugin.json b/web/i18n/ko-KR/plugin.json index 2f20a584c5..93b28beeb4 100644 --- a/web/i18n/ko-KR/plugin.json +++ b/web/i18n/ko-KR/plugin.json @@ -3,6 +3,7 @@ "action.delete": "플러그인 제거", "action.deleteContentLeft": "제거하시겠습니까?", "action.deleteContentRight": "플러그인?", + "action.deleteSuccess": "플러그인이 성공적으로 제거되었습니다", "action.pluginInfo": "플러그인 정보", "action.usedInApps": "이 플러그인은 {{num}}개의 앱에서 사용되고 있습니다.", "allCategories": "모든 카테고리", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "설치", "detailPanel.operation.remove": "제거", "detailPanel.operation.update": "업데이트", + "detailPanel.operation.updateTooltip": "최신 모델에 액세스하려면 업데이트하세요.", "detailPanel.operation.viewDetail": "자세히보기", "detailPanel.serviceOk": "서비스 정상", "detailPanel.strategyNum": "{{num}} {{strategy}} 포함", @@ -231,12 +233,18 @@ "source.local": "로컬 패키지 파일", "source.marketplace": "마켓", "task.clearAll": "모두 지우기", + "task.errorMsg.github": "이 플러그인을 자동으로 설치할 수 없었습니다.\nGitHub에서 설치하세요.", + "task.errorMsg.marketplace": "이 플러그인을 자동으로 설치할 수 없었습니다.\n마켓플레이스에서 설치하세요.", + "task.errorMsg.unknown": "이 플러그인을 설치할 수 없었습니다.\n플러그인 소스를 확인할 수 없습니다.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} 플러그인 설치 실패, 보려면 클릭하십시오.", + "task.installFromGithub": "GitHub에서 설치", + "task.installFromMarketplace": "마켓플레이스에서 설치", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} 플러그인 설치 실패", "task.installing": "플러그인 설치 중.", + "task.installingHint": "설치 중... 몇 분 정도 걸릴 수 있습니다.", "task.installingWithError": "{{installingLength}} 플러그인 설치, {{successLength}} 성공, {{errorLength}} 실패", "task.installingWithSuccess": "{{installingLength}} 플러그인 설치, {{successLength}} 성공.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/ko-KR/workflow.json b/web/i18n/ko-KR/workflow.json index b83afea149..24e8e634d3 100644 --- a/web/i18n/ko-KR/workflow.json +++ b/web/i18n/ko-KR/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "워크플로 업데이트", "error.startNodeRequired": "{{operation}} 전에 먼저 시작 노드를 추가해 주세요", "errorMsg.authRequired": "인증이 필요합니다", + "errorMsg.configureModel": "모델을 구성하세요", "errorMsg.fieldRequired": "{{field}}가 필요합니다", "errorMsg.fields.code": "코드", "errorMsg.fields.model": "모델", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "비전 변수", "errorMsg.invalidJson": "{{field}}는 잘못된 JSON 입니다", "errorMsg.invalidVariable": "잘못된 변수", + "errorMsg.modelPluginNotInstalled": "잘못된 변수입니다. 이 변수를 사용하려면 모델을 구성하세요.", "errorMsg.noValidTool": "{{field}} 유효한 도구가 선택되지 않았습니다.", "errorMsg.rerankModelRequired": "Rerank Model 을 켜기 전에 설정에서 모델이 성공적으로 구성되었는지 확인하십시오.", "errorMsg.startNodeRequired": "{{operation}} 전에 먼저 시작 노드를 추가해 주세요", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "창 크기", "nodes.common.outputVars": "출력 변수", "nodes.common.pluginNotInstalled": "플러그인이 설치되지 않았습니다", + "nodes.common.pluginsNotInstalled": "{{count}}개의 플러그인이 설치되지 않았습니다", "nodes.common.retry.maxRetries": "최대 재시도 횟수", "nodes.common.retry.ms": "ms", "nodes.common.retry.retries": "{{num}} 재시도", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "청크", "nodes.knowledgeBase.chunksInputTip": "지식 기반 노드의 입력 변수는 Chunks입니다. 변수 유형은 선택된 청크 구조와 일치해야 하는 특정 JSON 스키마를 가진 객체입니다.", "nodes.knowledgeBase.chunksVariableIsRequired": "Chunks 변수는 필수입니다", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API Key 사용 불가", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "크레딧 소진", + "nodes.knowledgeBase.embeddingModelIncompatible": "호환되지 않음", "nodes.knowledgeBase.embeddingModelIsInvalid": "임베딩 모델이 유효하지 않습니다", "nodes.knowledgeBase.embeddingModelIsRequired": "임베딩 모델이 필요합니다", + "nodes.knowledgeBase.embeddingModelNotConfigured": "임베딩 모델이 구성되지 않았습니다", "nodes.knowledgeBase.indexMethodIsRequired": "인덱스 메서드가 필요합니다.", + "nodes.knowledgeBase.notConfigured": "구성되지 않음", "nodes.knowledgeBase.rerankingModelIsInvalid": "재정렬 모델이 유효하지 않습니다", "nodes.knowledgeBase.rerankingModelIsRequired": "재순위 모델이 필요합니다", "nodes.knowledgeBase.retrievalSettingIsRequired": "검색 설정이 필요합니다.", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Jinja2 만 지원합니다", "nodes.templateTransform.inputVars": "입력 변수", "nodes.templateTransform.outputVars.output": "변환된 내용", + "nodes.tool.authorizationRequired": "인증 필요", "nodes.tool.authorize": "권한 부여", "nodes.tool.inputVars": "입력 변수", "nodes.tool.insertPlaceholder1": "타이프하거나 누르세요", @@ -1062,10 +1071,12 @@ "panel.change": "변경", "panel.changeBlock": "노드 변경", "panel.checklist": "체크리스트", + "panel.checklistDescription": "게시 전에 다음 문제를 해결하세요", "panel.checklistResolved": "모든 문제가 해결되었습니다", "panel.checklistTip": "게시하기 전에 모든 문제가 해결되었는지 확인하세요", "panel.createdBy": "작성자 ", "panel.goTo": "로 이동", + "panel.goToFix": "수정하러 가기", "panel.helpLink": "도움말 센터", "panel.maximize": "캔버스 전체 화면", "panel.minimize": "전체 화면 종료", diff --git a/web/i18n/nl-NL/app-debug.json b/web/i18n/nl-NL/app-debug.json index b667cfb052..7552cb7cc9 100644 --- a/web/i18n/nl-NL/app-debug.json +++ b/web/i18n/nl-NL/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "RUN", "inputs.title": "Debug & Preview", "inputs.userInputField": "User Input Field", + "manageModels": "Modellen beheren", "modelConfig.modeType.chat": "Chat", "modelConfig.modeType.completion": "Complete", "modelConfig.model": "Model", "modelConfig.setTone": "Set tone of responses", "modelConfig.title": "Model and Parameters", + "noModelProviderConfigured": "Geen modelprovider geconfigureerd", + "noModelProviderConfiguredTip": "Installeer of configureer een modelprovider om te beginnen.", + "noModelSelected": "Geen model geselecteerd", + "noModelSelectedTip": "Configureer hierboven een model om door te gaan.", "noResult": "Output will be displayed here.", "notSetAPIKey.description": "The LLM provider key has not been set, and it needs to be set before debugging.", "notSetAPIKey.settingBtn": "Go to settings", diff --git a/web/i18n/nl-NL/common.json b/web/i18n/nl-NL/common.json index 013f06b035..fb1b332a0c 100644 --- a/web/i18n/nl-NL/common.json +++ b/web/i18n/nl-NL/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Unauthorized", "modelProvider.buyQuota": "Buy Quota", "modelProvider.callTimes": "Call times", + "modelProvider.card.aiCreditsInUse": "AI-tegoeden in gebruik", + "modelProvider.card.aiCreditsOption": "AI-tegoeden", + "modelProvider.card.apiKeyOption": "API-sleutel", + "modelProvider.card.apiKeyRequired": "API-sleutel vereist", + "modelProvider.card.apiKeyUnavailableFallback": "API-sleutel niet beschikbaar, nu worden AI-tegoeden gebruikt", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Controleer uw API-sleutelconfiguratie om terug te schakelen", "modelProvider.card.buyQuota": "Buy Quota", "modelProvider.card.callTimes": "Call times", + "modelProvider.card.creditsExhaustedDescription": "Verhaag uw abonnement of configureer een API-sleutel", + "modelProvider.card.creditsExhaustedFallback": "AI-tegoeden uitgeput, nu wordt API-sleutel gebruikt", + "modelProvider.card.creditsExhaustedFallbackDescription": "Verhoog uw abonnement om AI-tegoed prioriteit te hervatten.", + "modelProvider.card.creditsExhaustedMessage": "AI-tegoeden zijn uitgeput", "modelProvider.card.modelAPI": "{{modelName}} models are using the API Key.", - "modelProvider.card.modelNotSupported": "{{modelName}} models are not installed.", - "modelProvider.card.modelSupported": "{{modelName}} models are using this quota.", + "modelProvider.card.modelNotSupported": "{{modelName}} niet geïnstalleerd", + "modelProvider.card.modelSupported": "{{modelName}} modellen gebruiken deze tegoeden.", + "modelProvider.card.noApiKeysDescription": "Voeg een API-sleutel toe om uw eigen modelgegevens te gebruiken.", + "modelProvider.card.noApiKeysFallback": "Geen API-sleutels, AI-tegoeden worden gebruikt", + "modelProvider.card.noApiKeysTitle": "Nog geen API-sleutels geconfigureerd", + "modelProvider.card.noAvailableUsage": "Geen beschikbaar gebruik", "modelProvider.card.onTrial": "On Trial", "modelProvider.card.paid": "Paid", "modelProvider.card.priorityUse": "Priority use", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Remove API Key", "modelProvider.card.tip": "Message Credits supports models from {{modelNames}}. Priority will be given to the paid quota. The free quota will be used after the paid quota is exhausted.", "modelProvider.card.tokens": "Tokens", + "modelProvider.card.unavailable": "Niet beschikbaar", + "modelProvider.card.upgradePlan": "verhaag uw abonnement", + "modelProvider.card.usageLabel": "Gebruik", + "modelProvider.card.usagePriority": "Gebruiksprioriteit", + "modelProvider.card.usagePriorityTip": "Stel in welke resource als eerste wordt gebruikt bij het uitvoeren van modellen.", "modelProvider.collapse": "Collapse", "modelProvider.config": "Config", "modelProvider.configLoadBalancing": "Config Load Balancing", @@ -387,9 +406,11 @@ "modelProvider.model": "Model", "modelProvider.modelAndParameters": "Model and Parameters", "modelProvider.modelHasBeenDeprecated": "This model has been deprecated", + "modelProvider.modelSettings": "Modelinstellingen", "modelProvider.models": "Models", "modelProvider.modelsNum": "{{num}} Models", "modelProvider.noModelFound": "No model found for {{model}}", + "modelProvider.noneConfigured": "Configureer een standaard systeemmodel om applicaties uit te voeren", "modelProvider.notConfigured": "The system model has not yet been fully configured", "modelProvider.parameters": "PARAMETERS", "modelProvider.parametersInvalidRemoved": "Some parameters are invalid and have been removed", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Reset on {{date}}", "modelProvider.searchModel": "Search model", "modelProvider.selectModel": "Select your model", + "modelProvider.selector.aiCredits": "AI-tegoeden", + "modelProvider.selector.apiKeyUnavailable": "API-sleutel niet beschikbaar", + "modelProvider.selector.apiKeyUnavailableTip": "De API-sleutel is verwijderd. Configureer een nieuwe API-sleutel.", + "modelProvider.selector.configure": "Configureren", + "modelProvider.selector.configureRequired": "Configuratie vereist", + "modelProvider.selector.creditsExhausted": "Tegoeden uitgeput", + "modelProvider.selector.creditsExhaustedTip": "Uw AI-tegoeden zijn uitgeput. Verhoog uw abonnement of voeg een API-sleutel toe.", + "modelProvider.selector.disabled": "Uitgeschakeld", + "modelProvider.selector.discoverMoreInMarketplace": "Ontdek meer in de Marketplace", "modelProvider.selector.emptySetting": "Please go to settings to configure", "modelProvider.selector.emptyTip": "No available models", + "modelProvider.selector.fromMarketplace": "Vanuit de Marketplace", + "modelProvider.selector.incompatible": "Incompatibel", + "modelProvider.selector.incompatibleTip": "Dit model is niet beschikbaar in de huidige versie. Selecteer een ander beschikbaar model.", + "modelProvider.selector.install": "Installeren", + "modelProvider.selector.modelProviderSettings": "Modelproviderinstellingen", + "modelProvider.selector.noProviderConfigured": "Geen modelprovider geconfigureerd", + "modelProvider.selector.noProviderConfiguredDesc": "Blader in de Marketplace om er een te installeren, of configureer providers in de instellingen.", + "modelProvider.selector.onlyCompatibleModelsShown": "Alleen compatibele modellen worden weergegeven", "modelProvider.selector.rerankTip": "Please set up the Rerank model", "modelProvider.selector.tip": "This model has been removed. Please add a model or select another model.", "modelProvider.setupModelFirst": "Please set up your model first", diff --git a/web/i18n/nl-NL/plugin.json b/web/i18n/nl-NL/plugin.json index c7f091a442..4e0301b5f5 100644 --- a/web/i18n/nl-NL/plugin.json +++ b/web/i18n/nl-NL/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Remove plugin", "action.deleteContentLeft": "Would you like to remove ", "action.deleteContentRight": " plugin?", + "action.deleteSuccess": "Plugin succesvol verwijderd", "action.pluginInfo": "Plugin info", "action.usedInApps": "This plugin is being used in {{num}} apps.", "allCategories": "All Categories", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Install", "detailPanel.operation.remove": "Remove", "detailPanel.operation.update": "Update", + "detailPanel.operation.updateTooltip": "Werk bij voor toegang tot de nieuwste modellen.", "detailPanel.operation.viewDetail": "View Detail", "detailPanel.serviceOk": "Service OK", "detailPanel.strategyNum": "{{num}} {{strategy}} INCLUDED", @@ -231,12 +233,18 @@ "source.local": "Local Package File", "source.marketplace": "Marketplace", "task.clearAll": "Clear all", + "task.errorMsg.github": "Deze plugin is niet automatisch geïnstalleerd.\nInstalleer het vanuit GitHub.", + "task.errorMsg.marketplace": "Deze plugin is niet automatisch geïnstalleerd.\nInstalleer het vanuit de Marketplace.", + "task.errorMsg.unknown": "Deze plugin is niet geïnstalleerd.\nDe pluginbron kon niet worden geïdentificeerd.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} plugins failed to install, click to view", + "task.installFromGithub": "Installeren vanuit GitHub", + "task.installFromMarketplace": "Installeren vanuit de Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} plugins failed to install", "task.installing": "Installing plugins", + "task.installingHint": "Installeren... Dit kan enkele minuten duren.", "task.installingWithError": "Installing {{installingLength}} plugins, {{successLength}} success, {{errorLength}} failed", "task.installingWithSuccess": "Installing {{installingLength}} plugins, {{successLength}} success.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/nl-NL/workflow.json b/web/i18n/nl-NL/workflow.json index 35555d0e7b..891df72387 100644 --- a/web/i18n/nl-NL/workflow.json +++ b/web/i18n/nl-NL/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "updating workflow", "error.startNodeRequired": "Please add a start node first before {{operation}}", "errorMsg.authRequired": "Authorization is required", + "errorMsg.configureModel": "Configureer een model", "errorMsg.fieldRequired": "{{field}} is required", "errorMsg.fields.code": "Code", "errorMsg.fields.model": "Model", @@ -313,7 +314,8 @@ "errorMsg.fields.variableValue": "Variable Value", "errorMsg.fields.visionVariable": "Vision Variable", "errorMsg.invalidJson": "{{field}} is invalid JSON", - "errorMsg.invalidVariable": "Invalid variable", + "errorMsg.invalidVariable": "Ongeldige variabele. Selecteer een bestaande variabele.", + "errorMsg.modelPluginNotInstalled": "Ongeldige variabele. Configureer een model om deze variabele in te schakelen.", "errorMsg.noValidTool": "{{field}} no valid tool selected", "errorMsg.rerankModelRequired": "A configured Rerank Model is required", "errorMsg.startNodeRequired": "Please add a start node first before {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Window Size", "nodes.common.outputVars": "Output Variables", "nodes.common.pluginNotInstalled": "Plugin is not installed", + "nodes.common.pluginsNotInstalled": "{{count}} plugins niet geïnstalleerd", "nodes.common.retry.maxRetries": "max retries", "nodes.common.retry.ms": "ms", "nodes.common.retry.retries": "{{num}} Retries", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Chunks", "nodes.knowledgeBase.chunksInputTip": "The input variable of the knowledge base node is Chunks. The variable type is an object with a specific JSON Schema which must be consistent with the selected chunk structure.", "nodes.knowledgeBase.chunksVariableIsRequired": "Chunks variable is required", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API-sleutel niet beschikbaar", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Tegoeden uitgeput", + "nodes.knowledgeBase.embeddingModelIncompatible": "Incompatibel", "nodes.knowledgeBase.embeddingModelIsInvalid": "Embedding model is invalid", "nodes.knowledgeBase.embeddingModelIsRequired": "Embedding model is required", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Inbeddingsmodel niet geconfigureerd", "nodes.knowledgeBase.indexMethodIsRequired": "Index method is required", + "nodes.knowledgeBase.notConfigured": "Niet geconfigureerd", "nodes.knowledgeBase.rerankingModelIsInvalid": "Reranking model is invalid", "nodes.knowledgeBase.rerankingModelIsRequired": "Reranking model is required", "nodes.knowledgeBase.retrievalSettingIsRequired": "Retrieval setting is required", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Only supports Jinja2", "nodes.templateTransform.inputVars": "Input Variables", "nodes.templateTransform.outputVars.output": "Transformed content", + "nodes.tool.authorizationRequired": "Autorisatie vereist", "nodes.tool.authorize": "Authorize", "nodes.tool.inputVars": "Input Variables", "nodes.tool.insertPlaceholder1": "Type or press", @@ -1062,10 +1071,12 @@ "panel.change": "Change", "panel.changeBlock": "Change Node", "panel.checklist": "Checklist", + "panel.checklistDescription": "Los de volgende problemen op vóór het publiceren", "panel.checklistResolved": "All issues are resolved", "panel.checklistTip": "Make sure all issues are resolved before publishing", "panel.createdBy": "Created By ", "panel.goTo": "Go to", + "panel.goToFix": "Ga naar repareren", "panel.helpLink": "View Docs", "panel.maximize": "Maximize Canvas", "panel.minimize": "Exit Full Screen", diff --git a/web/i18n/pl-PL/app-debug.json b/web/i18n/pl-PL/app-debug.json index 4d7c2bf2e5..d708c997e9 100644 --- a/web/i18n/pl-PL/app-debug.json +++ b/web/i18n/pl-PL/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "URUCHOM", "inputs.title": "Debugowanie i podgląd", "inputs.userInputField": "Pole wejściowe użytkownika", + "manageModels": "Zarządzaj modelami", "modelConfig.modeType.chat": "Czat", "modelConfig.modeType.completion": "Uzupełnienie", "modelConfig.model": "Model", "modelConfig.setTone": "Ustaw ton odpowiedzi", "modelConfig.title": "Model i parametry", + "noModelProviderConfigured": "Nie skonfigurowano dostawcy modeli", + "noModelProviderConfiguredTip": "Zainstaluj lub skonfiguruj dostawcę modeli, aby rozpocząć.", + "noModelSelected": "Nie wybrano modelu", + "noModelSelectedTip": "skonfiguruj model powyżej, aby kontynuować.", "noResult": "W tym miejscu zostaną wyświetlone dane wyjściowe.", "notSetAPIKey.description": "Klucz dostawcy LLM nie został ustawiony, musi zostać ustawiony przed debugowaniem.", "notSetAPIKey.settingBtn": "Przejdź do ustawień", diff --git a/web/i18n/pl-PL/common.json b/web/i18n/pl-PL/common.json index 029e9dd660..130950a57c 100644 --- a/web/i18n/pl-PL/common.json +++ b/web/i18n/pl-PL/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Nieautoryzowany", "modelProvider.buyQuota": "Kup limit", "modelProvider.callTimes": "Czasy wywołań", + "modelProvider.card.aiCreditsInUse": "Używane AI credits", + "modelProvider.card.aiCreditsOption": "AI credits", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "Wymagany klucz API", + "modelProvider.card.apiKeyUnavailableFallback": "API Key niedostępny, używane są AI credits", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Sprawdź konfigurację klucza API, aby przełączyć z powrotem", "modelProvider.card.buyQuota": "Kup limit", "modelProvider.card.callTimes": "Czasy wywołań", + "modelProvider.card.creditsExhaustedDescription": "Proszę ulepszyć swój plan lub skonfigurować klucz API", + "modelProvider.card.creditsExhaustedFallback": "AI credits wyczerpane, używany jest API Key", + "modelProvider.card.creditsExhaustedFallbackDescription": "Ulepsz swój plan, aby przywrócić priorytet AI credits.", + "modelProvider.card.creditsExhaustedMessage": "AI credits zostały wyczerpane", "modelProvider.card.modelAPI": "Modele {{modelName}} używają klucza API.", "modelProvider.card.modelNotSupported": "Modele {{modelName}} nie są zainstalowane.", "modelProvider.card.modelSupported": "Modele {{modelName}} używają tego limitu.", + "modelProvider.card.noApiKeysDescription": "Dodaj klucz API, aby zacząć korzystać z własnych poświadczeń modelu.", + "modelProvider.card.noApiKeysFallback": "Brak kluczy API, używane są AI credits", + "modelProvider.card.noApiKeysTitle": "Nie skonfigurowano jeszcze kluczy API", + "modelProvider.card.noAvailableUsage": "Brak dostępnego użycia", "modelProvider.card.onTrial": "Na próbę", "modelProvider.card.paid": "Płatny", "modelProvider.card.priorityUse": "Używanie z priorytetem", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Usuń klucz API", "modelProvider.card.tip": "Kredyty wiadomości obsługują modele od {{modelNames}}. Priorytet zostanie nadany płatnemu limitowi. Darmowy limit zostanie użyty po wyczerpaniu płatnego limitu.", "modelProvider.card.tokens": "Tokeny", + "modelProvider.card.unavailable": "Niedostępne", + "modelProvider.card.upgradePlan": "ulepsz swój plan", + "modelProvider.card.usageLabel": "Użycie", + "modelProvider.card.usagePriority": "Priorytet użycia", + "modelProvider.card.usagePriorityTip": "Ustaw, który zasób ma być używany jako pierwszy przy uruchamianiu modeli.", "modelProvider.collapse": "Zwiń", "modelProvider.config": "Konfiguracja", "modelProvider.configLoadBalancing": "Równoważenie obciążenia konfiguracji", @@ -387,9 +406,11 @@ "modelProvider.model": "Model", "modelProvider.modelAndParameters": "Model i parametry", "modelProvider.modelHasBeenDeprecated": "Ten model jest przestarzały", + "modelProvider.modelSettings": "Ustawienia modelu", "modelProvider.models": "Modele", "modelProvider.modelsNum": "{{num}} Modele", "modelProvider.noModelFound": "Nie znaleziono modelu dla {{model}}", + "modelProvider.noneConfigured": "Skonfiguruj domyślny model systemowy, aby uruchamiać aplikacje", "modelProvider.notConfigured": "Systemowy model nie został jeszcze w pełni skonfigurowany, co może skutkować niedostępnością niektórych funkcji.", "modelProvider.parameters": "PARAMETRY", "modelProvider.parametersInvalidRemoved": "Niektóre parametry są nieprawidłowe i zostały usunięte.", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Reset {{date}}", "modelProvider.searchModel": "Model wyszukiwania", "modelProvider.selectModel": "Wybierz swój model", + "modelProvider.selector.aiCredits": "AI credits", + "modelProvider.selector.apiKeyUnavailable": "API Key niedostępny", + "modelProvider.selector.apiKeyUnavailableTip": "Klucz API został usunięty. Proszę skonfigurować nowy klucz API.", + "modelProvider.selector.configure": "Konfiguruj", + "modelProvider.selector.configureRequired": "Wymagana konfiguracja", + "modelProvider.selector.creditsExhausted": "Kredyty wyczerpane", + "modelProvider.selector.creditsExhaustedTip": "Twoje AI credits zostały wyczerpane. Proszę ulepszyć swój plan lub dodać klucz API.", + "modelProvider.selector.disabled": "Wyłączony", + "modelProvider.selector.discoverMoreInMarketplace": "Odkryj więcej w Marketplace", "modelProvider.selector.emptySetting": "Przejdź do ustawień, aby skonfigurować", "modelProvider.selector.emptyTip": "Brak dostępnych modeli", + "modelProvider.selector.fromMarketplace": "Z Marketplace", + "modelProvider.selector.incompatible": "Niekompatybilny", + "modelProvider.selector.incompatibleTip": "Ten model nie jest dostępny w bieżącej wersji. Proszę wybrać inny dostępny model.", + "modelProvider.selector.install": "Zainstaluj", + "modelProvider.selector.modelProviderSettings": "Ustawienia dostawcy modeli", + "modelProvider.selector.noProviderConfigured": "Nie skonfigurowano dostawcy modeli", + "modelProvider.selector.noProviderConfiguredDesc": "Przeglądaj Marketplace, aby zainstalować dostawcę, lub skonfiguruj dostawców w ustawieniach.", + "modelProvider.selector.onlyCompatibleModelsShown": "Wyświetlane są tylko kompatybilne modele", "modelProvider.selector.rerankTip": "Proszę skonfigurować model ponownego rankingu", "modelProvider.selector.tip": "Ten model został usunięty. Proszę dodać model lub wybrać inny model.", "modelProvider.setupModelFirst": "Proszę najpierw skonfigurować swój model", diff --git a/web/i18n/pl-PL/plugin.json b/web/i18n/pl-PL/plugin.json index abe94610dc..88ac549968 100644 --- a/web/i18n/pl-PL/plugin.json +++ b/web/i18n/pl-PL/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Usuń wtyczkę", "action.deleteContentLeft": "Czy chcesz usunąć", "action.deleteContentRight": "wtyczka?", + "action.deleteSuccess": "Wtyczka została pomyślnie usunięta", "action.pluginInfo": "Informacje o wtyczce", "action.usedInApps": "Ta wtyczka jest używana w aplikacjach {{num}}.", "allCategories": "Wszystkie kategorie", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Instalować", "detailPanel.operation.remove": "Usunąć", "detailPanel.operation.update": "Aktualizacja", + "detailPanel.operation.updateTooltip": "Zaktualizuj, aby uzyskać dostęp do najnowszych modeli.", "detailPanel.operation.viewDetail": "Pokaż szczegóły", "detailPanel.serviceOk": "Serwis OK", "detailPanel.strategyNum": "{{num}} {{strategy}} ZAWARTE", @@ -231,12 +233,18 @@ "source.local": "Lokalny plik pakietu", "source.marketplace": "Rynek", "task.clearAll": "Wyczyść wszystko", + "task.errorMsg.github": "Nie udało się automatycznie zainstalować tej wtyczki.\nProszę zainstalować ją z GitHub.", + "task.errorMsg.marketplace": "Nie udało się automatycznie zainstalować tej wtyczki.\nProszę zainstalować ją z Marketplace.", + "task.errorMsg.unknown": "Nie udało się zainstalować tej wtyczki.\nNie można zidentyfikować źródła wtyczki.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "Nie udało się zainstalować wtyczek {{errorLength}}, kliknij, aby wyświetlić", + "task.installFromGithub": "Zainstaluj z GitHub", + "task.installFromMarketplace": "Zainstaluj z Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "Nie udało się zainstalować wtyczek {{errorLength}}", "task.installing": "Instalowanie wtyczek.", + "task.installingHint": "Instalowanie... To może potrwać kilka minut.", "task.installingWithError": "Instalacja wtyczek {{installingLength}}, {{successLength}} powodzenie, {{errorLength}} niepowodzenie", "task.installingWithSuccess": "Instalacja wtyczek {{installingLength}}, {{successLength}} powodzenie.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/pl-PL/workflow.json b/web/i18n/pl-PL/workflow.json index 52514fe6b7..8aad8e0b71 100644 --- a/web/i18n/pl-PL/workflow.json +++ b/web/i18n/pl-PL/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "aktualizowanie przepływu pracy", "error.startNodeRequired": "Najpierw dodaj węzeł początkowy przed {{operation}}", "errorMsg.authRequired": "Wymagana autoryzacja", + "errorMsg.configureModel": "Skonfiguruj model", "errorMsg.fieldRequired": "{{field}} jest wymagane", "errorMsg.fields.code": "Kod", "errorMsg.fields.model": "Model", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Zmienna wizji", "errorMsg.invalidJson": "{{field}} jest nieprawidłowym JSON-em", "errorMsg.invalidVariable": "Nieprawidłowa zmienna", + "errorMsg.modelPluginNotInstalled": "Nieprawidłowa zmienna. Skonfiguruj model, aby włączyć tę zmienną.", "errorMsg.noValidTool": "{{field}} nie wybrano prawidłowego narzędzia", "errorMsg.rerankModelRequired": "Przed włączeniem Rerank Model upewnij się, że model został pomyślnie skonfigurowany w ustawieniach.", "errorMsg.startNodeRequired": "Najpierw dodaj węzeł początkowy przed {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Rozmiar okna", "nodes.common.outputVars": "Zmienne wyjściowe", "nodes.common.pluginNotInstalled": "Wtyczka nie jest zainstalowana", + "nodes.common.pluginsNotInstalled": "{{count}} wtyczek niezainstalowanych", "nodes.common.retry.maxRetries": "Maksymalna liczba ponownych prób", "nodes.common.retry.ms": "Ms", "nodes.common.retry.retries": "{{num}} Ponownych prób", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Kawałki", "nodes.knowledgeBase.chunksInputTip": "Zmienna wejściowa węzła bazy wiedzy to Chunks. Typ zmiennej to obiekt z określonym schematem JSON, który musi być zgodny z wybraną strukturą chunk.", "nodes.knowledgeBase.chunksVariableIsRequired": "Wymagana jest zmienna Chunks", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "Klucz API niedostępny", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Kredyty wyczerpane", + "nodes.knowledgeBase.embeddingModelIncompatible": "Niekompatybilny", "nodes.knowledgeBase.embeddingModelIsInvalid": "Model osadzania jest nieprawidłowy", "nodes.knowledgeBase.embeddingModelIsRequired": "Wymagany jest model osadzania", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Model embeddingu nie jest skonfigurowany", "nodes.knowledgeBase.indexMethodIsRequired": "Metoda indeksowa jest wymagana", + "nodes.knowledgeBase.notConfigured": "Nieskonfigurowany", "nodes.knowledgeBase.rerankingModelIsInvalid": "Model ponownego rankingowania jest nieprawidłowy", "nodes.knowledgeBase.rerankingModelIsRequired": "Wymagany jest model ponownego rankingu", "nodes.knowledgeBase.retrievalSettingIsRequired": "Wymagane jest ustawienie pobierania", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Obsługuje tylko Jinja2", "nodes.templateTransform.inputVars": "Zmienne wejściowe", "nodes.templateTransform.outputVars.output": "Przekształcona treść", + "nodes.tool.authorizationRequired": "Wymagana autoryzacja", "nodes.tool.authorize": "Autoryzuj", "nodes.tool.inputVars": "Zmienne wejściowe", "nodes.tool.insertPlaceholder1": "Wpisz lub naciśnij", @@ -1062,10 +1071,12 @@ "panel.change": "Zmień", "panel.changeBlock": "Zmień węzeł", "panel.checklist": "Lista kontrolna", + "panel.checklistDescription": "Rozwiąż poniższe problemy przed opublikowaniem", "panel.checklistResolved": "Wszystkie problemy zostały rozwiązane", "panel.checklistTip": "Upewnij się, że wszystkie problemy zostały rozwiązane przed opublikowaniem", "panel.createdBy": "Stworzone przez ", "panel.goTo": "Idź do", + "panel.goToFix": "Przejdź do naprawy", "panel.helpLink": "Pomoc", "panel.maximize": "Maksymalizuj płótno", "panel.minimize": "Wyjdź z trybu pełnoekranowego", diff --git a/web/i18n/pt-BR/app-debug.json b/web/i18n/pt-BR/app-debug.json index 5b0b4c9969..3b1a0da424 100644 --- a/web/i18n/pt-BR/app-debug.json +++ b/web/i18n/pt-BR/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "EXECUTAR", "inputs.title": "Depuração e Visualização", "inputs.userInputField": "Campo de Entrada do Usuário", + "manageModels": "Gerenciar modelos", "modelConfig.modeType.chat": "Chat", "modelConfig.modeType.completion": "Completar", "modelConfig.model": "Modelo", "modelConfig.setTone": "Definir tom das respostas", "modelConfig.title": "Modelo e Parâmetros", + "noModelProviderConfigured": "Nenhum provedor de modelo configurado", + "noModelProviderConfiguredTip": "Instale ou configure um provedor de modelo para começar.", + "noModelSelected": "Nenhum modelo selecionado", + "noModelSelectedTip": "Configure um modelo acima para continuar.", "noResult": "A saída será exibida aqui.", "notSetAPIKey.description": "A chave do provedor LLM não foi definida e precisa ser definida antes da depuração.", "notSetAPIKey.settingBtn": "Ir para configurações", diff --git a/web/i18n/pt-BR/common.json b/web/i18n/pt-BR/common.json index 0f2106b1eb..6840bb964b 100644 --- a/web/i18n/pt-BR/common.json +++ b/web/i18n/pt-BR/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Não autorizado", "modelProvider.buyQuota": "Comprar Quota", "modelProvider.callTimes": "Chamadas", + "modelProvider.card.aiCreditsInUse": "AI credits em uso", + "modelProvider.card.aiCreditsOption": "AI credits", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "API Key necessária", + "modelProvider.card.apiKeyUnavailableFallback": "API Key indisponível, usando AI credits", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Verifique a configuração da sua API Key para voltar a usá-la", "modelProvider.card.buyQuota": "Comprar Quota", "modelProvider.card.callTimes": "Chamadas", + "modelProvider.card.creditsExhaustedDescription": "Por favor, atualize seu plano ou configure uma API Key", + "modelProvider.card.creditsExhaustedFallback": "AI credits esgotados, usando API Key", + "modelProvider.card.creditsExhaustedFallbackDescription": "Atualize seu plano para retomar a prioridade de AI credits.", + "modelProvider.card.creditsExhaustedMessage": "AI credits foram esgotados", "modelProvider.card.modelAPI": "Os modelos {{modelName}} estão usando a Chave API.", "modelProvider.card.modelNotSupported": "Os modelos {{modelName}} não estão instalados.", "modelProvider.card.modelSupported": "Os modelos {{modelName}} estão usando esta cota.", + "modelProvider.card.noApiKeysDescription": "Adicione uma API Key para usar suas próprias credenciais de modelo.", + "modelProvider.card.noApiKeysFallback": "Sem API Keys, usando AI credits", + "modelProvider.card.noApiKeysTitle": "Nenhuma API Key configurada", + "modelProvider.card.noAvailableUsage": "Sem uso disponível", "modelProvider.card.onTrial": "Em Teste", "modelProvider.card.paid": "Pago", "modelProvider.card.priorityUse": "Uso prioritário", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Remover Chave da API", "modelProvider.card.tip": "Créditos de mensagens suportam modelos de {{modelNames}}. A prioridade será dada à quota paga. A quota gratuita será usada após a quota paga ser esgotada.", "modelProvider.card.tokens": "Tokens", + "modelProvider.card.unavailable": "Indisponível", + "modelProvider.card.upgradePlan": "atualize seu plano", + "modelProvider.card.usageLabel": "Uso", + "modelProvider.card.usagePriority": "Prioridade de uso", + "modelProvider.card.usagePriorityTip": "Defina qual recurso usar primeiro ao executar modelos.", "modelProvider.collapse": "Recolher", "modelProvider.config": "Configuração", "modelProvider.configLoadBalancing": "Balanceamento de carga de configuração", @@ -387,9 +406,11 @@ "modelProvider.model": "Modelo", "modelProvider.modelAndParameters": "Modelo e Parâmetros", "modelProvider.modelHasBeenDeprecated": "Este modelo foi preterido", + "modelProvider.modelSettings": "Configurações de modelo", "modelProvider.models": "Modelos", "modelProvider.modelsNum": "{{num}} Modelos", "modelProvider.noModelFound": "Nenhum modelo encontrado para {{model}}", + "modelProvider.noneConfigured": "Configure um modelo de sistema padrão para executar aplicações", "modelProvider.notConfigured": "O modelo do sistema ainda não foi totalmente configurado e algumas funções podem estar indisponíveis.", "modelProvider.parameters": "PARÂMETROS", "modelProvider.parametersInvalidRemoved": "Alguns parâmetros são inválidos e foram removidos", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Redefinir em {{date}}", "modelProvider.searchModel": "Modelo de pesquisa", "modelProvider.selectModel": "Selecione seu modelo", + "modelProvider.selector.aiCredits": "AI credits", + "modelProvider.selector.apiKeyUnavailable": "API Key indisponível", + "modelProvider.selector.apiKeyUnavailableTip": "A API Key foi removida. Por favor, configure uma nova API Key.", + "modelProvider.selector.configure": "Configurar", + "modelProvider.selector.configureRequired": "Configuração necessária", + "modelProvider.selector.creditsExhausted": "Créditos esgotados", + "modelProvider.selector.creditsExhaustedTip": "Seus AI credits foram esgotados. Por favor, atualize seu plano ou adicione uma API Key.", + "modelProvider.selector.disabled": "Desativado", + "modelProvider.selector.discoverMoreInMarketplace": "Descubra mais no Marketplace", "modelProvider.selector.emptySetting": "Por favor, vá para configurações para configurar", "modelProvider.selector.emptyTip": "Nenhum modelo disponível", + "modelProvider.selector.fromMarketplace": "Do Marketplace", + "modelProvider.selector.incompatible": "Incompatível", + "modelProvider.selector.incompatibleTip": "Este modelo não está disponível na versão atual. Por favor, selecione outro modelo disponível.", + "modelProvider.selector.install": "Instalar", + "modelProvider.selector.modelProviderSettings": "Configurações do provedor de modelo", + "modelProvider.selector.noProviderConfigured": "Nenhum provedor de modelo configurado", + "modelProvider.selector.noProviderConfiguredDesc": "Navegue pelo Marketplace para instalar um, ou configure provedores nas configurações.", + "modelProvider.selector.onlyCompatibleModelsShown": "Apenas modelos compatíveis são exibidos", "modelProvider.selector.rerankTip": "Por favor, configure o modelo de reordenação", "modelProvider.selector.tip": "Este modelo foi removido. Adicione um modelo ou selecione outro modelo.", "modelProvider.setupModelFirst": "Por favor, configure seu modelo primeiro", diff --git a/web/i18n/pt-BR/plugin.json b/web/i18n/pt-BR/plugin.json index c9297b5840..d5d218c8b6 100644 --- a/web/i18n/pt-BR/plugin.json +++ b/web/i18n/pt-BR/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Remover plugin", "action.deleteContentLeft": "Gostaria de remover", "action.deleteContentRight": "plugin?", + "action.deleteSuccess": "Plugin removido com sucesso", "action.pluginInfo": "Informações do plugin", "action.usedInApps": "Este plugin está sendo usado em aplicativos {{num}}.", "allCategories": "Todas as categorias", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Instalar", "detailPanel.operation.remove": "Retirar", "detailPanel.operation.update": "Atualização", + "detailPanel.operation.updateTooltip": "Atualize para acessar os modelos mais recentes.", "detailPanel.operation.viewDetail": "Ver detalhes", "detailPanel.serviceOk": "Serviço OK", "detailPanel.strategyNum": "{{num}} {{strategy}} INCLUSO", @@ -231,12 +233,18 @@ "source.local": "Arquivo de pacote local", "source.marketplace": "Mercado", "task.clearAll": "Apagar tudo", + "task.errorMsg.github": "Este plugin não pôde ser instalado automaticamente.\nPor favor, instale-o pelo GitHub.", + "task.errorMsg.marketplace": "Este plugin não pôde ser instalado automaticamente.\nPor favor, instale-o pelo Marketplace.", + "task.errorMsg.unknown": "Este plugin não pôde ser instalado.\nNão foi possível identificar a origem do plugin.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} plugins falha ao instalar, clique para ver", + "task.installFromGithub": "Instalar pelo GitHub", + "task.installFromMarketplace": "Instalar pelo Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "Falha na instalação dos plug-ins {{errorLength}}", "task.installing": "Instalando plugins.", + "task.installingHint": "Instalando... Isso pode levar alguns minutos.", "task.installingWithError": "Instalando plug-ins {{installingLength}}, {{successLength}} sucesso, {{errorLength}} falhou", "task.installingWithSuccess": "Instalando plugins {{installingLength}}, {{successLength}} sucesso.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/pt-BR/workflow.json b/web/i18n/pt-BR/workflow.json index 3edab361bb..dc986df82c 100644 --- a/web/i18n/pt-BR/workflow.json +++ b/web/i18n/pt-BR/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "atualizando fluxo de trabalho", "error.startNodeRequired": "Por favor, adicione um nó inicial antes de {{operation}}", "errorMsg.authRequired": "Autorização é necessária", + "errorMsg.configureModel": "Configure um modelo", "errorMsg.fieldRequired": "{{field}} é obrigatório", "errorMsg.fields.code": "Código", "errorMsg.fields.model": "Modelo", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Variável de visão", "errorMsg.invalidJson": "{{field}} é um JSON inválido", "errorMsg.invalidVariable": "Variável inválida", + "errorMsg.modelPluginNotInstalled": "Variável inválida. Configure um modelo para habilitar esta variável.", "errorMsg.noValidTool": "{{field}} nenhuma ferramenta válida selecionada", "errorMsg.rerankModelRequired": "Antes de ativar o modelo de reclassificação, confirme se o modelo foi configurado com sucesso nas configurações.", "errorMsg.startNodeRequired": "Por favor, adicione um nó inicial antes de {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Tamanho da janela", "nodes.common.outputVars": "Variáveis de saída", "nodes.common.pluginNotInstalled": "O plugin não está instalado", + "nodes.common.pluginsNotInstalled": "{{count}} plugins não instalados", "nodes.common.retry.maxRetries": "Máximo de tentativas", "nodes.common.retry.ms": "ms", "nodes.common.retry.retries": "{{num}} Tentativas", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Pedaços", "nodes.knowledgeBase.chunksInputTip": "A variável de entrada do nó da base de conhecimento é Chunks. O tipo da variável é um objeto com um esquema JSON específico que deve ser consistente com a estrutura de chunk selecionada.", "nodes.knowledgeBase.chunksVariableIsRequired": "A variável 'chunks' é obrigatória", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API Key indisponível", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Créditos esgotados", + "nodes.knowledgeBase.embeddingModelIncompatible": "Incompatível", "nodes.knowledgeBase.embeddingModelIsInvalid": "O modelo de incorporação é inválido", "nodes.knowledgeBase.embeddingModelIsRequired": "Modelo de incorporação é necessário", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Modelo de embedding não configurado", "nodes.knowledgeBase.indexMethodIsRequired": "O método de índice é necessário", + "nodes.knowledgeBase.notConfigured": "Não configurado", "nodes.knowledgeBase.rerankingModelIsInvalid": "O modelo de reclassificação é inválido", "nodes.knowledgeBase.rerankingModelIsRequired": "Um modelo de reclassificação é necessário", "nodes.knowledgeBase.retrievalSettingIsRequired": "A configuração de recuperação é necessária", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Suporta apenas Jinja2", "nodes.templateTransform.inputVars": "Variáveis de entrada", "nodes.templateTransform.outputVars.output": "Conteúdo transformado", + "nodes.tool.authorizationRequired": "Autorização necessária", "nodes.tool.authorize": "Autorizar", "nodes.tool.inputVars": "Variáveis de entrada", "nodes.tool.insertPlaceholder1": "Digite ou pressione", @@ -1062,10 +1071,12 @@ "panel.change": "Mudar", "panel.changeBlock": "Mudar Nó", "panel.checklist": "Lista de verificação", + "panel.checklistDescription": "Resolva os seguintes problemas antes de publicar", "panel.checklistResolved": "Todos os problemas foram resolvidos", "panel.checklistTip": "Certifique-se de que todos os problemas foram resolvidos antes de publicar", "panel.createdBy": "Criado por ", "panel.goTo": "Ir para", + "panel.goToFix": "Ir para correção", "panel.helpLink": "Ajuda", "panel.maximize": "Maximize Canvas", "panel.minimize": "Sair do Modo Tela Cheia", diff --git a/web/i18n/ro-RO/app-debug.json b/web/i18n/ro-RO/app-debug.json index 6245ca680d..d2b8294804 100644 --- a/web/i18n/ro-RO/app-debug.json +++ b/web/i18n/ro-RO/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "RULARE", "inputs.title": "Depanare și previzualizare", "inputs.userInputField": "Câmp de intrare utilizator", + "manageModels": "Gestionare modele", "modelConfig.modeType.chat": "Chat", "modelConfig.modeType.completion": "Completare", "modelConfig.model": "Model", "modelConfig.setTone": "Setați tonul răspunsurilor", "modelConfig.title": "Model și Parametri", + "noModelProviderConfigured": "Niciun furnizor de modele configurat", + "noModelProviderConfiguredTip": "Instalați sau configurați un furnizor de modele pentru a începe.", + "noModelSelected": "Niciun model selectat", + "noModelSelectedTip": "configurați un model mai sus pentru a continua.", "noResult": "Ieșirea va fi afișată aici.", "notSetAPIKey.description": "Cheia furnizorului LLM nu a fost setată și trebuie să fie setată înainte de depanare.", "notSetAPIKey.settingBtn": "Du-te la setări", diff --git a/web/i18n/ro-RO/common.json b/web/i18n/ro-RO/common.json index 8fdb09b3c1..306439768b 100644 --- a/web/i18n/ro-RO/common.json +++ b/web/i18n/ro-RO/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Neautorizat", "modelProvider.buyQuota": "Cumpără cotă", "modelProvider.callTimes": "Apeluri", + "modelProvider.card.aiCreditsInUse": "AI credits în uz", + "modelProvider.card.aiCreditsOption": "AI credits", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "API key necesar", + "modelProvider.card.apiKeyUnavailableFallback": "API Key indisponibil, se utilizează AI credits", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Verificați configurația API key pentru a reveni", "modelProvider.card.buyQuota": "Cumpără cotă", "modelProvider.card.callTimes": "Apeluri", + "modelProvider.card.creditsExhaustedDescription": "Vă rugăm să faceți upgrade la plan sau să configurați un API key", + "modelProvider.card.creditsExhaustedFallback": "AI credits epuizate, se utilizează API Key", + "modelProvider.card.creditsExhaustedFallbackDescription": "Faceți upgrade la plan pentru a relua prioritatea AI credits.", + "modelProvider.card.creditsExhaustedMessage": "AI credits au fost epuizate", "modelProvider.card.modelAPI": "Modelele {{modelName}} folosesc cheia API.", "modelProvider.card.modelNotSupported": "Modelele {{modelName}} nu sunt instalate.", "modelProvider.card.modelSupported": "Modelele {{modelName}} folosesc această cotă.", + "modelProvider.card.noApiKeysDescription": "Adăugați un API key pentru a începe să utilizați propriile credențiale de model.", + "modelProvider.card.noApiKeysFallback": "Fără API key-uri, se utilizează AI credits", + "modelProvider.card.noApiKeysTitle": "Niciun API key configurat încă", + "modelProvider.card.noAvailableUsage": "Nicio utilizare disponibilă", "modelProvider.card.onTrial": "În probă", "modelProvider.card.paid": "Plătit", "modelProvider.card.priorityUse": "Utilizare prioritară", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Elimină cheia API", "modelProvider.card.tip": "Creditele de mesaje acceptă modele de la {{modelNames}}. Prioritate va fi acordată cotei plătite. Cota gratuită va fi utilizată după epuizarea cotei plătite.", "modelProvider.card.tokens": "Jetoane", + "modelProvider.card.unavailable": "Indisponibil", + "modelProvider.card.upgradePlan": "faceți upgrade la plan", + "modelProvider.card.usageLabel": "Utilizare", + "modelProvider.card.usagePriority": "Prioritate de utilizare", + "modelProvider.card.usagePriorityTip": "Setați ce resursă să fie utilizată prima la rularea modelelor.", "modelProvider.collapse": "Restrânge", "modelProvider.config": "Configurare", "modelProvider.configLoadBalancing": "Echilibrarea încărcării de configurare", @@ -387,9 +406,11 @@ "modelProvider.model": "Model", "modelProvider.modelAndParameters": "Model și parametri", "modelProvider.modelHasBeenDeprecated": "Acest model a fost depreciat", + "modelProvider.modelSettings": "Setări model", "modelProvider.models": "Modele", "modelProvider.modelsNum": "{{num}} Modele", "modelProvider.noModelFound": "Nu a fost găsit niciun model pentru {{model}}", + "modelProvider.noneConfigured": "Configurați un model de sistem implicit pentru a rula aplicații", "modelProvider.notConfigured": "Modelul de sistem nu a fost încă configurat complet, iar unele funcții pot fi indisponibile.", "modelProvider.parameters": "PARAMETRI", "modelProvider.parametersInvalidRemoved": "Unele parametrii sunt invalizi și au fost eliminați.", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Resetare la {{date}}", "modelProvider.searchModel": "Model de căutare", "modelProvider.selectModel": "Selectați modelul dvs.", + "modelProvider.selector.aiCredits": "AI credits", + "modelProvider.selector.apiKeyUnavailable": "API Key indisponibil", + "modelProvider.selector.apiKeyUnavailableTip": "API key-ul a fost eliminat. Vă rugăm să configurați un nou API key.", + "modelProvider.selector.configure": "Configurare", + "modelProvider.selector.configureRequired": "Configurare necesară", + "modelProvider.selector.creditsExhausted": "Credite epuizate", + "modelProvider.selector.creditsExhaustedTip": "AI credits au fost epuizate. Vă rugăm să faceți upgrade la plan sau să adăugați un API key.", + "modelProvider.selector.disabled": "Dezactivat", + "modelProvider.selector.discoverMoreInMarketplace": "Descoperiți mai multe în Marketplace", "modelProvider.selector.emptySetting": "Vă rugăm să mergeți la setări pentru a configura", "modelProvider.selector.emptyTip": "Nu există modele disponibile", + "modelProvider.selector.fromMarketplace": "Din Marketplace", + "modelProvider.selector.incompatible": "Incompatibil", + "modelProvider.selector.incompatibleTip": "Acest model nu este disponibil în versiunea curentă. Vă rugăm să selectați alt model disponibil.", + "modelProvider.selector.install": "Instalare", + "modelProvider.selector.modelProviderSettings": "Setări furnizor de modele", + "modelProvider.selector.noProviderConfigured": "Niciun furnizor de modele configurat", + "modelProvider.selector.noProviderConfiguredDesc": "Răsfoiți Marketplace pentru a instala unul sau configurați furnizorii în setări.", + "modelProvider.selector.onlyCompatibleModelsShown": "Sunt afișate doar modelele compatibile", "modelProvider.selector.rerankTip": "Vă rugăm să configurați modelul de reordonare", "modelProvider.selector.tip": "Acest model a fost eliminat. Vă rugăm să adăugați un model sau să selectați un alt model.", "modelProvider.setupModelFirst": "Vă rugăm să configurați mai întâi modelul", diff --git a/web/i18n/ro-RO/plugin.json b/web/i18n/ro-RO/plugin.json index c0295b64d6..15523b6c62 100644 --- a/web/i18n/ro-RO/plugin.json +++ b/web/i18n/ro-RO/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Eliminați pluginul", "action.deleteContentLeft": "Doriți să eliminați", "action.deleteContentRight": "plugin?", + "action.deleteSuccess": "Plugin eliminat cu succes", "action.pluginInfo": "Informații despre plugin", "action.usedInApps": "Acest plugin este folosit în aplicațiile {{num}}.", "allCategories": "Toate categoriile", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Instala", "detailPanel.operation.remove": "Depărta", "detailPanel.operation.update": "Actualiza", + "detailPanel.operation.updateTooltip": "Actualizați pentru a accesa cele mai recente modele.", "detailPanel.operation.viewDetail": "Vezi detalii", "detailPanel.serviceOk": "Serviciu OK", "detailPanel.strategyNum": "{{num}} {{strategy}} INCLUS", @@ -231,12 +233,18 @@ "source.local": "Fișier pachet local", "source.marketplace": "Târg", "task.clearAll": "Ștergeți tot", + "task.errorMsg.github": "Acest plugin nu a putut fi instalat automat.\nVă rugăm să îl instalați de pe GitHub.", + "task.errorMsg.marketplace": "Acest plugin nu a putut fi instalat automat.\nVă rugăm să îl instalați din Marketplace.", + "task.errorMsg.unknown": "Acest plugin nu a putut fi instalat.\nSursa pluginului nu a putut fi identificată.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} plugin-urile nu s-au instalat, faceți clic pentru a vizualiza", + "task.installFromGithub": "Instalare de pe GitHub", + "task.installFromMarketplace": "Instalare din Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} plugin-urile nu s-au instalat", "task.installing": "Se instalează pluginuri.", + "task.installingHint": "Se instalează... Aceasta poate dura câteva minute.", "task.installingWithError": "Instalarea pluginurilor {{installingLength}}, {{successLength}} succes, {{errorLength}} eșuat", "task.installingWithSuccess": "Instalarea pluginurilor {{installingLength}}, {{successLength}} succes.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/ro-RO/workflow.json b/web/i18n/ro-RO/workflow.json index a68d477980..e34ba42007 100644 --- a/web/i18n/ro-RO/workflow.json +++ b/web/i18n/ro-RO/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "actualizarea fluxului de lucru", "error.startNodeRequired": "Vă rugăm să adăugați mai întâi un nod de pornire înainte de {{operation}}", "errorMsg.authRequired": "Autorizarea este necesară", + "errorMsg.configureModel": "Configurați un model", "errorMsg.fieldRequired": "{{field}} este obligatoriu", "errorMsg.fields.code": "Cod", "errorMsg.fields.model": "Model", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Vizibilitate variabilă", "errorMsg.invalidJson": "{{field}} este un JSON invalid", "errorMsg.invalidVariable": "Variabilă invalidă", + "errorMsg.modelPluginNotInstalled": "Variabilă invalidă. Configurați un model pentru a activa această variabilă.", "errorMsg.noValidTool": "{{field}} nu a fost selectat niciun instrument valid", "errorMsg.rerankModelRequired": "Înainte de a activa modelul de reclasificare, vă rugăm să confirmați că modelul a fost configurat cu succes în setări.", "errorMsg.startNodeRequired": "Vă rugăm să adăugați mai întâi un nod de pornire înainte de {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Dimensiunea ferestrei", "nodes.common.outputVars": "Variabile de ieșire", "nodes.common.pluginNotInstalled": "Pluginul nu este instalat", + "nodes.common.pluginsNotInstalled": "{{count}} pluginuri neinstalate", "nodes.common.retry.maxRetries": "numărul maxim de încercări", "nodes.common.retry.ms": "Ms", "nodes.common.retry.retries": "{{num}} Încercări", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Bucăți", "nodes.knowledgeBase.chunksInputTip": "Variabila de intrare a nodului bazei de cunoștințe este Chunks. Tipul variabilei este un obiect cu un Șchema JSON specific care trebuie să fie coerent cu structura de chunk selectată.", "nodes.knowledgeBase.chunksVariableIsRequired": "Variabila Chunks este obligatorie", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API key indisponibil", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Credite epuizate", + "nodes.knowledgeBase.embeddingModelIncompatible": "Incompatibil", "nodes.knowledgeBase.embeddingModelIsInvalid": "Modelul de încorporare este invalid", "nodes.knowledgeBase.embeddingModelIsRequired": "Este necesar un model de încorporare", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Modelul de embedding nu este configurat", "nodes.knowledgeBase.indexMethodIsRequired": "Este necesară metoda indexului", + "nodes.knowledgeBase.notConfigured": "Neconfigurat", "nodes.knowledgeBase.rerankingModelIsInvalid": "Modelul de reordonare este invalid", "nodes.knowledgeBase.rerankingModelIsRequired": "Este necesar un model de reordonare", "nodes.knowledgeBase.retrievalSettingIsRequired": "Setarea de recuperare este necesară", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Suportă doar Jinja2", "nodes.templateTransform.inputVars": "Variabile de intrare", "nodes.templateTransform.outputVars.output": "Conținut transformat", + "nodes.tool.authorizationRequired": "Autorizare necesară", "nodes.tool.authorize": "Autorizați", "nodes.tool.inputVars": "Variabile de intrare", "nodes.tool.insertPlaceholder1": "Scrieți sau apăsați", @@ -1062,10 +1071,12 @@ "panel.change": "Schimbă", "panel.changeBlock": "Schimbă nodul", "panel.checklist": "Lista de verificare", + "panel.checklistDescription": "Rezolvați următoarele probleme înainte de publicare", "panel.checklistResolved": "Toate problemele au fost rezolvate", "panel.checklistTip": "Asigurați-vă că toate problemele sunt rezolvate înainte de publicare", "panel.createdBy": "Creat de ", "panel.goTo": "Du-te la", + "panel.goToFix": "Mergi la remediere", "panel.helpLink": "Ajutor", "panel.maximize": "Maximize Canvas", "panel.minimize": "Iesi din modul pe tot ecranul", diff --git a/web/i18n/ru-RU/app-debug.json b/web/i18n/ru-RU/app-debug.json index fdc797da2f..514958101d 100644 --- a/web/i18n/ru-RU/app-debug.json +++ b/web/i18n/ru-RU/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "ЗАПУСТИТЬ", "inputs.title": "Отладка и предварительный просмотр", "inputs.userInputField": "Поле пользовательского ввода", + "manageModels": "Управление моделями", "modelConfig.modeType.chat": "Чат", "modelConfig.modeType.completion": "Завершение", "modelConfig.model": "Модель", "modelConfig.setTone": "Установить тон ответов", "modelConfig.title": "Модель и параметры", + "noModelProviderConfigured": "Поставщик моделей не настроен", + "noModelProviderConfiguredTip": "Установите или настройте поставщика моделей, чтобы начать работу.", + "noModelSelected": "Модель не выбрана", + "noModelSelectedTip": "Настройте модель выше, чтобы продолжить.", "noResult": "Вывод будет отображаться здесь.", "notSetAPIKey.description": "Ключ поставщика LLM не установлен, его необходимо установить перед отладкой.", "notSetAPIKey.settingBtn": "Перейти к настройкам", diff --git a/web/i18n/ru-RU/common.json b/web/i18n/ru-RU/common.json index dc301e4ed9..aec9a69483 100644 --- a/web/i18n/ru-RU/common.json +++ b/web/i18n/ru-RU/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Неавторизованный", "modelProvider.buyQuota": "Купить квоту", "modelProvider.callTimes": "Количество вызовов", + "modelProvider.card.aiCreditsInUse": "Используются AI-кредиты", + "modelProvider.card.aiCreditsOption": "AI-кредиты", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "Требуется API-ключ", + "modelProvider.card.apiKeyUnavailableFallback": "API Key недоступен, используются AI-кредиты", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Проверьте настройки API Key для переключения обратно", "modelProvider.card.buyQuota": "Купить квоту", "modelProvider.card.callTimes": "Количество вызовов", + "modelProvider.card.creditsExhaustedDescription": "Пожалуйста, обновите тарифный план или настройте API-ключ", + "modelProvider.card.creditsExhaustedFallback": "AI-кредиты исчерпаны, используется API Key", + "modelProvider.card.creditsExhaustedFallbackDescription": "Обновите тарифный план, чтобы возобновить приоритетное использование AI-кредитов.", + "modelProvider.card.creditsExhaustedMessage": "AI-кредиты исчерпаны", "modelProvider.card.modelAPI": "Модели {{modelName}} используют API-ключ.", "modelProvider.card.modelNotSupported": "Модели {{modelName}} не установлены.", "modelProvider.card.modelSupported": "Модели {{modelName}} используют эту квоту.", + "modelProvider.card.noApiKeysDescription": "Добавьте API-ключ, чтобы использовать собственные учётные данные модели.", + "modelProvider.card.noApiKeysFallback": "API-ключи не настроены, используются AI-кредиты", + "modelProvider.card.noApiKeysTitle": "API-ключи ещё не настроены", + "modelProvider.card.noAvailableUsage": "Нет доступного использования", "modelProvider.card.onTrial": "Пробная версия", "modelProvider.card.paid": "Платный", "modelProvider.card.priorityUse": "Приоритетное использование", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Удалить API-ключ", "modelProvider.card.tip": "Кредиты сообщений поддерживают модели от {{modelNames}}. Приоритет будет отдаваться платной квоте. Бесплатная квота будет использоваться после исчерпания платной квоты.", "modelProvider.card.tokens": "Токены", + "modelProvider.card.unavailable": "Недоступно", + "modelProvider.card.upgradePlan": "обновите тарифный план", + "modelProvider.card.usageLabel": "Использование", + "modelProvider.card.usagePriority": "Приоритет использования", + "modelProvider.card.usagePriorityTip": "Укажите, какой ресурс использовать первым при запуске моделей.", "modelProvider.collapse": "Свернуть", "modelProvider.config": "Настройка", "modelProvider.configLoadBalancing": "Настроить балансировку нагрузки", @@ -387,9 +406,11 @@ "modelProvider.model": "Модель", "modelProvider.modelAndParameters": "Модель и параметры", "modelProvider.modelHasBeenDeprecated": "Эта модель устарела", + "modelProvider.modelSettings": "Настройки моделей", "modelProvider.models": "Модели", "modelProvider.modelsNum": "{{num}} Моделей", "modelProvider.noModelFound": "Модель не найдена для {{model}}", + "modelProvider.noneConfigured": "Настройте системную модель по умолчанию для запуска приложений", "modelProvider.notConfigured": "Системная модель еще не полностью настроена, и некоторые функции могут быть недоступны.", "modelProvider.parameters": "ПАРАМЕТРЫ", "modelProvider.parametersInvalidRemoved": "Некоторые параметры недействительны и были удалены", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Сброс {{date}}", "modelProvider.searchModel": "Поиск модели", "modelProvider.selectModel": "Выберите свою модель", + "modelProvider.selector.aiCredits": "AI-кредиты", + "modelProvider.selector.apiKeyUnavailable": "API Key недоступен", + "modelProvider.selector.apiKeyUnavailableTip": "API Key был удалён. Пожалуйста, настройте новый API Key.", + "modelProvider.selector.configure": "Настроить", + "modelProvider.selector.configureRequired": "Требуется настройка", + "modelProvider.selector.creditsExhausted": "Кредиты исчерпаны", + "modelProvider.selector.creditsExhaustedTip": "Ваши AI-кредиты исчерпаны. Обновите тарифный план или добавьте API-ключ.", + "modelProvider.selector.disabled": "Отключено", + "modelProvider.selector.discoverMoreInMarketplace": "Найти больше в Marketplace", "modelProvider.selector.emptySetting": "Пожалуйста, перейдите в настройки для настройки", "modelProvider.selector.emptyTip": "Нет доступных моделей", + "modelProvider.selector.fromMarketplace": "Из Marketplace", + "modelProvider.selector.incompatible": "Несовместимо", + "modelProvider.selector.incompatibleTip": "Эта модель недоступна в текущей версии. Пожалуйста, выберите другую доступную модель.", + "modelProvider.selector.install": "Установить", + "modelProvider.selector.modelProviderSettings": "Настройки поставщика моделей", + "modelProvider.selector.noProviderConfigured": "Поставщик моделей не настроен", + "modelProvider.selector.noProviderConfiguredDesc": "Установите из Marketplace или настройте поставщиков в настройках.", + "modelProvider.selector.onlyCompatibleModelsShown": "Показаны только совместимые модели", "modelProvider.selector.rerankTip": "Пожалуйста, настройте модель повторного ранжирования", "modelProvider.selector.tip": "Эта модель была удалена. Пожалуйста, добавьте модель или выберите другую модель.", "modelProvider.setupModelFirst": "Пожалуйста, сначала настройте свою модель", diff --git a/web/i18n/ru-RU/plugin.json b/web/i18n/ru-RU/plugin.json index 3b10a3a995..52cb6cbd55 100644 --- a/web/i18n/ru-RU/plugin.json +++ b/web/i18n/ru-RU/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Удалить плагин", "action.deleteContentLeft": "Вы хотели бы удалить", "action.deleteContentRight": "Плагин?", + "action.deleteSuccess": "Плагин успешно удалён", "action.pluginInfo": "Информация о плагине", "action.usedInApps": "Этот плагин используется в приложениях {{num}}.", "allCategories": "Все категории", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Устанавливать", "detailPanel.operation.remove": "Убирать", "detailPanel.operation.update": "Обновлять", + "detailPanel.operation.updateTooltip": "Обновите для доступа к последним моделям.", "detailPanel.operation.viewDetail": "Подробнее", "detailPanel.serviceOk": "Услуга ОК", "detailPanel.strategyNum": "{{num}} {{strategy}} ВКЛЮЧЕННЫЙ", @@ -231,12 +233,18 @@ "source.local": "Локальный файл пакета", "source.marketplace": "Рынок", "task.clearAll": "Очистить все", + "task.errorMsg.github": "Не удалось автоматически установить этот плагин.\nПожалуйста, установите его из GitHub.", + "task.errorMsg.marketplace": "Не удалось автоматически установить этот плагин.\nПожалуйста, установите его из Marketplace.", + "task.errorMsg.unknown": "Не удалось установить этот плагин.\nНе удалось определить источник плагина.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "Плагины {{errorLength}} не удалось установить, нажмите для просмотра", + "task.installFromGithub": "Установить из GitHub", + "task.installFromMarketplace": "Установить из Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "плагины {{errorLength}} не удалось установить", "task.installing": "Установка плагинов.", + "task.installingHint": "Установка... Это может занять несколько минут.", "task.installingWithError": "Установка плагинов {{installingLength}}, {{successLength}} успех, {{errorLength}} неудачный", "task.installingWithSuccess": "Установка плагинов {{installingLength}}, {{successLength}} успех.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/ru-RU/workflow.json b/web/i18n/ru-RU/workflow.json index 9265e4e6d6..73cdad253a 100644 --- a/web/i18n/ru-RU/workflow.json +++ b/web/i18n/ru-RU/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "обновление рабочего процесса", "error.startNodeRequired": "Пожалуйста, сначала добавьте начальный узел перед {{operation}}", "errorMsg.authRequired": "Требуется авторизация", + "errorMsg.configureModel": "Настройте модель", "errorMsg.fieldRequired": "{{field}} обязательно для заполнения", "errorMsg.fields.code": "Код", "errorMsg.fields.model": "Модель", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Переменная зрения", "errorMsg.invalidJson": "{{field}} неверный JSON", "errorMsg.invalidVariable": "Неверная переменная", + "errorMsg.modelPluginNotInstalled": "Недопустимая переменная. Настройте модель, чтобы активировать эту переменную.", "errorMsg.noValidTool": "{{field}} не выбран валидный инструмент", "errorMsg.rerankModelRequired": "Перед включением модели повторного ранжирования убедитесь, что модель успешно настроена в настройках.", "errorMsg.startNodeRequired": "Пожалуйста, сначала добавьте начальный узел перед {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Размер окна", "nodes.common.outputVars": "Выходные переменные", "nodes.common.pluginNotInstalled": "Плагин не установлен", + "nodes.common.pluginsNotInstalled": "{{count}} плагинов не установлено", "nodes.common.retry.maxRetries": "максимальное количество повторных попыток", "nodes.common.retry.ms": "госпожа", "nodes.common.retry.retries": "{{num}} Повторных попыток", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Куски", "nodes.knowledgeBase.chunksInputTip": "Входная переменная узла базы знаний - это Чанки. Тип переменной является объектом с определенной схемой JSON, которая должна соответствовать выбранной структуре чанка.", "nodes.knowledgeBase.chunksVariableIsRequired": "Переменная chunks обязательна", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API-ключ недоступен", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Кредиты исчерпаны", + "nodes.knowledgeBase.embeddingModelIncompatible": "Несовместимо", "nodes.knowledgeBase.embeddingModelIsInvalid": "Модель встраивания недействительна", "nodes.knowledgeBase.embeddingModelIsRequired": "Требуется модель встраивания", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Модель эмбеддингов не настроена", "nodes.knowledgeBase.indexMethodIsRequired": "Метод index является обязательным", + "nodes.knowledgeBase.notConfigured": "Не настроено", "nodes.knowledgeBase.rerankingModelIsInvalid": "Модель повторной ранжировки недействительна", "nodes.knowledgeBase.rerankingModelIsRequired": "Требуется модель перераспределения рангов", "nodes.knowledgeBase.retrievalSettingIsRequired": "Настройка извлечения обязательна", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Поддерживает только Jinja2", "nodes.templateTransform.inputVars": "Входные переменные", "nodes.templateTransform.outputVars.output": "Преобразованный контент", + "nodes.tool.authorizationRequired": "Требуется авторизация", "nodes.tool.authorize": "Авторизовать", "nodes.tool.inputVars": "Входные переменные", "nodes.tool.insertPlaceholder1": "Наберите или нажмите", @@ -1062,10 +1071,12 @@ "panel.change": "Изменить", "panel.changeBlock": "Изменить узел", "panel.checklist": "Контрольный список", + "panel.checklistDescription": "Устраните следующие проблемы перед публикацией", "panel.checklistResolved": "Все проблемы решены", "panel.checklistTip": "Убедитесь, что все проблемы решены перед публикацией", "panel.createdBy": "Создано ", "panel.goTo": "Перейти к", + "panel.goToFix": "Перейти к исправлению", "panel.helpLink": "Помощь", "panel.maximize": "Максимизировать холст", "panel.minimize": "Выйти из полноэкранного режима", diff --git a/web/i18n/sl-SI/app-debug.json b/web/i18n/sl-SI/app-debug.json index 948e3dbc67..cf3d6c9ec4 100644 --- a/web/i18n/sl-SI/app-debug.json +++ b/web/i18n/sl-SI/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "TEČI", "inputs.title": "Odpravljanje napak in predogled", "inputs.userInputField": "Uporabniško polje za vnos", + "manageModels": "Upravljanje modelov", "modelConfig.modeType.chat": "Chat", "modelConfig.modeType.completion": "Dokončati", "modelConfig.model": "Model", "modelConfig.setTone": "Nastavitev tona odzivov", "modelConfig.title": "Model in parametri", + "noModelProviderConfigured": "Ponudnik modelov ni konfiguriran", + "noModelProviderConfiguredTip": "Za začetek namestite ali konfigurirajte ponudnika modelov.", + "noModelSelected": "Noben model ni izbran", + "noModelSelectedTip": "Za nadaljevanje konfigurirajte model zgoraj.", "noResult": "Tukaj bo prikazan izhod.", "notSetAPIKey.description": "Ključ ponudnika LLM ni nastavljen. Pred odpravljanjem napak je treba nastaviti ključ.", "notSetAPIKey.settingBtn": "Pojdi v nastavitve", diff --git a/web/i18n/sl-SI/common.json b/web/i18n/sl-SI/common.json index 247874bb30..6ec4fe430c 100644 --- a/web/i18n/sl-SI/common.json +++ b/web/i18n/sl-SI/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Neavtorizirano", "modelProvider.buyQuota": "Kupi kvoto", "modelProvider.callTimes": "Število klicev", + "modelProvider.card.aiCreditsInUse": "Krediti AI v uporabi", + "modelProvider.card.aiCreditsOption": "Krediti AI", + "modelProvider.card.apiKeyOption": "API ključ", + "modelProvider.card.apiKeyRequired": "Potreben je API ključ", + "modelProvider.card.apiKeyUnavailableFallback": "API ključ ni na voljo, zdaj se uporabljajo krediti AI", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Preverite konfiguracijo API ključa za preklop nazaj", "modelProvider.card.buyQuota": "Kupi kvoto", "modelProvider.card.callTimes": "Časi klicev", + "modelProvider.card.creditsExhaustedDescription": "Prosimo, nadgradite načrt ali konfigurirajte API ključ", + "modelProvider.card.creditsExhaustedFallback": "Krediti AI so porabljeni, zdaj se uporablja API ključ", + "modelProvider.card.creditsExhaustedFallbackDescription": "Nadgradite načrt za nadaljevanje prednostne uporabe kreditov AI.", + "modelProvider.card.creditsExhaustedMessage": "Krediti AI so bili porabljeni", "modelProvider.card.modelAPI": "Modeli {{modelName}} uporabljajo API ključ.", "modelProvider.card.modelNotSupported": "Modeli {{modelName}} niso nameščeni.", "modelProvider.card.modelSupported": "Modeli {{modelName}} uporabljajo to kvoto.", + "modelProvider.card.noApiKeysDescription": "Dodajte API ključ za začetek uporabe lastnih poverilnic modela.", + "modelProvider.card.noApiKeysFallback": "Ni API ključev, namesto tega se uporabljajo krediti AI", + "modelProvider.card.noApiKeysTitle": "Še ni konfiguriranih API ključev", + "modelProvider.card.noAvailableUsage": "Ni razpoložljive uporabe", "modelProvider.card.onTrial": "Na preizkusu", "modelProvider.card.paid": "Plačano", "modelProvider.card.priorityUse": "Prednostna uporaba", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Odstrani API ključ", "modelProvider.card.tip": "Krediti za sporočila podpirajo modele od {{modelNames}}. Prednostno se bo uporabila plačana kvota. Brezplačna kvota se bo uporabila, ko bo plačana kvota porabljena.", "modelProvider.card.tokens": "Žetoni", + "modelProvider.card.unavailable": "Ni na voljo", + "modelProvider.card.upgradePlan": "nadgradite načrt", + "modelProvider.card.usageLabel": "Poraba", + "modelProvider.card.usagePriority": "Prednost porabe", + "modelProvider.card.usagePriorityTip": "Nastavite, kateri vir se bo najprej uporabil pri zaganjanju modelov.", "modelProvider.collapse": "Strni", "modelProvider.config": "Konfiguracija", "modelProvider.configLoadBalancing": "Konfiguracija uravnoteženja obremenitev", @@ -387,9 +406,11 @@ "modelProvider.model": "Model", "modelProvider.modelAndParameters": "Model in parametri", "modelProvider.modelHasBeenDeprecated": "Ta model je zastarel", + "modelProvider.modelSettings": "Nastavitve modela", "modelProvider.models": "Modeli", "modelProvider.modelsNum": "{{num}} modelov", "modelProvider.noModelFound": "Za {{model}} ni najden noben model", + "modelProvider.noneConfigured": "Konfigurirajte privzeti sistemski model za zaganjanje aplikacij", "modelProvider.notConfigured": "Sistemski model še ni popolnoma konfiguriran, nekatere funkcije morda ne bodo na voljo.", "modelProvider.parameters": "PARAMETRI", "modelProvider.parametersInvalidRemoved": "Nekateri parametri so neveljavni in so bili odstranjeni.", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Ponastavi {{date}}", "modelProvider.searchModel": "Model iskanja", "modelProvider.selectModel": "Izberite svoj model", + "modelProvider.selector.aiCredits": "Krediti AI", + "modelProvider.selector.apiKeyUnavailable": "API ključ ni na voljo", + "modelProvider.selector.apiKeyUnavailableTip": "API ključ je bil odstranjen. Prosimo, konfigurirajte nov API ključ.", + "modelProvider.selector.configure": "Konfiguriraj", + "modelProvider.selector.configureRequired": "Konfiguracija je obvezna", + "modelProvider.selector.creditsExhausted": "Krediti so porabljeni", + "modelProvider.selector.creditsExhaustedTip": "Vaši krediti AI so bili porabljeni. Prosimo, nadgradite načrt ali dodajte API ključ.", + "modelProvider.selector.disabled": "Onemogočeno", + "modelProvider.selector.discoverMoreInMarketplace": "Odkrijte več v Tržnici", "modelProvider.selector.emptySetting": "Prosimo, pojdite v nastavitve za konfiguracijo", "modelProvider.selector.emptyTip": "Ni razpoložljivih modelov", + "modelProvider.selector.fromMarketplace": "Iz Tržnice", + "modelProvider.selector.incompatible": "Nezdružljivo", + "modelProvider.selector.incompatibleTip": "Ta model ni na voljo v trenutni različici. Izberite drug razpoložljiv model.", + "modelProvider.selector.install": "Namesti", + "modelProvider.selector.modelProviderSettings": "Nastavitve ponudnika modelov", + "modelProvider.selector.noProviderConfigured": "Noben ponudnik modelov ni konfiguriran", + "modelProvider.selector.noProviderConfiguredDesc": "Poiščite v Tržnici za namestitev ali konfigurirajte ponudnike v nastavitvah.", + "modelProvider.selector.onlyCompatibleModelsShown": "Prikazani so samo združljivi modeli", "modelProvider.selector.rerankTip": "Prosimo, nastavite model za prerazvrstitev", "modelProvider.selector.tip": "Ta model je bil odstranjen. Prosimo, dodajte model ali izberite drugega.", "modelProvider.setupModelFirst": "Najprej nastavite svoj model", diff --git a/web/i18n/sl-SI/plugin.json b/web/i18n/sl-SI/plugin.json index 0f84e91c80..91f6c670bf 100644 --- a/web/i18n/sl-SI/plugin.json +++ b/web/i18n/sl-SI/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Odstrani vtičnik", "action.deleteContentLeft": "Ali želite odstraniti", "action.deleteContentRight": "vtičnik?", + "action.deleteSuccess": "Vtičnik je bil uspešno odstranjen", "action.pluginInfo": "Informacije o vtičniku", "action.usedInApps": "Ta vtičnik se uporablja v {{num}} aplikacijah.", "allCategories": "Vse kategorije", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Namestite", "detailPanel.operation.remove": "Odstrani", "detailPanel.operation.update": "Posodobitev", + "detailPanel.operation.updateTooltip": "Posodobite za dostop do najnovejših modelov.", "detailPanel.operation.viewDetail": "Oglej si podrobnosti", "detailPanel.serviceOk": "Storitve so v redu", "detailPanel.strategyNum": "{{num}} {{strategy}} VKLJUČENO", @@ -231,12 +233,18 @@ "source.local": "Lokalna paketna datoteka", "source.marketplace": "Tržnica", "task.clearAll": "Počisti vse", + "task.errorMsg.github": "Ta vtičnik ni bil samodejno nameščen.\nProsimo, namestite ga iz GitHuba.", + "task.errorMsg.marketplace": "Ta vtičnik ni bil samodejno nameščen.\nProsimo, namestite ga iz Tržnice.", + "task.errorMsg.unknown": "Ta vtičnik ni bil nameščen.\nIzvora vtičnika ni mogoče ugotoviti.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} vtičnikov ni uspelo namestiti, kliknite za ogled", + "task.installFromGithub": "Namestite iz GitHuba", + "task.installFromMarketplace": "Namestite iz Tržnice", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} vtičnikov ni uspelo namestiti", "task.installing": "Nameščanje vtičnikov.", + "task.installingHint": "Nameščanje... To lahko traja nekaj minut.", "task.installingWithError": "Namestitev {{installingLength}} vtičnikov, {{successLength}} uspešnih, {{errorLength}} neuspešnih", "task.installingWithSuccess": "Namestitev {{installingLength}} dodatkov, {{successLength}} uspešnih.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/sl-SI/workflow.json b/web/i18n/sl-SI/workflow.json index f11175d1d4..a20a30753d 100644 --- a/web/i18n/sl-SI/workflow.json +++ b/web/i18n/sl-SI/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "posodabljanje delovnega procesa", "error.startNodeRequired": "Prosimo, najprej dodajte začetni vozel pred {{operation}}", "errorMsg.authRequired": "Zahtevana je avtorizacija", + "errorMsg.configureModel": "Konfiguriraj model", "errorMsg.fieldRequired": "{{field}} je obvezno", "errorMsg.fields.code": "Koda", "errorMsg.fields.model": "Model", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Vizijska spremenljivka", "errorMsg.invalidJson": "{{field}} je neveljaven JSON", "errorMsg.invalidVariable": "Neveljavna spremenljivka", + "errorMsg.modelPluginNotInstalled": "Neveljavna spremenljivka. Konfigurirajte model za omogočanje te spremenljivke.", "errorMsg.noValidTool": "{{field}} ni izbranega veljavnega orodja", "errorMsg.rerankModelRequired": "Zahteva se konfigurirana model ponovnega razvrščanja.", "errorMsg.startNodeRequired": "Prosimo, najprej dodajte začetni vozel pred {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Velikost okna", "nodes.common.outputVars": "Izhodne spremenljivke", "nodes.common.pluginNotInstalled": "Vtičnik ni nameščen", + "nodes.common.pluginsNotInstalled": "{{count}} vtičnikov ni nameščenih", "nodes.common.retry.maxRetries": "maksimalno število poskusov", "nodes.common.retry.ms": "ms", "nodes.common.retry.retries": "{{num}} Poskusi", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Kosi", "nodes.knowledgeBase.chunksInputTip": "Vhodna spremenljivka vozlišča podatkovne baze je Chunks. Tip spremenljivke je objekt s specifično JSON shemo, ki mora biti skladna z izbrano strukturo kosov.", "nodes.knowledgeBase.chunksVariableIsRequired": "Spremenljivka Chunks je obvezna", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API ključ ni na voljo", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Krediti so porabljeni", + "nodes.knowledgeBase.embeddingModelIncompatible": "Nezdružljivo", "nodes.knowledgeBase.embeddingModelIsInvalid": "Vdelovalni model ni veljaven", "nodes.knowledgeBase.embeddingModelIsRequired": "Zahteva se vgrajevalni model", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Vdelovalni model ni konfiguriran", "nodes.knowledgeBase.indexMethodIsRequired": "Zahteva se indeksna metoda", + "nodes.knowledgeBase.notConfigured": "Ni konfigurirano", "nodes.knowledgeBase.rerankingModelIsInvalid": "Model prerazvrščanja ni veljaven", "nodes.knowledgeBase.rerankingModelIsRequired": "Potreben je model za ponovno razvrščanje", "nodes.knowledgeBase.retrievalSettingIsRequired": "Zahtevana je nastavitev pridobivanja", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Podpira samo Jinja2", "nodes.templateTransform.inputVars": "Vhodne spremenljivke", "nodes.templateTransform.outputVars.output": "Transformirana vsebina", + "nodes.tool.authorizationRequired": "Zahtevana je avtorizacija", "nodes.tool.authorize": "Pooblasti", "nodes.tool.inputVars": "Vhodne spremenljivke", "nodes.tool.insertPlaceholder1": "Vnesite ali pritisnite", @@ -1062,10 +1071,12 @@ "panel.change": "Spremeni", "panel.changeBlock": "Spremeni vozlišče", "panel.checklist": "Kontrolni seznam", + "panel.checklistDescription": "Rešite naslednje težave pred objavo", "panel.checklistResolved": "Vse težave so rešene", "panel.checklistTip": "Prepričajte se, da so vse težave rešene, preden objavite.", "panel.createdBy": "Ustvarjeno z", "panel.goTo": "Pojdi na", + "panel.goToFix": "Pojdi na popravi", "panel.helpLink": "Pomoč", "panel.maximize": "Maksimiziraj platno", "panel.minimize": "Izhod iz celotnega zaslona", diff --git a/web/i18n/th-TH/app-debug.json b/web/i18n/th-TH/app-debug.json index 53dc629a7f..c36db9ce18 100644 --- a/web/i18n/th-TH/app-debug.json +++ b/web/i18n/th-TH/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "วิ่ง", "inputs.title": "ดีบัก & ดูตัวอย่าง", "inputs.userInputField": "ฟิลด์ป้อนข้อมูลของผู้ใช้", + "manageModels": "จัดการโมเดล", "modelConfig.modeType.chat": "สนทนา", "modelConfig.modeType.completion": "สมบูรณ์", "modelConfig.model": "แบบ", "modelConfig.setTone": "กําหนดน้ําเสียงของการตอบกลับ", "modelConfig.title": "รุ่นและพารามิเตอร์", + "noModelProviderConfigured": "ยังไม่ได้กำหนดค่าผู้ให้บริการโมเดล", + "noModelProviderConfiguredTip": "ติดตั้งหรือกำหนดค่าผู้ให้บริการโมเดลเพื่อเริ่มต้นใช้งาน", + "noModelSelected": "ยังไม่ได้เลือกโมเดล", + "noModelSelectedTip": "กำหนดค่าโมเดลด้านบนเพื่อดำเนินการต่อ", "noResult": "ผลลัพธ์จะแสดงที่นี่", "notSetAPIKey.description": "ยังไม่ได้ตั้งค่าคีย์ผู้ให้บริการ LLM และจําเป็นต้องตั้งค่าก่อนการดีบัก", "notSetAPIKey.settingBtn": "ไปที่การตั้งค่า", diff --git a/web/i18n/th-TH/common.json b/web/i18n/th-TH/common.json index 71c9369599..6eed5eba93 100644 --- a/web/i18n/th-TH/common.json +++ b/web/i18n/th-TH/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "ไม่ได้รับอนุญาต", "modelProvider.buyQuota": "ซื้อโควต้า", "modelProvider.callTimes": "เวลาโทร", + "modelProvider.card.aiCreditsInUse": "กำลังใช้เครดิต AI", + "modelProvider.card.aiCreditsOption": "เครดิต AI", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "ต้องการ API Key", + "modelProvider.card.apiKeyUnavailableFallback": "API Key ไม่พร้อมใช้งาน กำลังใช้เครดิต AI แทน", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "ตรวจสอบการกำหนดค่า API Key ของคุณเพื่อสลับกลับ", "modelProvider.card.buyQuota": "ซื้อโควต้า", "modelProvider.card.callTimes": "เวลาโทร", + "modelProvider.card.creditsExhaustedDescription": "กรุณาอัปเกรดแพ็กเกจหรือกำหนดค่า API Key", + "modelProvider.card.creditsExhaustedFallback": "เครดิต AI หมดแล้ว กำลังใช้ API Key แทน", + "modelProvider.card.creditsExhaustedFallbackDescription": "อัปเกรดแพ็กเกจเพื่อกลับมาใช้เครดิต AI เป็นลำดับแรก", + "modelProvider.card.creditsExhaustedMessage": "เครดิต AI หมดแล้ว", "modelProvider.card.modelAPI": "โมเดล {{modelName}} กำลังใช้คีย์ API", "modelProvider.card.modelNotSupported": "โมเดล {{modelName}} ไม่ได้ติดตั้ง", "modelProvider.card.modelSupported": "โมเดล {{modelName}} กำลังใช้โควต้านี้", + "modelProvider.card.noApiKeysDescription": "เพิ่ม API Key เพื่อเริ่มใช้ข้อมูลรับรองโมเดลของคุณเอง", + "modelProvider.card.noApiKeysFallback": "ไม่มี API Key กำลังใช้เครดิต AI แทน", + "modelProvider.card.noApiKeysTitle": "ยังไม่ได้กำหนดค่า API Key", + "modelProvider.card.noAvailableUsage": "ไม่มีปริมาณการใช้งานที่พร้อมใช้", "modelProvider.card.onTrial": "ทดลองใช้", "modelProvider.card.paid": "จ่าย", "modelProvider.card.priorityUse": "ลําดับความสําคัญในการใช้งาน", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "ลบคีย์ API", "modelProvider.card.tip": "เครดิตข้อความรองรับโมเดลจาก {{modelNames}} จะให้ลำดับความสำคัญกับโควต้าที่ชำระแล้ว โควต้าฟรีจะถูกใช้หลังจากโควต้าที่ชำระแล้วหมด", "modelProvider.card.tokens": "โท เค็น", + "modelProvider.card.unavailable": "ไม่พร้อมใช้งาน", + "modelProvider.card.upgradePlan": "อัปเกรดแพ็กเกจ", + "modelProvider.card.usageLabel": "การใช้งาน", + "modelProvider.card.usagePriority": "ลำดับความสำคัญการใช้งาน", + "modelProvider.card.usagePriorityTip": "ตั้งค่าทรัพยากรที่จะใช้ก่อนเมื่อเรียกใช้โมเดล", "modelProvider.collapse": "ทรุด", "modelProvider.config": "กําหนดค่า", "modelProvider.configLoadBalancing": "กําหนดค่าโหลดบาลานซ์", @@ -387,9 +406,11 @@ "modelProvider.model": "แบบ", "modelProvider.modelAndParameters": "รุ่นและพารามิเตอร์", "modelProvider.modelHasBeenDeprecated": "โมเดลนี้เลิกใช้แล้ว", + "modelProvider.modelSettings": "การตั้งค่าโมเดล", "modelProvider.models": "รุ่น", "modelProvider.modelsNum": "{{num}} รุ่น", "modelProvider.noModelFound": "ไม่พบแบบจําลองสําหรับ {{model}}", + "modelProvider.noneConfigured": "กำหนดค่าโมเดลระบบเริ่มต้นเพื่อเรียกใช้แอปพลิเคชัน", "modelProvider.notConfigured": "โมเดลระบบยังไม่ได้รับการกําหนดค่าอย่างสมบูรณ์ และฟังก์ชันบางอย่างอาจไม่พร้อมใช้งาน", "modelProvider.parameters": "พารามิเตอร์", "modelProvider.parametersInvalidRemoved": "บางพารามิเตอร์ไม่ถูกต้องและถูกนำออก", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "รีเซ็ตเมื่อ {{date}}", "modelProvider.searchModel": "ค้นหารุ่น", "modelProvider.selectModel": "เลือกรุ่นของคุณ", + "modelProvider.selector.aiCredits": "เครดิต AI", + "modelProvider.selector.apiKeyUnavailable": "API Key ไม่พร้อมใช้งาน", + "modelProvider.selector.apiKeyUnavailableTip": "API Key ถูกลบแล้ว กรุณากำหนดค่า API Key ใหม่", + "modelProvider.selector.configure": "กำหนดค่า", + "modelProvider.selector.configureRequired": "ต้องกำหนดค่า", + "modelProvider.selector.creditsExhausted": "เครดิตหมดแล้ว", + "modelProvider.selector.creditsExhaustedTip": "เครดิต AI ของคุณหมดแล้ว กรุณาอัปเกรดแพ็กเกจหรือเพิ่ม API Key", + "modelProvider.selector.disabled": "ปิดใช้งาน", + "modelProvider.selector.discoverMoreInMarketplace": "ค้นพบเพิ่มเติมใน Marketplace", "modelProvider.selector.emptySetting": "โปรดไปที่การตั้งค่าเพื่อกําหนดค่า", "modelProvider.selector.emptyTip": "ไม่มีรุ่นที่พร้อมใช้งาน", + "modelProvider.selector.fromMarketplace": "จาก Marketplace", + "modelProvider.selector.incompatible": "ไม่รองรับ", + "modelProvider.selector.incompatibleTip": "โมเดลนี้ไม่พร้อมใช้งานในเวอร์ชันปัจจุบัน กรุณาเลือกโมเดลอื่นที่พร้อมใช้งาน", + "modelProvider.selector.install": "ติดตั้ง", + "modelProvider.selector.modelProviderSettings": "การตั้งค่าผู้ให้บริการโมเดล", + "modelProvider.selector.noProviderConfigured": "ยังไม่ได้กำหนดค่าผู้ให้บริการโมเดล", + "modelProvider.selector.noProviderConfiguredDesc": "เรียกดู Marketplace เพื่อติดตั้ง หรือกำหนดค่าผู้ให้บริการในการตั้งค่า", + "modelProvider.selector.onlyCompatibleModelsShown": "แสดงเฉพาะโมเดลที่รองรับเท่านั้น", "modelProvider.selector.rerankTip": "โปรดตั้งค่าโมเดล Rerank", "modelProvider.selector.tip": "รุ่นนี้ถูกลบออกแล้ว โปรดเพิ่มรุ่นหรือเลือกรุ่นอื่น", "modelProvider.setupModelFirst": "โปรดตั้งค่าโมเดลของคุณก่อน", diff --git a/web/i18n/th-TH/plugin.json b/web/i18n/th-TH/plugin.json index 1c5a544abc..0545d0d46b 100644 --- a/web/i18n/th-TH/plugin.json +++ b/web/i18n/th-TH/plugin.json @@ -3,6 +3,7 @@ "action.delete": "ลบปลั๊กอิน", "action.deleteContentLeft": "คุณต้องการลบ", "action.deleteContentRight": "ปลั๊กอิน?", + "action.deleteSuccess": "ลบปลั๊กอินสำเร็จแล้ว", "action.pluginInfo": "ข้อมูลปลั๊กอิน", "action.usedInApps": "ปลั๊กอินนี้ถูกใช้ในแอป {{num}}", "allCategories": "หมวดหมู่ทั้งหมด", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "ติดตั้ง", "detailPanel.operation.remove": "ถอด", "detailPanel.operation.update": "อัพเดต", + "detailPanel.operation.updateTooltip": "อัปเดตเพื่อเข้าถึงโมเดลล่าสุด", "detailPanel.operation.viewDetail": "ดูรายละเอียด", "detailPanel.serviceOk": "บริการตกลง", "detailPanel.strategyNum": "{{num}} {{strategy}} รวม", @@ -231,12 +233,18 @@ "source.local": "ไฟล์แพ็คเกจในเครื่อง", "source.marketplace": "ตลาด", "task.clearAll": "ล้างทั้งหมด", + "task.errorMsg.github": "ไม่สามารถติดตั้งปลั๊กอินนี้โดยอัตโนมัติได้\nกรุณาติดตั้งจาก GitHub", + "task.errorMsg.marketplace": "ไม่สามารถติดตั้งปลั๊กอินนี้โดยอัตโนมัติได้\nกรุณาติดตั้งจาก Marketplace", + "task.errorMsg.unknown": "ไม่สามารถติดตั้งปลั๊กอินนี้ได้\nไม่สามารถระบุแหล่งที่มาของปลั๊กอินได้", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} ปลั๊กอินติดตั้งไม่สําเร็จ คลิกเพื่อดู", + "task.installFromGithub": "ติดตั้งจาก GitHub", + "task.installFromMarketplace": "ติดตั้งจาก Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} ปลั๊กอินติดตั้งไม่สําเร็จ", "task.installing": "การติดตั้งปลั๊กอิน", + "task.installingHint": "กำลังติดตั้ง... อาจใช้เวลาสักครู่", "task.installingWithError": "การติดตั้งปลั๊กอิน {{installingLength}}, {{successLength}} สําเร็จ, {{errorLength}} ล้มเหลว", "task.installingWithSuccess": "การติดตั้งปลั๊กอิน {{installingLength}}, {{successLength}} สําเร็จ", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/th-TH/workflow.json b/web/i18n/th-TH/workflow.json index 84bfe5ed97..7819e884c3 100644 --- a/web/i18n/th-TH/workflow.json +++ b/web/i18n/th-TH/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "กำลังปรับปรุงเวิร์กโฟลว์", "error.startNodeRequired": "โปรดเพิ่มโหนดเริ่มต้นก่อน {{operation}}", "errorMsg.authRequired": "ต้องได้รับอนุญาต", + "errorMsg.configureModel": "กำหนดค่าโมเดล", "errorMsg.fieldRequired": "{{field}} เป็นสิ่งจําเป็น", "errorMsg.fields.code": "รหัส", "errorMsg.fields.model": "แบบ", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "ตัวแปรวิสัยทัศน์", "errorMsg.invalidJson": "{{field}} เป็น JSON ไม่ถูกต้อง", "errorMsg.invalidVariable": "ตัวแปรไม่ถูกต้อง", + "errorMsg.modelPluginNotInstalled": "ตัวแปรไม่ถูกต้อง กำหนดค่าโมเดลเพื่อเปิดใช้งานตัวแปรนี้", "errorMsg.noValidTool": "{{field}} ไม่ได้เลือกเครื่องมือที่ถูกต้อง", "errorMsg.rerankModelRequired": "ก่อนเปิด Rerank Model โปรดยืนยันว่าได้กําหนดค่าโมเดลสําเร็จในการตั้งค่า", "errorMsg.startNodeRequired": "โปรดเพิ่มโหนดเริ่มต้นก่อน {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "ขนาดหน้าต่าง", "nodes.common.outputVars": "ตัวแปรเอาต์พุต", "nodes.common.pluginNotInstalled": "ปลั๊กอินไม่ได้ติดตั้ง", + "nodes.common.pluginsNotInstalled": "{{count}} ปลั๊กอินยังไม่ได้ติดตั้ง", "nodes.common.retry.maxRetries": "การลองซ้ําสูงสุด", "nodes.common.retry.ms": "นางสาว", "nodes.common.retry.retries": "{{num}} ลอง", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "ชิ้นส่วน", "nodes.knowledgeBase.chunksInputTip": "ตัวแปรนำเข้าของโหนดฐานความรู้คือ Chunks ตัวแปรประเภทเป็นอ็อบเจ็กต์ที่มี JSON Schema เฉพาะซึ่งต้องสอดคล้องกับโครงสร้างชิ้นส่วนที่เลือกไว้.", "nodes.knowledgeBase.chunksVariableIsRequired": "ตัวแปร Chunks เป็นสิ่งจำเป็น", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API Key ไม่พร้อมใช้งาน", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "เครดิตหมดแล้ว", + "nodes.knowledgeBase.embeddingModelIncompatible": "ไม่รองรับ", "nodes.knowledgeBase.embeddingModelIsInvalid": "แบบจำลองการฝังไม่ถูกต้อง", "nodes.knowledgeBase.embeddingModelIsRequired": "จำเป็นต้องใช้โมเดลฝัง", + "nodes.knowledgeBase.embeddingModelNotConfigured": "ยังไม่ได้กำหนดค่าโมเดล Embedding", "nodes.knowledgeBase.indexMethodIsRequired": "ต้องใช้วิธีการจัดทําดัชนี", + "nodes.knowledgeBase.notConfigured": "ยังไม่ได้กำหนดค่า", "nodes.knowledgeBase.rerankingModelIsInvalid": "โมเดลการจัดอันดับใหม่ไม่ถูกต้อง", "nodes.knowledgeBase.rerankingModelIsRequired": "จำเป็นต้องมีโมเดลการจัดอันดับใหม่", "nodes.knowledgeBase.retrievalSettingIsRequired": "จําเป็นต้องมีการตั้งค่าการดึงข้อมูล", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "รองรับเฉพาะ Jinja2", "nodes.templateTransform.inputVars": "ตัวแปรอินพุต", "nodes.templateTransform.outputVars.output": "เนื้อหาที่แปลงโฉม", + "nodes.tool.authorizationRequired": "ต้องการการอนุญาต", "nodes.tool.authorize": "อนุญาต", "nodes.tool.inputVars": "ตัวแปรอินพุต", "nodes.tool.insertPlaceholder1": "พิมพ์หรือลงทะเบียน", @@ -1062,10 +1071,12 @@ "panel.change": "เปลี่ยน", "panel.changeBlock": "เปลี่ยนโหนด", "panel.checklist": "ตรวจ สอบ", + "panel.checklistDescription": "กรุณาแก้ไขปัญหาต่อไปนี้ก่อนเผยแพร่", "panel.checklistResolved": "ปัญหาทั้งหมดได้รับการแก้ไขแล้ว", "panel.checklistTip": "ตรวจสอบให้แน่ใจว่าปัญหาทั้งหมดได้รับการแก้ไขแล้วก่อนที่จะเผยแพร่", "panel.createdBy": "สร้างโดย", "panel.goTo": "ไปที่", + "panel.goToFix": "ไปแก้ไข", "panel.helpLink": "วิธีใช้", "panel.maximize": "เพิ่มประสิทธิภาพผ้าใบ", "panel.minimize": "ออกจากโหมดเต็มหน้าจอ", diff --git a/web/i18n/uk-UA/app-debug.json b/web/i18n/uk-UA/app-debug.json index 74dcc72efd..dd7ec2de8f 100644 --- a/web/i18n/uk-UA/app-debug.json +++ b/web/i18n/uk-UA/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "ЗАПУСТИТИ", "inputs.title": "Налагодження та попередній перегляд", "inputs.userInputField": "Поле введення користувача", + "manageModels": "Керування моделями", "modelConfig.modeType.chat": "Чат", "modelConfig.modeType.completion": "Завершення", "modelConfig.model": "Модель", "modelConfig.setTone": "Встановити тон відповідей", "modelConfig.title": "Модель і параметри", + "noModelProviderConfigured": "Постачальник моделей не налаштований", + "noModelProviderConfiguredTip": "Встановіть або налаштуйте постачальника моделей, щоб почати роботу.", + "noModelSelected": "Модель не вибрана", + "noModelSelectedTip": "налаштуйте модель вище, щоб продовжити.", "noResult": "Тут буде відображено вихідні дані.", "notSetAPIKey.description": "Ключ провайдера LLM не встановлено, і його потрібно встановити перед налагодженням.", "notSetAPIKey.settingBtn": "Перейти до налаштувань", diff --git a/web/i18n/uk-UA/common.json b/web/i18n/uk-UA/common.json index 6745644573..806cbede3d 100644 --- a/web/i18n/uk-UA/common.json +++ b/web/i18n/uk-UA/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Несанкціоновано", "modelProvider.buyQuota": "Придбати квоту", "modelProvider.callTimes": "Кількість викликів", + "modelProvider.card.aiCreditsInUse": "Використовуються AI-кредити", + "modelProvider.card.aiCreditsOption": "AI-кредити", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "Потрібен API-ключ", + "modelProvider.card.apiKeyUnavailableFallback": "API Key недоступний, використовуються AI-кредити", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Перевірте конфігурацію API-ключа, щоб повернутися до нього", "modelProvider.card.buyQuota": "Придбати квоту", "modelProvider.card.callTimes": "Кількість викликів", + "modelProvider.card.creditsExhaustedDescription": "Будь ласка, оновіть свій план або налаштуйте API-ключ", + "modelProvider.card.creditsExhaustedFallback": "AI-кредити вичерпано, використовується API Key", + "modelProvider.card.creditsExhaustedFallbackDescription": "Оновіть свій план, щоб відновити пріоритет AI-кредитів.", + "modelProvider.card.creditsExhaustedMessage": "AI-кредити вичерпано", "modelProvider.card.modelAPI": "Моделі {{modelName}} використовують API-ключ.", "modelProvider.card.modelNotSupported": "Моделі {{modelName}} не встановлено.", "modelProvider.card.modelSupported": "Моделі {{modelName}} використовують цю квоту.", + "modelProvider.card.noApiKeysDescription": "Додайте API-ключ, щоб почати використовувати власні облікові дані моделі.", + "modelProvider.card.noApiKeysFallback": "API-ключі відсутні, використовуються AI-кредити", + "modelProvider.card.noApiKeysTitle": "API-ключі ще не налаштовані", + "modelProvider.card.noAvailableUsage": "Немає доступного використання", "modelProvider.card.onTrial": "У пробному періоді", "modelProvider.card.paid": "Оплачено", "modelProvider.card.priorityUse": "Пріоритетне використання", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Видалити ключ API", "modelProvider.card.tip": "Кредити повідомлень підтримують моделі від {{modelNames}}. Пріоритет буде надано оплаченій квоті. Безкоштовна квота буде використовуватися після вичерпання платної квоти.", "modelProvider.card.tokens": "Токени", + "modelProvider.card.unavailable": "Недоступно", + "modelProvider.card.upgradePlan": "оновіть свій план", + "modelProvider.card.usageLabel": "Використання", + "modelProvider.card.usagePriority": "Пріоритет використання", + "modelProvider.card.usagePriorityTip": "Встановіть, який ресурс використовувати першим при запуску моделей.", "modelProvider.collapse": "Згорнути", "modelProvider.config": "Налаштування", "modelProvider.configLoadBalancing": "Балансування навантаження конфігурації", @@ -387,9 +406,11 @@ "modelProvider.model": "Модель", "modelProvider.modelAndParameters": "Модель та параметри", "modelProvider.modelHasBeenDeprecated": "Ця модель вважається застарілою", + "modelProvider.modelSettings": "Налаштування моделі", "modelProvider.models": "Моделі", "modelProvider.modelsNum": "{{num}} моделей", "modelProvider.noModelFound": "Модель для {{model}} не знайдено", + "modelProvider.noneConfigured": "Налаштуйте системну модель за замовчуванням для запуску застосунків", "modelProvider.notConfigured": "Системну модель ще не повністю налаштовано, і деякі функції можуть бути недоступні.", "modelProvider.parameters": "ПАРАМЕТРИ", "modelProvider.parametersInvalidRemoved": "Деякі параметри є недійсними і були видалені", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Скидання {{date}}", "modelProvider.searchModel": "Пошукова модель", "modelProvider.selectModel": "Виберіть свою модель", + "modelProvider.selector.aiCredits": "AI-кредити", + "modelProvider.selector.apiKeyUnavailable": "API Key недоступний", + "modelProvider.selector.apiKeyUnavailableTip": "API-ключ було видалено. Будь ласка, налаштуйте новий API-ключ.", + "modelProvider.selector.configure": "Налаштувати", + "modelProvider.selector.configureRequired": "Потрібне налаштування", + "modelProvider.selector.creditsExhausted": "Кредити вичерпано", + "modelProvider.selector.creditsExhaustedTip": "Ваші AI-кредити вичерпано. Будь ласка, оновіть свій план або додайте API-ключ.", + "modelProvider.selector.disabled": "Вимкнено", + "modelProvider.selector.discoverMoreInMarketplace": "Знайти більше в Marketplace", "modelProvider.selector.emptySetting": "Перейдіть до налаштувань, щоб налаштувати", "modelProvider.selector.emptyTip": "Доступні моделі відсутні", + "modelProvider.selector.fromMarketplace": "З Marketplace", + "modelProvider.selector.incompatible": "Несумісно", + "modelProvider.selector.incompatibleTip": "Ця модель недоступна в поточній версії. Будь ласка, виберіть іншу доступну модель.", + "modelProvider.selector.install": "Встановити", + "modelProvider.selector.modelProviderSettings": "Налаштування постачальника моделей", + "modelProvider.selector.noProviderConfigured": "Постачальник моделей не налаштований", + "modelProvider.selector.noProviderConfiguredDesc": "Перегляньте Marketplace для встановлення або налаштуйте постачальників у параметрах.", + "modelProvider.selector.onlyCompatibleModelsShown": "Показано лише сумісні моделі", "modelProvider.selector.rerankTip": "Будь ласка, налаштуйте модель повторного ранжування", "modelProvider.selector.tip": "Цю модель було видалено. Будь ласка, додайте модель або виберіть іншу.", "modelProvider.setupModelFirst": "Будь ласка, спочатку налаштуйте свою модель", diff --git a/web/i18n/uk-UA/plugin.json b/web/i18n/uk-UA/plugin.json index 98bebf0ca8..603a8226a3 100644 --- a/web/i18n/uk-UA/plugin.json +++ b/web/i18n/uk-UA/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Видалити плагін", "action.deleteContentLeft": "Чи хотіли б ви видалити", "action.deleteContentRight": "плагін?", + "action.deleteSuccess": "Плагін успішно видалено", "action.pluginInfo": "Інформація про плагін", "action.usedInApps": "Цей плагін використовується в додатках {{num}}.", "allCategories": "Всі категорії", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Інсталювати", "detailPanel.operation.remove": "Видалити", "detailPanel.operation.update": "Оновлювати", + "detailPanel.operation.updateTooltip": "Оновіть, щоб отримати доступ до найновіших моделей.", "detailPanel.operation.viewDetail": "Переглянути деталі", "detailPanel.serviceOk": "Сервіс працює", "detailPanel.strategyNum": "{{num}} {{strategy}} ВКЛЮЧЕНІ", @@ -231,12 +233,18 @@ "source.local": "Файл локального пакета", "source.marketplace": "Ринку", "task.clearAll": "Очистити все", + "task.errorMsg.github": "Цей плагін не вдалося встановити автоматично.\nБудь ласка, встановіть його з GitHub.", + "task.errorMsg.marketplace": "Цей плагін не вдалося встановити автоматично.\nБудь ласка, встановіть його з Marketplace.", + "task.errorMsg.unknown": "Не вдалося встановити цей плагін.\nДжерело плагіна не вдалося визначити.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "Плагіни {{errorLength}} не вдалося встановити, натисніть, щоб переглянути", + "task.installFromGithub": "Встановити з GitHub", + "task.installFromMarketplace": "Встановити з Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "Плагіни {{errorLength}} не вдалося встановити", "task.installing": "Встановлення плагінів.", + "task.installingHint": "Встановлення... Це може зайняти кілька хвилин.", "task.installingWithError": "Не вдалося встановити плагіни {{installingLength}}, успіх {{successLength}}, {{errorLength}}", "task.installingWithSuccess": "Встановлення плагінів {{installingLength}}, успіх {{successLength}}.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/uk-UA/workflow.json b/web/i18n/uk-UA/workflow.json index e9365303f2..4fa95f6d57 100644 --- a/web/i18n/uk-UA/workflow.json +++ b/web/i18n/uk-UA/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "оновлення робочого процесу", "error.startNodeRequired": "Будь ласка, спершу додайте стартовий вузол перед {{operation}}", "errorMsg.authRequired": "Потрібна авторизація", + "errorMsg.configureModel": "Налаштуйте модель", "errorMsg.fieldRequired": "{{field}} є обов'язковим", "errorMsg.fields.code": "Код", "errorMsg.fields.model": "Модель", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Змінна зору", "errorMsg.invalidJson": "{{field}} є недійсним JSON", "errorMsg.invalidVariable": "Недійсна змінна", + "errorMsg.modelPluginNotInstalled": "Недійсна змінна. Налаштуйте модель, щоб увімкнути цю змінну.", "errorMsg.noValidTool": "{{field}} не вибрано дійсного інструменту", "errorMsg.rerankModelRequired": "Перед увімкненням Rerank Model, будь ласка, підтвердьте, що модель успішно налаштована в налаштуваннях.", "errorMsg.startNodeRequired": "Будь ласка, спершу додайте стартовий вузол перед {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Розмір вікна", "nodes.common.outputVars": "Змінні виходу", "nodes.common.pluginNotInstalled": "Плагін не встановлений", + "nodes.common.pluginsNotInstalled": "{{count}} плагінів не встановлено", "nodes.common.retry.maxRetries": "Максимальна кількість повторних спроб", "nodes.common.retry.ms": "МС", "nodes.common.retry.retries": "{{num}} Спроб", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Частини", "nodes.knowledgeBase.chunksInputTip": "Вхідна змінна вузла бази знань - це Частини. Тип змінної - об'єкт з певною JSON-схемою, яка повинна відповідати вибраній структурі частин.", "nodes.knowledgeBase.chunksVariableIsRequired": "Змінна chunks є обов'язковою", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API-ключ недоступний", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Кредити вичерпано", + "nodes.knowledgeBase.embeddingModelIncompatible": "Несумісно", "nodes.knowledgeBase.embeddingModelIsInvalid": "Модель вбудовування недійсна", "nodes.knowledgeBase.embeddingModelIsRequired": "Потрібна модель вбудовування", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Модель ембедингу не налаштована", "nodes.knowledgeBase.indexMethodIsRequired": "Обов'язковий індексний метод", + "nodes.knowledgeBase.notConfigured": "Не налаштовано", "nodes.knowledgeBase.rerankingModelIsInvalid": "Модель переналаштування недійсна", "nodes.knowledgeBase.rerankingModelIsRequired": "Потрібна модель повторного ранжування", "nodes.knowledgeBase.retrievalSettingIsRequired": "Потрібне налаштування для отримання", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Підтримує лише Jinja2", "nodes.templateTransform.inputVars": "Вхідні змінні", "nodes.templateTransform.outputVars.output": "Трансформований вміст", + "nodes.tool.authorizationRequired": "Потрібна авторизація", "nodes.tool.authorize": "Уповноважити", "nodes.tool.inputVars": "Вхідні змінні", "nodes.tool.insertPlaceholder1": "Введіть або натисніть", @@ -1062,10 +1071,12 @@ "panel.change": "Змінити", "panel.changeBlock": "Змінити вузол", "panel.checklist": "Контрольний список", + "panel.checklistDescription": "Вирішіть наступні проблеми перед публікацією", "panel.checklistResolved": "Всі проблеми вирішені", "panel.checklistTip": "Переконайтеся, що всі проблеми вирішені перед публікацією", "panel.createdBy": "Створено ", "panel.goTo": "Перейти до", + "panel.goToFix": "Перейти до виправлення", "panel.helpLink": "Довідковий центр", "panel.maximize": "Максимізувати полотно", "panel.minimize": "Вийти з повноекранного режиму", diff --git a/web/i18n/vi-VN/app-debug.json b/web/i18n/vi-VN/app-debug.json index d533a02370..92037650cb 100644 --- a/web/i18n/vi-VN/app-debug.json +++ b/web/i18n/vi-VN/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "CHẠY", "inputs.title": "Gỡ lỗi và xem trước", "inputs.userInputField": "Trường nhập liệu người dùng", + "manageModels": "Quản lý mô hình", "modelConfig.modeType.chat": "Trò chuyện", "modelConfig.modeType.completion": "Hoàn thành", "modelConfig.model": "Mô hình", "modelConfig.setTone": "Thiết lập giọng điệu của phản hồi", "modelConfig.title": "Mô hình và tham số", + "noModelProviderConfigured": "Chưa cấu hình nhà cung cấp mô hình", + "noModelProviderConfiguredTip": "Cài đặt hoặc cấu hình nhà cung cấp mô hình để bắt đầu.", + "noModelSelected": "Chưa chọn mô hình", + "noModelSelectedTip": "cấu hình mô hình ở trên để tiếp tục.", "noResult": "Đầu ra sẽ được hiển thị ở đây.", "notSetAPIKey.description": "Chưa thiết lập khóa API của nhà cung cấp LLM. Cần thiết lập trước khi gỡ lỗi.", "notSetAPIKey.settingBtn": "Đi đến cài đặt", diff --git a/web/i18n/vi-VN/common.json b/web/i18n/vi-VN/common.json index a47ee6da57..820bfdfdab 100644 --- a/web/i18n/vi-VN/common.json +++ b/web/i18n/vi-VN/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "Không có quyền truy cập", "modelProvider.buyQuota": "Mua Quyền lợi", "modelProvider.callTimes": "Số lần gọi", + "modelProvider.card.aiCreditsInUse": "Đang sử dụng AI credits", + "modelProvider.card.aiCreditsOption": "AI credits", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "Yêu cầu API key", + "modelProvider.card.apiKeyUnavailableFallback": "API Key không khả dụng, đang sử dụng AI credits", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "Kiểm tra cấu hình API key để chuyển lại", "modelProvider.card.buyQuota": "Mua Quota", "modelProvider.card.callTimes": "Số lần gọi", + "modelProvider.card.creditsExhaustedDescription": "Vui lòng nâng cấp gói dịch vụ hoặc cấu hình API key", + "modelProvider.card.creditsExhaustedFallback": "AI credits đã hết, đang sử dụng API Key", + "modelProvider.card.creditsExhaustedFallbackDescription": "Nâng cấp gói dịch vụ để khôi phục ưu tiên AI credits.", + "modelProvider.card.creditsExhaustedMessage": "AI credits đã hết", "modelProvider.card.modelAPI": "Các mô hình {{modelName}} đang sử dụng Khóa API.", "modelProvider.card.modelNotSupported": "Các mô hình {{modelName}} chưa được cài đặt.", "modelProvider.card.modelSupported": "Các mô hình {{modelName}} đang sử dụng hạn mức này.", + "modelProvider.card.noApiKeysDescription": "Thêm API key để bắt đầu sử dụng thông tin xác thực mô hình của bạn.", + "modelProvider.card.noApiKeysFallback": "Không có API key, sử dụng AI credits thay thế", + "modelProvider.card.noApiKeysTitle": "Chưa cấu hình API key", + "modelProvider.card.noAvailableUsage": "Không có lượt sử dụng khả dụng", "modelProvider.card.onTrial": "Thử nghiệm", "modelProvider.card.paid": "Đã thanh toán", "modelProvider.card.priorityUse": "Ưu tiên sử dụng", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "Remove API Key", "modelProvider.card.tip": "Tín dụng tin nhắn hỗ trợ các mô hình từ {{modelNames}}. Ưu tiên sẽ được trao cho hạn ngạch đã thanh toán. Hạn ngạch miễn phí sẽ được sử dụng sau khi hết hạn ngạch trả phí.", "modelProvider.card.tokens": "Tokens", + "modelProvider.card.unavailable": "Không khả dụng", + "modelProvider.card.upgradePlan": "nâng cấp gói dịch vụ", + "modelProvider.card.usageLabel": "Sử dụng", + "modelProvider.card.usagePriority": "Ưu tiên sử dụng", + "modelProvider.card.usagePriorityTip": "Đặt tài nguyên sử dụng trước khi chạy mô hình.", "modelProvider.collapse": "Thu gọn", "modelProvider.config": "Cấu hình", "modelProvider.configLoadBalancing": "Cấu hình cân bằng tải", @@ -387,9 +406,11 @@ "modelProvider.model": "Mô hình", "modelProvider.modelAndParameters": "Mô hình và Tham số", "modelProvider.modelHasBeenDeprecated": "Mô hình này đã bị phản đối", + "modelProvider.modelSettings": "Cài đặt mô hình", "modelProvider.models": "Mô hình", "modelProvider.modelsNum": "{{num}} Mô hình", "modelProvider.noModelFound": "Không tìm thấy mô hình cho {{model}}", + "modelProvider.noneConfigured": "Cấu hình mô hình hệ thống mặc định để chạy ứng dụng", "modelProvider.notConfigured": "Mô hình hệ thống vẫn chưa được cấu hình hoàn toàn và một số chức năng có thể không khả dụng.", "modelProvider.parameters": "THAM SỐ", "modelProvider.parametersInvalidRemoved": "Một số tham số không hợp lệ và đã được loại bỏ", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "Đặt lại vào {{date}}", "modelProvider.searchModel": "Mô hình tìm kiếm", "modelProvider.selectModel": "Chọn mô hình của bạn", + "modelProvider.selector.aiCredits": "AI credits", + "modelProvider.selector.apiKeyUnavailable": "API Key không khả dụng", + "modelProvider.selector.apiKeyUnavailableTip": "API key đã bị xóa. Vui lòng cấu hình API key mới.", + "modelProvider.selector.configure": "Cấu hình", + "modelProvider.selector.configureRequired": "Cần cấu hình", + "modelProvider.selector.creditsExhausted": "Credits đã hết", + "modelProvider.selector.creditsExhaustedTip": "AI credits của bạn đã hết. Vui lòng nâng cấp gói dịch vụ hoặc thêm API key.", + "modelProvider.selector.disabled": "Đã tắt", + "modelProvider.selector.discoverMoreInMarketplace": "Khám phá thêm trên Marketplace", "modelProvider.selector.emptySetting": "Vui lòng vào cài đặt để cấu hình", "modelProvider.selector.emptyTip": "Không có mô hình khả dụng", + "modelProvider.selector.fromMarketplace": "Từ Marketplace", + "modelProvider.selector.incompatible": "Không tương thích", + "modelProvider.selector.incompatibleTip": "Mô hình này không khả dụng trong phiên bản hiện tại. Vui lòng chọn mô hình khả dụng khác.", + "modelProvider.selector.install": "Cài đặt", + "modelProvider.selector.modelProviderSettings": "Cài đặt nhà cung cấp mô hình", + "modelProvider.selector.noProviderConfigured": "Chưa cấu hình nhà cung cấp mô hình", + "modelProvider.selector.noProviderConfiguredDesc": "Duyệt Marketplace để cài đặt hoặc cấu hình nhà cung cấp trong phần cài đặt.", + "modelProvider.selector.onlyCompatibleModelsShown": "Chỉ hiển thị các mô hình tương thích", "modelProvider.selector.rerankTip": "Vui lòng thiết lập mô hình sắp xếp lại", "modelProvider.selector.tip": "Mô hình này đã bị xóa. Vui lòng thêm một mô hình hoặc chọn mô hình khác.", "modelProvider.setupModelFirst": "Vui lòng thiết lập mô hình của bạn trước", diff --git a/web/i18n/vi-VN/plugin.json b/web/i18n/vi-VN/plugin.json index 40cc20b7b0..1c1b37bba3 100644 --- a/web/i18n/vi-VN/plugin.json +++ b/web/i18n/vi-VN/plugin.json @@ -3,6 +3,7 @@ "action.delete": "Xóa plugin", "action.deleteContentLeft": "Bạn có muốn xóa", "action.deleteContentRight": "plugin?", + "action.deleteSuccess": "Đã xóa plugin thành công", "action.pluginInfo": "Thông tin plugin", "action.usedInApps": "Plugin này đang được sử dụng trong các ứng dụng {{num}}.", "allCategories": "Tất cả các danh mục", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "Cài đặt", "detailPanel.operation.remove": "Triệt", "detailPanel.operation.update": "Cập nhật", + "detailPanel.operation.updateTooltip": "Cập nhật để truy cập các mô hình mới nhất.", "detailPanel.operation.viewDetail": "xem chi tiết", "detailPanel.serviceOk": "Dịch vụ OK", "detailPanel.strategyNum": "{{num}} {{strategy}} BAO GỒM", @@ -231,12 +233,18 @@ "source.local": "Tệp gói cục bộ", "source.marketplace": "Chợ", "task.clearAll": "Xóa tất cả", + "task.errorMsg.github": "Không thể cài đặt plugin này tự động.\nVui lòng cài đặt từ GitHub.", + "task.errorMsg.marketplace": "Không thể cài đặt plugin này tự động.\nVui lòng cài đặt từ Marketplace.", + "task.errorMsg.unknown": "Không thể cài đặt plugin này.\nKhông xác định được nguồn plugin.", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} plugin không cài đặt được, nhấp để xem", + "task.installFromGithub": "Cài đặt từ GitHub", + "task.installFromMarketplace": "Cài đặt từ Marketplace", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} plugin không cài đặt được", "task.installing": "Đang cài đặt plugin.", + "task.installingHint": "Đang cài đặt... Quá trình này có thể mất vài phút.", "task.installingWithError": "Cài đặt {{installingLength}} plugins, {{successLength}} thành công, {{errorLength}} không thành công", "task.installingWithSuccess": "Cài đặt {{installingLength}} plugins, {{successLength}} thành công.", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/vi-VN/workflow.json b/web/i18n/vi-VN/workflow.json index 3bdd86e231..3a8bdbaaf1 100644 --- a/web/i18n/vi-VN/workflow.json +++ b/web/i18n/vi-VN/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "cập nhật quy trình công việc", "error.startNodeRequired": "Vui lòng thêm một nút bắt đầu trước {{operation}}", "errorMsg.authRequired": "Yêu cầu xác thực", + "errorMsg.configureModel": "Cấu hình mô hình", "errorMsg.fieldRequired": "{{field}} là bắt buộc", "errorMsg.fields.code": "Mã", "errorMsg.fields.model": "Mô hình", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Biến tầm nhìn", "errorMsg.invalidJson": "{{field}} là JSON không hợp lệ", "errorMsg.invalidVariable": "Biến không hợp lệ", + "errorMsg.modelPluginNotInstalled": "Biến không hợp lệ. Cấu hình mô hình để kích hoạt biến này.", "errorMsg.noValidTool": "{{field}} không chọn công cụ hợp lệ nào", "errorMsg.rerankModelRequired": "Trước khi bật Mô hình xếp hạng lại, vui lòng xác nhận rằng mô hình đã được định cấu hình thành công trong cài đặt.", "errorMsg.startNodeRequired": "Vui lòng thêm một nút bắt đầu trước {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "Kích thước cửa sổ", "nodes.common.outputVars": "Biến đầu ra", "nodes.common.pluginNotInstalled": "Plugin chưa được cài đặt", + "nodes.common.pluginsNotInstalled": "{{count}} plugin chưa được cài đặt", "nodes.common.retry.maxRetries": "Số lần thử lại tối đa", "nodes.common.retry.ms": "Ms", "nodes.common.retry.retries": "{{num}} Thử lại", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "Mảnh", "nodes.knowledgeBase.chunksInputTip": "Biến đầu vào của nút cơ sở tri thức là Chunks. Loại biến là một đối tượng với một JSON Schema cụ thể mà phải nhất quán với cấu trúc chunk đã chọn.", "nodes.knowledgeBase.chunksVariableIsRequired": "Biến Chunks là bắt buộc", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API key không khả dụng", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "Credits đã hết", + "nodes.knowledgeBase.embeddingModelIncompatible": "Không tương thích", "nodes.knowledgeBase.embeddingModelIsInvalid": "Mô hình nhúng không hợp lệ", "nodes.knowledgeBase.embeddingModelIsRequired": "Cần có mô hình nhúng", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Chưa cấu hình mô hình nhúng", "nodes.knowledgeBase.indexMethodIsRequired": "Phương pháp chỉ mục là bắt buộc", + "nodes.knowledgeBase.notConfigured": "Chưa cấu hình", "nodes.knowledgeBase.rerankingModelIsInvalid": "Mô hình xếp hạng lại không hợp lệ", "nodes.knowledgeBase.rerankingModelIsRequired": "Cần có mô hình sắp xếp lại", "nodes.knowledgeBase.retrievalSettingIsRequired": "Cài đặt truy xuất là bắt buộc", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "Chỉ hỗ trợ Jinja2", "nodes.templateTransform.inputVars": "Biến đầu vào", "nodes.templateTransform.outputVars.output": "Nội dung chuyển đổi", + "nodes.tool.authorizationRequired": "Yêu cầu ủy quyền", "nodes.tool.authorize": "Ủy quyền", "nodes.tool.inputVars": "Biến đầu vào", "nodes.tool.insertPlaceholder1": "Gõ hoặc nhấn", @@ -1062,10 +1071,12 @@ "panel.change": "Thay đổi", "panel.changeBlock": "Thay đổi Node", "panel.checklist": "Danh sách kiểm tra", + "panel.checklistDescription": "Giải quyết các vấn đề sau trước khi xuất bản", "panel.checklistResolved": "Tất cả các vấn đề đã được giải quyết", "panel.checklistTip": "Đảm bảo rằng tất cả các vấn đề đã được giải quyết trước khi xuất bản", "panel.createdBy": "Tạo bởi ", "panel.goTo": "Đi tới", + "panel.goToFix": "Đi đến sửa lỗi", "panel.helpLink": "Trung tâm trợ giúp", "panel.maximize": "Tối đa hóa Canvas", "panel.minimize": "Thoát chế độ toàn màn hình", diff --git a/web/i18n/zh-Hant/app-debug.json b/web/i18n/zh-Hant/app-debug.json index ab7286691f..3058cd8458 100644 --- a/web/i18n/zh-Hant/app-debug.json +++ b/web/i18n/zh-Hant/app-debug.json @@ -235,11 +235,16 @@ "inputs.run": "執行", "inputs.title": "除錯與預覽", "inputs.userInputField": "使用者輸入", + "manageModels": "管理模型", "modelConfig.modeType.chat": "對話型", "modelConfig.modeType.completion": "補全型", "modelConfig.model": "語言模型", "modelConfig.setTone": "模型設定", "modelConfig.title": "模型及引數", + "noModelProviderConfigured": "未配置模型供應商", + "noModelProviderConfiguredTip": "請先安裝或配置模型供應商以開始使用。", + "noModelSelected": "未選擇模型", + "noModelSelectedTip": "請先在上方配置模型以繼續。", "noResult": "輸出將顯示在此處。", "notSetAPIKey.description": "在除錯之前需要設定 LLM 提供者的金鑰。", "notSetAPIKey.settingBtn": "去設定", diff --git a/web/i18n/zh-Hant/common.json b/web/i18n/zh-Hant/common.json index 85ff9cc687..9317f68f82 100644 --- a/web/i18n/zh-Hant/common.json +++ b/web/i18n/zh-Hant/common.json @@ -340,11 +340,25 @@ "modelProvider.auth.unAuthorized": "未經授權", "modelProvider.buyQuota": "購買額度", "modelProvider.callTimes": "呼叫次數", + "modelProvider.card.aiCreditsInUse": "AI 額度使用中", + "modelProvider.card.aiCreditsOption": "AI 額度", + "modelProvider.card.apiKeyOption": "API Key", + "modelProvider.card.apiKeyRequired": "需要配置 API Key", + "modelProvider.card.apiKeyUnavailableFallback": "API Key 不可用,正在使用 AI 額度", + "modelProvider.card.apiKeyUnavailableFallbackDescription": "檢查你的 API Key 配置以切換回來", "modelProvider.card.buyQuota": "購買額度", "modelProvider.card.callTimes": "呼叫次數", + "modelProvider.card.creditsExhaustedDescription": "請升級方案或配置 API Key", + "modelProvider.card.creditsExhaustedFallback": "AI 額度已用盡,正在使用 API Key", + "modelProvider.card.creditsExhaustedFallbackDescription": "升級方案以恢復 AI 額度優先使用。", + "modelProvider.card.creditsExhaustedMessage": "AI 額度已用盡", "modelProvider.card.modelAPI": "{{modelName}} 模型正在使用 API Key。", "modelProvider.card.modelNotSupported": "{{modelName}} 模型未安裝。", "modelProvider.card.modelSupported": "{{modelName}} 模型正在使用此配額。", + "modelProvider.card.noApiKeysDescription": "新增 API Key 以使用自有模型憑證。", + "modelProvider.card.noApiKeysFallback": "未配置 API Key,正在使用 AI 額度", + "modelProvider.card.noApiKeysTitle": "尚未配置 API Key", + "modelProvider.card.noAvailableUsage": "無可用額度", "modelProvider.card.onTrial": "試用中", "modelProvider.card.paid": "已購買", "modelProvider.card.priorityUse": "優先使用", @@ -353,6 +367,11 @@ "modelProvider.card.removeKey": "刪除 API 金鑰", "modelProvider.card.tip": "消息額度支持使用 {{modelNames}} 的模型;免費額度會在付費額度用盡後才會消耗。", "modelProvider.card.tokens": "Tokens", + "modelProvider.card.unavailable": "不可用", + "modelProvider.card.upgradePlan": "升級方案", + "modelProvider.card.usageLabel": "用量", + "modelProvider.card.usagePriority": "使用優先順序", + "modelProvider.card.usagePriorityTip": "設定執行模型時優先使用的資源。", "modelProvider.collapse": "收起", "modelProvider.config": "配置", "modelProvider.configLoadBalancing": "配置負載均衡", @@ -387,9 +406,11 @@ "modelProvider.model": "模型", "modelProvider.modelAndParameters": "模型及引數", "modelProvider.modelHasBeenDeprecated": "此模型已棄用", + "modelProvider.modelSettings": "模型設定", "modelProvider.models": "模型列表", "modelProvider.modelsNum": "{{num}} 個模型", "modelProvider.noModelFound": "找不到模型 {{model}}", + "modelProvider.noneConfigured": "配置預設系統模型以執行應用", "modelProvider.notConfigured": "系統模型尚未完全配置,部分功能可能無法使用。", "modelProvider.parameters": "引數", "modelProvider.parametersInvalidRemoved": "一些參數無效,已被移除", @@ -403,8 +424,25 @@ "modelProvider.resetDate": "於 {{date}} 重置", "modelProvider.searchModel": "搜尋模型", "modelProvider.selectModel": "選擇您的模型", + "modelProvider.selector.aiCredits": "AI 額度", + "modelProvider.selector.apiKeyUnavailable": "API Key 不可用", + "modelProvider.selector.apiKeyUnavailableTip": "API Key 已被移除,請重新配置 API Key。", + "modelProvider.selector.configure": "配置", + "modelProvider.selector.configureRequired": "需要配置", + "modelProvider.selector.creditsExhausted": "額度已用盡", + "modelProvider.selector.creditsExhaustedTip": "AI 額度已用盡,請升級方案或新增 API Key。", + "modelProvider.selector.disabled": "已停用", + "modelProvider.selector.discoverMoreInMarketplace": "在插件市場探索更多", "modelProvider.selector.emptySetting": "請前往設定進行配置", "modelProvider.selector.emptyTip": "無可用模型", + "modelProvider.selector.fromMarketplace": "從插件市場安裝", + "modelProvider.selector.incompatible": "不相容", + "modelProvider.selector.incompatibleTip": "此模型在目前版本中不可用,請選擇其他可用模型。", + "modelProvider.selector.install": "安裝", + "modelProvider.selector.modelProviderSettings": "模型供應商設定", + "modelProvider.selector.noProviderConfigured": "未配置模型供應商", + "modelProvider.selector.noProviderConfiguredDesc": "前往插件市場安裝,或在設定中配置供應商。", + "modelProvider.selector.onlyCompatibleModelsShown": "僅顯示相容的模型", "modelProvider.selector.rerankTip": "請設定 Rerank 模型", "modelProvider.selector.tip": "該模型已被刪除。請添模型或選擇其他模型。", "modelProvider.setupModelFirst": "請先設定您的模型", diff --git a/web/i18n/zh-Hant/plugin.json b/web/i18n/zh-Hant/plugin.json index 20630f41ab..4e7d577aaa 100644 --- a/web/i18n/zh-Hant/plugin.json +++ b/web/i18n/zh-Hant/plugin.json @@ -3,6 +3,7 @@ "action.delete": "刪除插件", "action.deleteContentLeft": "是否要刪除", "action.deleteContentRight": "插件?", + "action.deleteSuccess": "插件移除成功", "action.pluginInfo": "插件資訊", "action.usedInApps": "此插件正在 {{num}} 個應用程式中使用。", "allCategories": "全部分類", @@ -114,6 +115,7 @@ "detailPanel.operation.install": "安裝", "detailPanel.operation.remove": "刪除", "detailPanel.operation.update": "更新", + "detailPanel.operation.updateTooltip": "更新以取得最新模型。", "detailPanel.operation.viewDetail": "查看詳情", "detailPanel.serviceOk": "服務正常", "detailPanel.strategyNum": "{{num}} {{strategy}} 包括", @@ -231,12 +233,18 @@ "source.local": "本地包檔", "source.marketplace": "市場", "task.clearAll": "全部清除", + "task.errorMsg.github": "此插件無法自動安裝。\n請從 GitHub 安裝。", + "task.errorMsg.marketplace": "此插件無法自動安裝。\n請從插件市場安裝。", + "task.errorMsg.unknown": "此插件無法安裝。\n無法識別插件來源。", "task.errorPlugins": "Failed to Install Plugins", "task.installError": "{{errorLength}} 個插件安裝失敗,點擊查看", + "task.installFromGithub": "從 GitHub 安裝", + "task.installFromMarketplace": "從插件市場安裝", "task.installSuccess": "{{successLength}} plugins installed successfully", "task.installed": "Installed", "task.installedError": "{{errorLength}} 個插件安裝失敗", "task.installing": "正在安裝插件。", + "task.installingHint": "正在安裝……可能需要幾分鐘。", "task.installingWithError": "安裝 {{installingLength}} 個插件,{{successLength}} 成功,{{errorLength}} 失敗", "task.installingWithSuccess": "安裝 {{installingLength}} 個插件,{{successLength}} 成功。", "task.runningPlugins": "Installing Plugins", diff --git a/web/i18n/zh-Hant/workflow.json b/web/i18n/zh-Hant/workflow.json index 8a3c703f55..b739984977 100644 --- a/web/i18n/zh-Hant/workflow.json +++ b/web/i18n/zh-Hant/workflow.json @@ -305,6 +305,7 @@ "error.operations.updatingWorkflow": "更新工作流程", "error.startNodeRequired": "請先新增一個起始節點,再執行 {{operation}}", "errorMsg.authRequired": "請先授權", + "errorMsg.configureModel": "請配置模型", "errorMsg.fieldRequired": "{{field}} 不能為空", "errorMsg.fields.code": "程式碼", "errorMsg.fields.model": "模型", @@ -314,6 +315,7 @@ "errorMsg.fields.visionVariable": "Vision Variable", "errorMsg.invalidJson": "{{field}} 是非法的 JSON", "errorMsg.invalidVariable": "無效的變數", + "errorMsg.modelPluginNotInstalled": "無效的變數。請配置模型以啟用此變數。", "errorMsg.noValidTool": "{{field}} 未選擇有效工具", "errorMsg.rerankModelRequired": "在開啟 Rerank 模型之前,請在設置中確認模型配置成功。", "errorMsg.startNodeRequired": "請先新增一個起始節點,再執行 {{operation}}", @@ -444,6 +446,7 @@ "nodes.common.memory.windowSize": "記憶窗口", "nodes.common.outputVars": "輸出變數", "nodes.common.pluginNotInstalled": "插件未安裝", + "nodes.common.pluginsNotInstalled": "{{count}} 個插件未安裝", "nodes.common.retry.maxRetries": "最大重試次數", "nodes.common.retry.ms": "毫秒", "nodes.common.retry.retries": "{{num}}重試", @@ -686,9 +689,14 @@ "nodes.knowledgeBase.chunksInput": "區塊", "nodes.knowledgeBase.chunksInputTip": "知識庫節點的輸入變數是 Chunks。該變數類型是一個物件,具有特定的 JSON Schema,必須與所選的塊結構一致。", "nodes.knowledgeBase.chunksVariableIsRequired": "Chunks 變數是必需的", + "nodes.knowledgeBase.embeddingModelApiKeyUnavailable": "API Key 不可用", + "nodes.knowledgeBase.embeddingModelCreditsExhausted": "額度已用盡", + "nodes.knowledgeBase.embeddingModelIncompatible": "不相容", "nodes.knowledgeBase.embeddingModelIsInvalid": "嵌入模型無效", "nodes.knowledgeBase.embeddingModelIsRequired": "需要嵌入模型", + "nodes.knowledgeBase.embeddingModelNotConfigured": "Embedding 模型未配置", "nodes.knowledgeBase.indexMethodIsRequired": "索引方法是必填的", + "nodes.knowledgeBase.notConfigured": "未配置", "nodes.knowledgeBase.rerankingModelIsInvalid": "重排序模型無效", "nodes.knowledgeBase.rerankingModelIsRequired": "需要重新排序模型", "nodes.knowledgeBase.retrievalSettingIsRequired": "需要檢索設定", @@ -872,6 +880,7 @@ "nodes.templateTransform.codeSupportTip": "只支持 Jinja2", "nodes.templateTransform.inputVars": "輸入變數", "nodes.templateTransform.outputVars.output": "轉換後內容", + "nodes.tool.authorizationRequired": "需要授權", "nodes.tool.authorize": "授權", "nodes.tool.inputVars": "輸入變數", "nodes.tool.insertPlaceholder1": "輸入或按壓", @@ -1062,10 +1071,12 @@ "panel.change": "更改", "panel.changeBlock": "更改節點", "panel.checklist": "檢查清單", + "panel.checklistDescription": "發佈前請解決以下問題", "panel.checklistResolved": "所有問題均已解決", "panel.checklistTip": "發佈前確保所有問題均已解決", "panel.createdBy": "作者", "panel.goTo": "前往", + "panel.goToFix": "前往修復", "panel.helpLink": "查看幫助文件", "panel.maximize": "最大化畫布", "panel.minimize": "退出全螢幕", diff --git a/web/next.config.ts b/web/next.config.ts index 838aa561a3..aa4d9318f4 100644 --- a/web/next.config.ts +++ b/web/next.config.ts @@ -10,7 +10,6 @@ const nextConfig: NextConfig = { basePath: env.NEXT_PUBLIC_BASE_PATH, transpilePackages: ['@t3-oss/env-core', '@t3-oss/env-nextjs', 'echarts', 'zrender'], turbopack: { - root: process.cwd(), rules: codeInspectorPlugin({ bundler: 'turbopack', }), diff --git a/web/package.json b/web/package.json index 65372ef5f5..9ed21fdb22 100644 --- a/web/package.json +++ b/web/package.json @@ -3,7 +3,6 @@ "type": "module", "version": "1.13.3", "private": true, - "packageManager": "pnpm@10.32.1", "imports": { "#i18n": { "react-server": "./i18n-config/lib.server.ts", @@ -22,9 +21,6 @@ "and_uc >= 15.5", "and_qq >= 14.9" ], - "engines": { - "node": "^22.22.1" - }, "scripts": { "analyze": "next experimental-analyze", "analyze-component": "node ./scripts/analyze-component.js", @@ -58,258 +54,189 @@ "uglify-embed": "node ./bin/uglify-embed" }, "dependencies": { - "@amplitude/analytics-browser": "2.37.0", - "@amplitude/plugin-session-replay-browser": "1.27.1", - "@base-ui/react": "1.3.0", - "@emoji-mart/data": "1.2.1", - "@floating-ui/react": "0.27.19", - "@formatjs/intl-localematcher": "0.8.2", - "@headlessui/react": "2.2.9", - "@heroicons/react": "2.2.0", - "@lexical/code": "0.42.0", - "@lexical/link": "0.42.0", - "@lexical/list": "0.42.0", - "@lexical/react": "0.42.0", - "@lexical/selection": "0.42.0", - "@lexical/text": "0.42.0", - "@lexical/utils": "0.42.0", - "@monaco-editor/react": "4.7.0", - "@orpc/client": "1.13.9", - "@orpc/contract": "1.13.9", - "@orpc/openapi-client": "1.13.9", - "@orpc/tanstack-query": "1.13.9", - "@remixicon/react": "4.9.0", - "@sentry/react": "10.45.0", - "@streamdown/math": "1.0.2", - "@svgdotjs/svg.js": "3.2.5", - "@t3-oss/env-nextjs": "0.13.11", - "@tailwindcss/typography": "0.5.19", - "@tanstack/react-form": "1.28.5", - "@tanstack/react-query": "5.95.0", - "abcjs": "6.6.2", - "ahooks": "3.9.6", - "class-variance-authority": "0.7.1", - "clsx": "2.1.1", - "cmdk": "1.1.1", - "copy-to-clipboard": "3.3.3", - "cron-parser": "5.5.0", - "dayjs": "1.11.20", - "decimal.js": "10.6.0", - "dompurify": "3.3.3", - "echarts": "6.0.0", - "echarts-for-react": "3.0.6", - "elkjs": "0.11.1", - "embla-carousel-autoplay": "8.6.0", - "embla-carousel-react": "8.6.0", - "emoji-mart": "5.6.0", - "es-toolkit": "1.45.1", - "fast-deep-equal": "3.1.3", - "foxact": "0.3.0", - "html-entities": "2.6.0", - "html-to-image": "1.11.13", - "i18next": "25.10.4", - "i18next-resources-to-backend": "1.2.1", - "immer": "11.1.4", - "jotai": "2.18.1", - "js-audio-recorder": "1.0.7", - "js-cookie": "3.0.5", - "js-yaml": "4.1.1", - "jsonschema": "1.5.0", - "katex": "0.16.40", - "ky": "1.14.3", - "lamejs": "1.2.1", - "lexical": "0.42.0", - "mermaid": "11.13.0", - "mime": "4.1.0", - "mitt": "3.0.1", - "negotiator": "1.0.0", - "next": "16.2.1", - "next-themes": "0.4.6", - "nuqs": "2.8.9", - "pinyin-pro": "3.28.0", - "qrcode.react": "4.2.0", - "qs": "6.15.0", - "react": "19.2.4", - "react-18-input-autosize": "3.0.0", - "react-dom": "19.2.4", - "react-easy-crop": "5.5.6", - "react-hotkeys-hook": "5.2.4", - "react-i18next": "16.6.1", - "react-multi-email": "1.0.25", - "react-papaparse": "4.4.0", - "react-pdf-highlighter": "8.0.0-rc.0", - "react-sortablejs": "6.1.4", - "react-syntax-highlighter": "15.6.6", - "react-textarea-autosize": "8.5.9", - "react-window": "1.8.11", - "reactflow": "11.11.4", - "remark-breaks": "4.0.0", - "remark-directive": "4.0.0", - "scheduler": "0.27.0", - "sharp": "0.34.5", - "sortablejs": "1.15.7", - "std-semver": "1.0.8", - "streamdown": "2.5.0", - "string-ts": "2.3.1", - "tailwind-merge": "2.6.1", - "tldts": "7.0.27", - "unist-util-visit": "5.1.0", - "use-context-selector": "2.0.0", - "uuid": "13.0.0", - "zod": "4.3.6", - "zundo": "2.3.0", - "zustand": "5.0.12" + "@amplitude/analytics-browser": "catalog:", + "@amplitude/plugin-session-replay-browser": "catalog:", + "@base-ui/react": "catalog:", + "@emoji-mart/data": "catalog:", + "@floating-ui/react": "catalog:", + "@formatjs/intl-localematcher": "catalog:", + "@headlessui/react": "catalog:", + "@heroicons/react": "catalog:", + "@lexical/code": "catalog:", + "@lexical/link": "catalog:", + "@lexical/list": "catalog:", + "@lexical/react": "catalog:", + "@lexical/selection": "catalog:", + "@lexical/text": "catalog:", + "@lexical/utils": "catalog:", + "@monaco-editor/react": "catalog:", + "@orpc/client": "catalog:", + "@orpc/contract": "catalog:", + "@orpc/openapi-client": "catalog:", + "@orpc/tanstack-query": "catalog:", + "@remixicon/react": "catalog:", + "@sentry/react": "catalog:", + "@streamdown/math": "catalog:", + "@svgdotjs/svg.js": "catalog:", + "@t3-oss/env-nextjs": "catalog:", + "@tailwindcss/typography": "catalog:", + "@tanstack/react-form": "catalog:", + "@tanstack/react-query": "catalog:", + "abcjs": "catalog:", + "ahooks": "catalog:", + "class-variance-authority": "catalog:", + "clsx": "catalog:", + "cmdk": "catalog:", + "copy-to-clipboard": "catalog:", + "cron-parser": "catalog:", + "dayjs": "catalog:", + "decimal.js": "catalog:", + "dompurify": "catalog:", + "echarts": "catalog:", + "echarts-for-react": "catalog:", + "elkjs": "catalog:", + "embla-carousel-autoplay": "catalog:", + "embla-carousel-react": "catalog:", + "emoji-mart": "catalog:", + "es-toolkit": "catalog:", + "fast-deep-equal": "catalog:", + "foxact": "catalog:", + "html-entities": "catalog:", + "html-to-image": "catalog:", + "i18next": "catalog:", + "i18next-resources-to-backend": "catalog:", + "immer": "catalog:", + "jotai": "catalog:", + "js-audio-recorder": "catalog:", + "js-cookie": "catalog:", + "js-yaml": "catalog:", + "jsonschema": "catalog:", + "katex": "catalog:", + "ky": "catalog:", + "lamejs": "catalog:", + "lexical": "catalog:", + "mermaid": "catalog:", + "mime": "catalog:", + "mitt": "catalog:", + "negotiator": "catalog:", + "next": "catalog:", + "next-themes": "catalog:", + "nuqs": "catalog:", + "pinyin-pro": "catalog:", + "qrcode.react": "catalog:", + "qs": "catalog:", + "react": "catalog:", + "react-18-input-autosize": "catalog:", + "react-dom": "catalog:", + "react-easy-crop": "catalog:", + "react-hotkeys-hook": "catalog:", + "react-i18next": "catalog:", + "react-multi-email": "catalog:", + "react-papaparse": "catalog:", + "react-pdf-highlighter": "catalog:", + "react-sortablejs": "catalog:", + "react-syntax-highlighter": "catalog:", + "react-textarea-autosize": "catalog:", + "react-window": "catalog:", + "reactflow": "catalog:", + "remark-breaks": "catalog:", + "remark-directive": "catalog:", + "scheduler": "catalog:", + "sharp": "catalog:", + "sortablejs": "catalog:", + "std-semver": "catalog:", + "streamdown": "catalog:", + "string-ts": "catalog:", + "tailwind-merge": "catalog:", + "tldts": "catalog:", + "unist-util-visit": "catalog:", + "use-context-selector": "catalog:", + "uuid": "catalog:", + "zod": "catalog:", + "zundo": "catalog:", + "zustand": "catalog:" }, "devDependencies": { - "@antfu/eslint-config": "7.7.3", - "@chromatic-com/storybook": "5.0.2", - "@egoist/tailwindcss-icons": "1.9.2", - "@eslint-react/eslint-plugin": "3.0.0", - "@hono/node-server": "1.19.11", - "@iconify-json/heroicons": "1.2.3", - "@iconify-json/ri": "1.2.10", - "@mdx-js/loader": "3.1.1", - "@mdx-js/react": "3.1.1", - "@mdx-js/rollup": "3.1.1", - "@next/eslint-plugin-next": "16.2.1", - "@next/mdx": "16.2.1", - "@rgrove/parse-xml": "4.2.0", - "@storybook/addon-docs": "10.3.1", - "@storybook/addon-links": "10.3.1", - "@storybook/addon-onboarding": "10.3.1", - "@storybook/addon-themes": "10.3.1", - "@storybook/nextjs-vite": "10.3.1", - "@storybook/react": "10.3.1", - "@tanstack/eslint-plugin-query": "5.95.0", - "@tanstack/react-devtools": "0.10.0", - "@tanstack/react-form-devtools": "0.2.19", - "@tanstack/react-query-devtools": "5.95.0", - "@testing-library/dom": "10.4.1", - "@testing-library/jest-dom": "6.9.1", - "@testing-library/react": "16.3.2", - "@testing-library/user-event": "14.6.1", - "@tsslint/cli": "3.0.2", - "@tsslint/compat-eslint": "3.0.2", - "@tsslint/config": "3.0.2", - "@types/js-cookie": "3.0.6", - "@types/js-yaml": "4.0.9", - "@types/negotiator": "0.6.4", - "@types/node": "25.5.0", - "@types/postcss-js": "4.1.0", - "@types/qs": "6.15.0", - "@types/react": "19.2.14", - "@types/react-dom": "19.2.3", - "@types/react-syntax-highlighter": "15.5.13", - "@types/react-window": "1.8.8", - "@types/sortablejs": "1.15.9", - "@typescript-eslint/parser": "8.57.1", - "@typescript/native-preview": "7.0.0-dev.20260322.1", - "@vitejs/plugin-react": "6.0.1", - "@vitejs/plugin-rsc": "0.5.21", - "@vitest/coverage-v8": "4.1.0", - "agentation": "2.3.3", - "autoprefixer": "10.4.27", - "code-inspector-plugin": "1.4.5", - "eslint": "10.1.0", - "eslint-markdown": "0.6.0", - "eslint-plugin-better-tailwindcss": "4.3.2", - "eslint-plugin-hyoban": "0.14.1", - "eslint-plugin-markdown-preferences": "0.40.3", - "eslint-plugin-no-barrel-files": "1.2.2", - "eslint-plugin-react-hooks": "7.0.1", - "eslint-plugin-react-refresh": "0.5.2", - "eslint-plugin-sonarjs": "4.0.2", - "eslint-plugin-storybook": "10.3.1", - "happy-dom": "20.8.9", - "hono": "4.12.8", - "husky": "9.1.7", - "iconify-import-svg": "0.1.2", - "knip": "6.0.2", - "lint-staged": "16.4.0", - "postcss": "8.5.8", - "postcss-js": "5.1.0", - "react-server-dom-webpack": "19.2.4", - "sass": "1.98.0", - "storybook": "10.3.1", - "tailwindcss": "3.4.19", - "taze": "19.10.0", - "tsx": "4.21.0", - "typescript": "5.9.3", - "uglify-js": "3.19.3", - "vinext": "https://pkg.pr.new/vinext@b6a2cac", - "vite": "npm:@voidzero-dev/vite-plus-core@0.1.13", - "vite-plugin-inspect": "11.3.3", - "vite-plus": "0.1.13", - "vitest": "npm:@voidzero-dev/vite-plus-test@0.1.13", - "vitest-canvas-mock": "1.1.3" - }, - "pnpm": { - "overrides": { - "@lexical/code": "npm:lexical-code-no-prism@0.41.0", - "@monaco-editor/loader": "1.7.0", - "@nolyfill/safe-buffer": "npm:safe-buffer@^5.2.1", - "array-includes": "npm:@nolyfill/array-includes@^1.0.44", - "array.prototype.findlast": "npm:@nolyfill/array.prototype.findlast@^1.0.44", - "array.prototype.findlastindex": "npm:@nolyfill/array.prototype.findlastindex@^1.0.44", - "array.prototype.flat": "npm:@nolyfill/array.prototype.flat@^1.0.44", - "array.prototype.flatmap": "npm:@nolyfill/array.prototype.flatmap@^1.0.44", - "array.prototype.tosorted": "npm:@nolyfill/array.prototype.tosorted@^1.0.44", - "assert": "npm:@nolyfill/assert@^1.0.26", - "brace-expansion@<2.0.2": "2.0.2", - "canvas": "^3.2.2", - "devalue@<5.3.2": "5.3.2", - "dompurify@>=3.1.3 <=3.3.1": "3.3.2", - "es-iterator-helpers": "npm:@nolyfill/es-iterator-helpers@^1.0.21", - "esbuild@<0.27.2": "0.27.2", - "glob@>=10.2.0 <10.5.0": "11.1.0", - "hasown": "npm:@nolyfill/hasown@^1.0.44", - "is-arguments": "npm:@nolyfill/is-arguments@^1.0.44", - "is-core-module": "npm:@nolyfill/is-core-module@^1.0.39", - "is-generator-function": "npm:@nolyfill/is-generator-function@^1.0.44", - "is-typed-array": "npm:@nolyfill/is-typed-array@^1.0.44", - "isarray": "npm:@nolyfill/isarray@^1.0.44", - "object.assign": "npm:@nolyfill/object.assign@^1.0.44", - "object.entries": "npm:@nolyfill/object.entries@^1.0.44", - "object.fromentries": "npm:@nolyfill/object.fromentries@^1.0.44", - "object.groupby": "npm:@nolyfill/object.groupby@^1.0.44", - "object.values": "npm:@nolyfill/object.values@^1.0.44", - "pbkdf2": "~3.1.5", - "pbkdf2@<3.1.3": "3.1.3", - "picomatch@<2.3.2": "2.3.2", - "picomatch@>=4.0.0 <4.0.4": "4.0.4", - "prismjs": "~1.30", - "prismjs@<1.30.0": "1.30.0", - "rollup@>=4.0.0 <4.59.0": "4.59.0", - "safe-buffer": "^5.2.1", - "safe-regex-test": "npm:@nolyfill/safe-regex-test@^1.0.44", - "safer-buffer": "npm:@nolyfill/safer-buffer@^1.0.44", - "side-channel": "npm:@nolyfill/side-channel@^1.0.44", - "smol-toml@<1.6.1": "1.6.1", - "solid-js": "1.9.11", - "string-width": "~8.2.0", - "string.prototype.includes": "npm:@nolyfill/string.prototype.includes@^1.0.44", - "string.prototype.matchall": "npm:@nolyfill/string.prototype.matchall@^1.0.44", - "string.prototype.repeat": "npm:@nolyfill/string.prototype.repeat@^1.0.44", - "string.prototype.trimend": "npm:@nolyfill/string.prototype.trimend@^1.0.44", - "svgo@>=3.0.0 <3.3.3": "3.3.3", - "tar@<=7.5.10": "7.5.11", - "typed-array-buffer": "npm:@nolyfill/typed-array-buffer@^1.0.44", - "undici@>=7.0.0 <7.24.0": "7.24.0", - "vite": "npm:@voidzero-dev/vite-plus-core@0.1.13", - "vitest": "npm:@voidzero-dev/vite-plus-test@0.1.13", - "which-typed-array": "npm:@nolyfill/which-typed-array@^1.0.44", - "yaml@>=2.0.0 <2.8.3": "2.8.3", - "yauzl@<3.2.1": "3.2.1" - }, - "ignoredBuiltDependencies": [ - "canvas", - "core-js-pure" - ], - "onlyBuiltDependencies": [ - "@parcel/watcher", - "esbuild", - "sharp" - ] + "@antfu/eslint-config": "catalog:", + "@chromatic-com/storybook": "catalog:", + "@egoist/tailwindcss-icons": "catalog:", + "@eslint-react/eslint-plugin": "catalog:", + "@hono/node-server": "catalog:", + "@iconify-json/heroicons": "catalog:", + "@iconify-json/ri": "catalog:", + "@mdx-js/loader": "catalog:", + "@mdx-js/react": "catalog:", + "@mdx-js/rollup": "catalog:", + "@next/eslint-plugin-next": "catalog:", + "@next/mdx": "catalog:", + "@rgrove/parse-xml": "catalog:", + "@storybook/addon-docs": "catalog:", + "@storybook/addon-links": "catalog:", + "@storybook/addon-onboarding": "catalog:", + "@storybook/addon-themes": "catalog:", + "@storybook/nextjs-vite": "catalog:", + "@storybook/react": "catalog:", + "@tanstack/eslint-plugin-query": "catalog:", + "@tanstack/react-devtools": "catalog:", + "@tanstack/react-form-devtools": "catalog:", + "@tanstack/react-query-devtools": "catalog:", + "@testing-library/dom": "catalog:", + "@testing-library/jest-dom": "catalog:", + "@testing-library/react": "catalog:", + "@testing-library/user-event": "catalog:", + "@tsslint/cli": "catalog:", + "@tsslint/compat-eslint": "catalog:", + "@tsslint/config": "catalog:", + "@types/js-cookie": "catalog:", + "@types/js-yaml": "catalog:", + "@types/negotiator": "catalog:", + "@types/node": "catalog:", + "@types/postcss-js": "catalog:", + "@types/qs": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@types/react-syntax-highlighter": "catalog:", + "@types/react-window": "catalog:", + "@types/sortablejs": "catalog:", + "@typescript-eslint/parser": "catalog:", + "@typescript/native-preview": "catalog:", + "@vitejs/plugin-react": "catalog:", + "@vitejs/plugin-rsc": "catalog:", + "@vitest/coverage-v8": "catalog:", + "agentation": "catalog:", + "autoprefixer": "catalog:", + "code-inspector-plugin": "catalog:", + "eslint": "catalog:", + "eslint-markdown": "catalog:", + "eslint-plugin-better-tailwindcss": "catalog:", + "eslint-plugin-hyoban": "catalog:", + "eslint-plugin-markdown-preferences": "catalog:", + "eslint-plugin-no-barrel-files": "catalog:", + "eslint-plugin-react-hooks": "catalog:", + "eslint-plugin-react-refresh": "catalog:", + "eslint-plugin-sonarjs": "catalog:", + "eslint-plugin-storybook": "catalog:", + "happy-dom": "catalog:", + "hono": "catalog:", + "husky": "catalog:", + "iconify-import-svg": "catalog:", + "knip": "catalog:", + "lint-staged": "catalog:", + "postcss": "catalog:", + "postcss-js": "catalog:", + "react-server-dom-webpack": "catalog:", + "sass": "catalog:", + "storybook": "catalog:", + "tailwindcss": "catalog:", + "tsx": "catalog:", + "typescript": "catalog:", + "uglify-js": "catalog:", + "vinext": "catalog:", + "vite": "catalog:", + "vite-plugin-inspect": "catalog:", + "vite-plus": "catalog:", + "vitest": "catalog:", + "vitest-canvas-mock": "catalog:" }, "lint-staged": { "*": "eslint --fix --pass-on-unpruned-suppressions" diff --git a/web/scripts/copy-and-start.mjs b/web/scripts/copy-and-start.mjs index 9525c6b45f..932a88a32d 100644 --- a/web/scripts/copy-and-start.mjs +++ b/web/scripts/copy-and-start.mjs @@ -8,21 +8,6 @@ import { spawn } from 'node:child_process' import { cp, mkdir, stat } from 'node:fs/promises' import path from 'node:path' -// Configuration for directories to copy -const DIRS_TO_COPY = [ - { - src: path.join('.next', 'static'), - dest: path.join('.next', 'standalone', '.next', 'static'), - }, - { - src: 'public', - dest: path.join('.next', 'standalone', 'public'), - }, -] - -// Path to the server script -const SERVER_SCRIPT_PATH = path.join('.next', 'standalone', 'server.js') - // Function to check if a path exists const pathExists = async (path) => { try { @@ -40,6 +25,23 @@ const pathExists = async (path) => { } } +const STANDALONE_ROOT_CANDIDATES = [ + path.join('.next', 'standalone', 'web'), + path.join('.next', 'standalone'), +] + +const getStandaloneRoot = async () => { + for (const standaloneRoot of STANDALONE_ROOT_CANDIDATES) { + const serverScriptPath = path.join(standaloneRoot, 'server.js') + if (await pathExists(serverScriptPath)) + return standaloneRoot + } + + throw new Error( + `Unable to find Next standalone server entry. Checked: ${STANDALONE_ROOT_CANDIDATES.join(', ')}`, + ) +} + // Function to recursively copy directories const copyDir = async (src, dest) => { console.debug(`Copying directory from ${src} to ${dest}`) @@ -48,9 +50,20 @@ const copyDir = async (src, dest) => { } // Process each directory copy operation -const copyAllDirs = async () => { +const copyAllDirs = async (standaloneRoot) => { + const dirsToCopy = [ + { + src: path.join('.next', 'static'), + dest: path.join(standaloneRoot, '.next', 'static'), + }, + { + src: 'public', + dest: path.join(standaloneRoot, 'public'), + }, + ] + console.debug('Starting directory copy operations') - for (const { src, dest } of DIRS_TO_COPY) { + for (const { src, dest } of dirsToCopy) { try { // Instead of pre-creating destination directory, we ensure parent directory exists const destParent = path.dirname(dest) @@ -75,19 +88,22 @@ const copyAllDirs = async () => { // Run copy operations and start server const main = async () => { console.debug('Starting copy-and-start script') - await copyAllDirs() + const standaloneRoot = await getStandaloneRoot() + const serverScriptPath = path.join(standaloneRoot, 'server.js') + + await copyAllDirs(standaloneRoot) // Start server const port = process.env.npm_config_port || process.env.PORT || '3000' const host = process.env.npm_config_host || process.env.HOSTNAME || '0.0.0.0' console.info(`Starting server on ${host}:${port}`) - console.debug(`Server script path: ${SERVER_SCRIPT_PATH}`) + console.debug(`Server script path: ${serverScriptPath}`) console.debug(`Environment variables - PORT: ${port}, HOSTNAME: ${host}`) const server = spawn( process.execPath, - [SERVER_SCRIPT_PATH], + [serverScriptPath], { env: { ...process.env, diff --git a/web/service/knowledge/use-document.ts b/web/service/knowledge/use-document.ts index 4eb2b7d282..6e48d7b6f4 100644 --- a/web/service/knowledge/use-document.ts +++ b/web/service/knowledge/use-document.ts @@ -133,15 +133,19 @@ export const useSyncWebsite = () => { } const useDocumentDetailKey = [NAME_SPACE, 'documentDetail', 'withoutMetaData'] +type DocumentDetailRefetchInterval = UseQueryOptions['refetchInterval'] + export const useDocumentDetail = (payload: { datasetId: string documentId: string params: { metadata: MetadataType } + refetchInterval?: DocumentDetailRefetchInterval }) => { - const { datasetId, documentId, params } = payload + const { datasetId, documentId, params, refetchInterval } = payload return useQuery({ queryKey: [...useDocumentDetailKey, 'withoutMetaData', datasetId, documentId, params], queryFn: () => get(`/datasets/${datasetId}/documents/${documentId}`, { params }), + refetchInterval, }) } diff --git a/web/vitest.setup.ts b/web/vitest.setup.ts index ac26ac5d25..b17a59bab6 100644 --- a/web/vitest.setup.ts +++ b/web/vitest.setup.ts @@ -1,8 +1,11 @@ +import * as jestDomMatchers from '@testing-library/jest-dom/matchers' import { act, cleanup } from '@testing-library/react' import * as React from 'react' import '@testing-library/jest-dom/vitest' import 'vitest-canvas-mock' +expect.extend(jestDomMatchers) + // Suppress act() warnings from @headlessui/react internal Transition component // These warnings are caused by Headless UI's internal async state updates, not our code const originalConsoleError = console.error
NAMEVALUE{t('env.export.name', { ns: 'workflow' })}{t('env.export.value', { ns: 'workflow' })}