diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 9591415728..0d6900b005 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -112,5 +112,9 @@
# Tests
/apps/api/src/__tests__/snips/* @mogery
+# Branding
+**/branding* @abimaelmartell
+**/branding-script* @abimaelmartell
+
# Examples
/examples/* @ericciarla @nickscamara
diff --git a/.github/archive/js-sdk.yml b/.github/archive/js-sdk.yml
index a468ee6378..e873d8ee60 100644
--- a/.github/archive/js-sdk.yml
+++ b/.github/archive/js-sdk.yml
@@ -21,7 +21,7 @@ env:
jobs:
build:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-4vcpu-ubuntu-2404
services:
redis:
image: redis
diff --git a/.github/archive/publish-rust-sdk.yml b/.github/archive/publish-rust-sdk.yml
index 9856bd77e5..a3ed6c1b86 100644
--- a/.github/archive/publish-rust-sdk.yml
+++ b/.github/archive/publish-rust-sdk.yml
@@ -7,7 +7,7 @@ env:
jobs:
build-and-publish:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- name: Checkout repository
diff --git a/.github/archive/python-sdk.yml b/.github/archive/python-sdk.yml
index fbafb9709d..d1f716de3b 100644
--- a/.github/archive/python-sdk.yml
+++ b/.github/archive/python-sdk.yml
@@ -21,7 +21,7 @@ env:
jobs:
build:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-4vcpu-ubuntu-2404
strategy:
matrix:
python-version: ["3.10"]
diff --git a/.github/archive/rust-sdk.yml b/.github/archive/rust-sdk.yml
index 9ec13fe5a3..a4f9b2d9b0 100644
--- a/.github/archive/rust-sdk.yml
+++ b/.github/archive/rust-sdk.yml
@@ -22,7 +22,7 @@ env:
jobs:
build:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-4vcpu-ubuntu-2404
services:
redis:
image: redis
diff --git a/.github/scripts/check_version_has_incremented.py b/.github/scripts/check_version_has_incremented.py
index 251e955275..34c56d8387 100644
--- a/.github/scripts/check_version_has_incremented.py
+++ b/.github/scripts/check_version_has_incremented.py
@@ -8,11 +8,16 @@
Published version: 0.0.21
true
-python .github/scripts/check_version_has_incremented.py python ./apps/python-sdk/firecrawl firecrawl-py
+python .github/scripts/check_version_has_incremented.py python ./apps/python-sdk/firecrawl firecrawl-py
Local version: 0.0.11
Published version: 0.0.11
false
+python .github/scripts/check_version_has_incremented.py java ./apps/java-sdk com.firecrawl:firecrawl-java
+Local version: 1.0.0
+Published version: 0.0.0 (0.0.0 means not yet published on Maven Central)
+true
+
"""
import json
import os
@@ -53,6 +58,30 @@ def get_npm_version(package_name: str) -> str:
version = response.json()['version']
return version.strip()
+def get_gradle_version(file_path: str) -> str:
+ """Extract version string from build.gradle.kts."""
+ build_file = Path(file_path).read_text()
+ version_match = re.search(r'^version\s*=\s*["\']([^"\']*)["\']', build_file, re.M)
+ if version_match:
+ return version_match.group(1).strip()
+ raise RuntimeError("Unable to find version string in build.gradle.kts.")
+
+def get_maven_central_version(package_name: str) -> str:
+ """Get latest version of Java package from Maven Central. package_name should be groupId:artifactId."""
+ group_id, artifact_id = package_name.split(":")
+ group_path = group_id.replace(".", "/")
+ url = f"https://repo1.maven.org/maven2/{group_path}/{artifact_id}/maven-metadata.xml"
+ response = requests.get(url)
+ if response.status_code == 404:
+ return "0.0.0"
+ response.raise_for_status()
+ version_match = re.search(r"(.*?)", response.text)
+ if not version_match:
+ version_match = re.search(r"(.*?)", response.text)
+ if version_match:
+ return version_match.group(1).strip()
+ return "0.0.0"
+
# def get_rust_version(file_path: str) -> str:
# """Extract version string from Cargo.toml."""
# cargo_toml = toml.load(file_path)
@@ -87,6 +116,11 @@ def is_version_incremented(local_version: str, published_version: str) -> bool:
current_version = get_js_version(os.path.join(package_path, 'package.json'))
# Get published version from npm
published_version = get_npm_version(package_name)
+ elif package_type == "java":
+ # Get current version from build.gradle.kts
+ current_version = get_gradle_version(os.path.join(package_path, 'build.gradle.kts'))
+ # Get published version from Maven Central
+ published_version = get_maven_central_version(package_name)
# if package_type == "rust":
# # Get current version from Cargo.toml
# current_version = get_rust_version(os.path.join(package_path, 'Cargo.toml'))
@@ -94,7 +128,7 @@ def is_version_incremented(local_version: str, published_version: str) -> bool:
# published_version = get_crates_version(package_name)
else:
- raise ValueError("Invalid package type. Use 'python' or 'js'.")
+ raise ValueError("Invalid package type. Use 'python', 'js', or 'java'.")
# Print versions for debugging
# print(f"Local version: {current_version}")
diff --git a/.github/workflows/deploy-go-service.yaml b/.github/workflows/deploy-go-service.yaml
index 3c2b8c7291..835d9918f0 100644
--- a/.github/workflows/deploy-go-service.yaml
+++ b/.github/workflows/deploy-go-service.yaml
@@ -14,7 +14,7 @@ on:
jobs:
push-app-image:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-4vcpu-ubuntu-2404
defaults:
run:
working-directory: "./apps/go-html-to-md-service"
@@ -22,8 +22,8 @@ jobs:
- name: "Checkout GitHub Action"
uses: actions/checkout@main
- - name: "Set up Docker Buildx"
- uses: docker/setup-buildx-action@v3
+ - name: Setup Blacksmith Builder
+ uses: useblacksmith/setup-docker-builder@v1
- name: "Login to GitHub Container Registry"
uses: docker/login-action@v3
@@ -33,10 +33,8 @@ jobs:
password: ${{secrets.GITHUB_TOKEN}}
- name: "Build and Push Image"
- uses: docker/build-push-action@v6
+ uses: useblacksmith/build-push-action@v2
with:
context: ./apps/go-html-to-md-service
push: true
tags: ghcr.io/firecrawl/go-html-to-md-service:latest
- cache-from: type=registry,ref=ghcr.io/firecrawl/go-html-to-md-service:buildcache
- cache-to: type=registry,ref=ghcr.io/firecrawl/go-html-to-md-service:buildcache,mode=max
diff --git a/.github/workflows/deploy-image-staging.yml b/.github/workflows/deploy-image-staging.yml
index 86de330b6f..1871eec2f2 100644
--- a/.github/workflows/deploy-image-staging.yml
+++ b/.github/workflows/deploy-image-staging.yml
@@ -8,7 +8,7 @@ on:
jobs:
push-app-image:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-4vcpu-ubuntu-2404
defaults:
run:
working-directory: './apps/api'
@@ -26,4 +26,4 @@ jobs:
- name: 'Build Inventory Image'
run: |
docker build . --tag ghcr.io/firecrawl/firecrawl-staging:latest
- docker push ghcr.io/firecrawl/firecrawl-staging:latest
\ No newline at end of file
+ docker push ghcr.io/firecrawl/firecrawl-staging:latest
diff --git a/.github/workflows/deploy-image.yml b/.github/workflows/deploy-image.yml
index f35efb7de0..4fa49674aa 100644
--- a/.github/workflows/deploy-image.yml
+++ b/.github/workflows/deploy-image.yml
@@ -1,41 +1,81 @@
name: Deploy Images to GHCR
-env:
- DOTNET_VERSION: '6.0.x'
-
on:
push:
branches:
- main
paths:
- apps/api/**
+ - .github/workflows/deploy-image.yml
workflow_dispatch:
jobs:
- push-app-image:
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: './apps/api'
- steps:
- - name: 'Checkout GitHub Action'
- uses: actions/checkout@main
-
- - name: 'Set up Docker Buildx'
- uses: docker/setup-buildx-action@v3
-
- - name: 'Login to GitHub Container Registry'
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{github.actor}}
- password: ${{secrets.GITHUB_TOKEN}}
-
- - name: 'Build and Push Image'
- uses: docker/build-push-action@v6
- with:
- context: ./apps/api
- push: true
- tags: ghcr.io/firecrawl/firecrawl:latest
- cache-from: type=registry,ref=ghcr.io/firecrawl/firecrawl:buildcache
- cache-to: type=registry,ref=ghcr.io/firecrawl/firecrawl:buildcache,mode=max
\ No newline at end of file
+ build:
+ runs-on: ${{ matrix.runner }}
+ strategy:
+ matrix:
+ include:
+ - platform: linux/amd64
+ runner: blacksmith-4vcpu-ubuntu-2404
+ - platform: linux/arm64
+ runner: blacksmith-4vcpu-ubuntu-2404-arm
+ defaults:
+ run:
+ working-directory: './apps/api'
+ steps:
+ - name: 'Checkout GitHub Action'
+ uses: actions/checkout@main
+
+ - name: Setup Blacksmith Builder
+ uses: useblacksmith/setup-docker-builder@v1
+
+ - name: 'Login to GitHub Container Registry'
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{github.actor}}
+ password: ${{secrets.GITHUB_TOKEN}}
+
+ - name: Lowercase Repo Owner
+ run: |
+ echo "REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
+ env:
+ GITHUB_REPOSITORY_OWNER: '${{ github.repository_owner }}'
+
+ - name: Extract platform suffix
+ run: |
+ platform=${{ matrix.platform }}
+ echo "PLATFORM_SUFFIX=${platform//\//-}" >> $GITHUB_ENV
+
+ - name: 'Build and Push Image'
+ uses: useblacksmith/build-push-action@v2
+ with:
+ context: ./apps/api
+ push: true
+ tags: ghcr.io/${{ env.REPO_OWNER }}/firecrawl:${{ env.PLATFORM_SUFFIX }}
+ platforms: ${{ matrix.platform }}
+ provenance: false
+
+ manifest:
+ runs-on: blacksmith-2vcpu-ubuntu-2404
+ needs: build
+ steps:
+ - name: 'Login to GitHub Container Registry'
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{github.actor}}
+ password: ${{secrets.GITHUB_TOKEN}}
+
+ - name: Lowercase Repo Owner
+ run: |
+ echo "REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
+ env:
+ GITHUB_REPOSITORY_OWNER: '${{ github.repository_owner }}'
+
+ - name: 'Create and Push Multi-Arch Manifest'
+ run: |
+ docker manifest create ghcr.io/${{ env.REPO_OWNER }}/firecrawl:latest \
+ ghcr.io/${{ env.REPO_OWNER }}/firecrawl:linux-amd64 \
+ ghcr.io/${{ env.REPO_OWNER }}/firecrawl:linux-arm64
+ docker manifest push ghcr.io/${{ env.REPO_OWNER }}/firecrawl:latest
diff --git a/.github/workflows/deploy-nuq-postgres.yml b/.github/workflows/deploy-nuq-postgres.yml
index 200ea814de..6f33e94129 100644
--- a/.github/workflows/deploy-nuq-postgres.yml
+++ b/.github/workflows/deploy-nuq-postgres.yml
@@ -10,7 +10,7 @@ on:
jobs:
push-app-image:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-4vcpu-ubuntu-2404
defaults:
run:
working-directory: './apps/nuq-postgres'
diff --git a/.github/workflows/deploy-playwright.yml b/.github/workflows/deploy-playwright.yml
index 00cb5866f8..fc00428f55 100644
--- a/.github/workflows/deploy-playwright.yml
+++ b/.github/workflows/deploy-playwright.yml
@@ -1,34 +1,81 @@
name: Deploy Playwright to GHCR
-env:
- DOTNET_VERSION: '6.0.x'
-
on:
push:
branches:
- main
paths:
- apps/playwright-service-ts/**
+ - .github/workflows/deploy-playwright.yml
workflow_dispatch:
jobs:
- push-app-image:
- runs-on: ubuntu-latest
- defaults:
- run:
- working-directory: './apps/playwright-service-ts'
- steps:
- - name: 'Checkout GitHub Action'
- uses: actions/checkout@main
-
- - name: 'Login to GitHub Container Registry'
- uses: docker/login-action@v3
- with:
- registry: ghcr.io
- username: ${{github.actor}}
- password: ${{secrets.GITHUB_TOKEN}}
-
- - name: 'Build Inventory Image'
- run: |
- docker build . --tag ghcr.io/firecrawl/playwright-service:latest
- docker push ghcr.io/firecrawl/playwright-service:latest
\ No newline at end of file
+ build:
+ runs-on: ${{ matrix.runner }}
+ strategy:
+ matrix:
+ include:
+ - platform: linux/amd64
+ runner: blacksmith-4vcpu-ubuntu-2404
+ - platform: linux/arm64
+ runner: blacksmith-4vcpu-ubuntu-2404-arm
+ defaults:
+ run:
+ working-directory: './apps/playwright-service-ts'
+ steps:
+ - name: 'Checkout GitHub Action'
+ uses: actions/checkout@main
+
+ - name: Setup Blacksmith Builder
+ uses: useblacksmith/setup-docker-builder@v1
+
+ - name: 'Login to GitHub Container Registry'
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{github.actor}}
+ password: ${{secrets.GITHUB_TOKEN}}
+
+ - name: Lowercase Repo Owner
+ run: |
+ echo "REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
+ env:
+ GITHUB_REPOSITORY_OWNER: '${{ github.repository_owner }}'
+
+ - name: Extract platform suffix
+ run: |
+ platform=${{ matrix.platform }}
+ echo "PLATFORM_SUFFIX=${platform//\//-}" >> $GITHUB_ENV
+
+ - name: 'Build and Push Image'
+ uses: useblacksmith/build-push-action@v2
+ with:
+ context: ./apps/playwright-service-ts
+ push: true
+ tags: ghcr.io/${{ env.REPO_OWNER }}/playwright-service:${{ env.PLATFORM_SUFFIX }}
+ platforms: ${{ matrix.platform }}
+ provenance: false
+
+ manifest:
+ runs-on: blacksmith-2vcpu-ubuntu-2404
+ needs: build
+ steps:
+ - name: 'Login to GitHub Container Registry'
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{github.actor}}
+ password: ${{secrets.GITHUB_TOKEN}}
+
+ - name: Lowercase Repo Owner
+ run: |
+ echo "REPO_OWNER=${GITHUB_REPOSITORY_OWNER,,}" >>${GITHUB_ENV}
+ env:
+ GITHUB_REPOSITORY_OWNER: '${{ github.repository_owner }}'
+
+ - name: 'Create and Push Multi-Arch Manifest'
+ run: |
+ docker manifest create ghcr.io/${{ env.REPO_OWNER }}/playwright-service:latest \
+ ghcr.io/${{ env.REPO_OWNER }}/playwright-service:linux-amd64 \
+ ghcr.io/${{ env.REPO_OWNER }}/playwright-service:linux-arm64
+ docker manifest push ghcr.io/${{ env.REPO_OWNER }}/playwright-service:latest
diff --git a/.github/workflows/deploy-redis.yml b/.github/workflows/deploy-redis.yml
index 21c0da3e22..72a094249b 100644
--- a/.github/workflows/deploy-redis.yml
+++ b/.github/workflows/deploy-redis.yml
@@ -13,7 +13,7 @@ on:
jobs:
push-app-image:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-4vcpu-ubuntu-2404
defaults:
run:
working-directory: './apps/redis'
diff --git a/.github/workflows/eval-prod.yml b/.github/workflows/eval-prod.yml
index 48a31de5db..365f9dc7a5 100644
--- a/.github/workflows/eval-prod.yml
+++ b/.github/workflows/eval-prod.yml
@@ -16,7 +16,7 @@ on:
jobs:
run-eval-benchmark-prod:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-2vcpu-ubuntu-2404
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
steps:
- name: Checkout repository
diff --git a/.github/workflows/ghcr-clean.yml b/.github/workflows/ghcr-clean.yml
index 2e93ff8643..49b41287a5 100644
--- a/.github/workflows/ghcr-clean.yml
+++ b/.github/workflows/ghcr-clean.yml
@@ -6,7 +6,7 @@ on:
jobs:
delete-untagged-images:
name: Delete Untagged Images
- runs-on: ubuntu-latest
+ runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- uses: bots-house/ghcr-delete-image-action@v1.1.0
with:
diff --git a/.github/workflows/npm-audit.yml b/.github/workflows/npm-audit.yml
index ab66d0b993..4e93c0083a 100644
--- a/.github/workflows/npm-audit.yml
+++ b/.github/workflows/npm-audit.yml
@@ -7,7 +7,7 @@ on:
jobs:
audit:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v5
- name: Install pnpm
@@ -15,63 +15,97 @@ jobs:
with:
version: 10
+ - name: Create audit output directory
+ run: mkdir -p /tmp/audit-outputs
+
- name: Audit API Packages
id: audit-api
continue-on-error: true
run: |
- pnpm dlx audit-ci@^7 --directory apps/api --config apps/api/audit-ci.jsonc
+ set -o pipefail
+ pnpm dlx audit-ci@^7 --directory apps/api --config apps/api/audit-ci.jsonc 2>&1 | tee /tmp/audit-outputs/api.txt
- name: Audit Playwright Service Packages
id: audit-playwright-service
continue-on-error: true
run: |
- pnpm dlx audit-ci@^7 --directory apps/playwright-service-ts --config apps/playwright-service-ts/audit-ci.jsonc
+ set -o pipefail
+ pnpm dlx audit-ci@^7 --directory apps/playwright-service-ts --config apps/playwright-service-ts/audit-ci.jsonc 2>&1 | tee /tmp/audit-outputs/playwright-service.txt
- name: Audit JavaScript SDK Packages
id: audit-js-sdk
continue-on-error: true
run: |
- pnpm dlx audit-ci@^7 --directory apps/js-sdk --config apps/js-sdk/audit-ci.jsonc
+ set -o pipefail
+ pnpm dlx audit-ci@^7 --directory apps/js-sdk --config apps/js-sdk/audit-ci.jsonc 2>&1 | tee /tmp/audit-outputs/js-sdk.txt
- name: Audit JavaScript SDK Firecrawl Packages
id: audit-js-sdk-firecrawl
continue-on-error: true
run: |
- pnpm dlx audit-ci@^7 --directory apps/js-sdk/firecrawl --config apps/js-sdk/firecrawl/audit-ci.jsonc
+ set -o pipefail
+ pnpm dlx audit-ci@^7 --directory apps/js-sdk/firecrawl --config apps/js-sdk/firecrawl/audit-ci.jsonc 2>&1 | tee /tmp/audit-outputs/js-sdk-firecrawl.txt
- name: Audit Test Suite Packages
id: audit-test-suite
continue-on-error: true
run: |
- pnpm dlx audit-ci@^7 --directory apps/test-suite --config apps/test-suite/audit-ci.jsonc
+ set -o pipefail
+ pnpm dlx audit-ci@^7 --directory apps/test-suite --config apps/test-suite/audit-ci.jsonc 2>&1 | tee /tmp/audit-outputs/test-suite.txt
- name: Audit Ingestion UI Packages
id: audit-ingestion-ui
continue-on-error: true
run: |
- pnpm dlx audit-ci@^7 --directory apps/ui/ingestion-ui --config apps/ui/ingestion-ui/audit-ci.jsonc
+ set -o pipefail
+ pnpm dlx audit-ci@^7 --directory apps/ui/ingestion-ui --config apps/ui/ingestion-ui/audit-ci.jsonc 2>&1 | tee /tmp/audit-outputs/ingestion-ui.txt
- name: Audit Test Site Packages
id: audit-test-site
continue-on-error: true
run: |
- pnpm dlx audit-ci@^7 --directory apps/test-site --config apps/test-site/audit-ci.jsonc
+ set -o pipefail
+ pnpm dlx audit-ci@^7 --directory apps/test-site --config apps/test-site/audit-ci.jsonc 2>&1 | tee /tmp/audit-outputs/test-site.txt
- name: Report audit failures
if: always()
run: |
- FAILED_AUDITS=()
- [ "${{ steps.audit-api.outcome }}" == "failure" ] && FAILED_AUDITS+=("API")
- [ "${{ steps.audit-playwright-service.outcome }}" == "failure" ] && FAILED_AUDITS+=("Playwright Service")
- [ "${{ steps.audit-js-sdk.outcome }}" == "failure" ] && FAILED_AUDITS+=("JavaScript SDK")
- [ "${{ steps.audit-js-sdk-firecrawl.outcome }}" == "failure" ] && FAILED_AUDITS+=("JavaScript SDK Firecrawl")
- [ "${{ steps.audit-test-suite.outcome }}" == "failure" ] && FAILED_AUDITS+=("Test Suite")
- [ "${{ steps.audit-ingestion-ui.outcome }}" == "failure" ] && FAILED_AUDITS+=("Ingestion UI")
- [ "${{ steps.audit-test-site.outcome }}" == "failure" ] && FAILED_AUDITS+=("Test Site")
-
- if [ ${#FAILED_AUDITS[@]} -gt 0 ]; then
- echo "❌ The following audits failed:"
- printf ' - %s\n' "${FAILED_AUDITS[@]}"
+ declare -A AUDIT_FILES=(
+ ["API"]="api.txt"
+ ["Playwright Service"]="playwright-service.txt"
+ ["JavaScript SDK"]="js-sdk.txt"
+ ["JavaScript SDK Firecrawl"]="js-sdk-firecrawl.txt"
+ ["Test Suite"]="test-suite.txt"
+ ["Ingestion UI"]="ingestion-ui.txt"
+ ["Test Site"]="test-site.txt"
+ )
+
+ declare -A AUDIT_OUTCOMES=(
+ ["API"]="${{ steps.audit-api.outcome }}"
+ ["Playwright Service"]="${{ steps.audit-playwright-service.outcome }}"
+ ["JavaScript SDK"]="${{ steps.audit-js-sdk.outcome }}"
+ ["JavaScript SDK Firecrawl"]="${{ steps.audit-js-sdk-firecrawl.outcome }}"
+ ["Test Suite"]="${{ steps.audit-test-suite.outcome }}"
+ ["Ingestion UI"]="${{ steps.audit-ingestion-ui.outcome }}"
+ ["Test Site"]="${{ steps.audit-test-site.outcome }}"
+ )
+
+ FAILED=false
+ for name in "API" "Playwright Service" "JavaScript SDK" "JavaScript SDK Firecrawl" "Test Suite" "Ingestion UI" "Test Site"; do
+ if [ "${AUDIT_OUTCOMES[$name]}" == "failure" ]; then
+ FAILED=true
+ echo ""
+ echo "=========================================="
+ echo "❌ $name audit failed"
+ echo "=========================================="
+ if [ -f "/tmp/audit-outputs/${AUDIT_FILES[$name]}" ]; then
+ # Extract only the summary (from "Found vulnerable advisory paths:" to end)
+ sed -n '/Found vulnerable advisory paths:/,$p' "/tmp/audit-outputs/${AUDIT_FILES[$name]}" | sed 's/\x1b\[[0-9;]*m//g'
+ fi
+ fi
+ done
+
+ if [ "$FAILED" == "true" ]; then
exit 1
else
echo "✅ All audits passed"
diff --git a/.github/workflows/publish-java-sdk.yml b/.github/workflows/publish-java-sdk.yml
new file mode 100644
index 0000000000..af9819a81b
--- /dev/null
+++ b/.github/workflows/publish-java-sdk.yml
@@ -0,0 +1,69 @@
+name: Publish Java SDK
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - main
+ paths:
+ - 'apps/java-sdk/**'
+
+jobs:
+ publish:
+ name: Publish to Maven Central
+ runs-on: blacksmith-2vcpu-ubuntu-2404
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v5
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.x'
+
+ - name: Install version check dependencies
+ run: pip install requests packaging
+
+ - name: Run version check script
+ id: version_check
+ run: |
+ VERSION_INCREMENTED=$(python .github/scripts/check_version_has_incremented.py java ./apps/java-sdk com.firecrawl:firecrawl-java)
+ echo "VERSION_INCREMENTED=$VERSION_INCREMENTED" >> $GITHUB_ENV
+
+ - name: Set up JDK 11
+ if: ${{ env.VERSION_INCREMENTED == 'true' }}
+ uses: actions/setup-java@v4
+ with:
+ distribution: temurin
+ java-version: '11'
+
+ - name: Cache Gradle packages
+ if: ${{ env.VERSION_INCREMENTED == 'true' }}
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('apps/java-sdk/**/*.gradle.kts', 'apps/java-sdk/gradle/wrapper/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+
+ - name: Grant execute permission for gradlew
+ if: ${{ env.VERSION_INCREMENTED == 'true' }}
+ working-directory: ./apps/java-sdk
+ run: chmod +x gradlew
+
+ - name: Build
+ if: ${{ env.VERSION_INCREMENTED == 'true' }}
+ working-directory: ./apps/java-sdk
+ run: ./gradlew build -x test
+
+ - name: Publish to Maven Central
+ if: ${{ env.VERSION_INCREMENTED == 'true' }}
+ working-directory: ./apps/java-sdk
+ env:
+ ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_USERNAME }}
+ ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_PASSWORD }}
+ ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.GPG_SIGNING_KEY }}
+ ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.GPG_SIGNING_PASSWORD }}
+ run: ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache
diff --git a/.github/workflows/publish-js-sdk.yml b/.github/workflows/publish-js-sdk.yml
index 49df984bad..fabb382549 100644
--- a/.github/workflows/publish-js-sdk.yml
+++ b/.github/workflows/publish-js-sdk.yml
@@ -13,22 +13,29 @@ env:
jobs:
publish:
name: Publish
- runs-on: ubuntu-latest
+ runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v5
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
+ cache: "pnpm"
+ cache-dependency-path: './apps/js-sdk/firecrawl/pnpm-lock.yaml'
- name: Authenticate
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
- name: Publish
run: |
- npm install
- npm run build
- npm publish --access public
+ pnpm install
+ pnpm run build
+ pnpm publish --access public --no-git-checks
sed -i 's/"name": "@mendable\/firecrawl-js"/"name": "@mendable\/firecrawl"/g' package.json
- npm publish --access public
+ pnpm publish --access public --no-git-checks
sed -i 's/"name": "@mendable\/firecrawl"/"name": "firecrawl"/g' package.json
- npm publish --access public
+ sed -i '/"firecrawl":/d' package.json
+ pnpm publish --access public --no-git-checks
working-directory: ./apps/js-sdk/firecrawl
diff --git a/.github/workflows/publish-python-sdk.yml b/.github/workflows/publish-python-sdk.yml
index 2d85ac7839..1e2e589ab3 100644
--- a/.github/workflows/publish-python-sdk.yml
+++ b/.github/workflows/publish-python-sdk.yml
@@ -13,7 +13,7 @@ env:
jobs:
build-and-publish:
- runs-on: ubuntu-latest
+ runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: Checkout repository
diff --git a/.github/workflows/test-java-sdk.yml b/.github/workflows/test-java-sdk.yml
new file mode 100644
index 0000000000..c5bef8d6a2
--- /dev/null
+++ b/.github/workflows/test-java-sdk.yml
@@ -0,0 +1,70 @@
+name: Java SDK Test Suite
+
+on:
+ pull_request:
+ branches:
+ - main
+ paths:
+ - apps/java-sdk/**
+ - .github/workflows/test-java-sdk.yml
+ push:
+ branches:
+ - main
+ paths:
+ - apps/java-sdk/**
+ workflow_dispatch:
+
+jobs:
+ build-and-test:
+ name: Build and Test
+ runs-on: blacksmith-4vcpu-ubuntu-2404
+ if: >-
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'pull_request' ||
+ (github.event_name == 'push' && github.ref == 'refs/heads/main')
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up JDK 11
+ uses: actions/setup-java@v4
+ with:
+ distribution: temurin
+ java-version: "11"
+
+ - name: Cache Gradle packages
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('apps/java-sdk/**/*.gradle.kts', 'apps/java-sdk/gradle/wrapper/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+
+ - name: Grant execute permission for gradlew
+ working-directory: ./apps/java-sdk
+ run: chmod +x gradlew
+
+ - name: Build
+ working-directory: ./apps/java-sdk
+ run: ./gradlew build -x test
+
+ - name: Run unit tests
+ working-directory: ./apps/java-sdk
+ run: ./gradlew test
+
+ - name: Run E2E tests
+ if: env.FIRECRAWL_API_KEY != ''
+ working-directory: ./apps/java-sdk
+ env:
+ FIRECRAWL_API_KEY: ${{ secrets.FIRECRAWL_API_KEY }}
+ run: ./gradlew test
+
+ - name: Publish test report
+ if: always() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
+ uses: dorny/test-reporter@v1
+ with:
+ name: Java SDK Test Report
+ path: apps/java-sdk/build/test-results/test/*.xml
+ reporter: java-junit
+ fail-on-error: true
diff --git a/.github/workflows/test-js-sdk.yml b/.github/workflows/test-js-sdk.yml
index 6f22087038..7bb396c30d 100644
--- a/.github/workflows/test-js-sdk.yml
+++ b/.github/workflows/test-js-sdk.yml
@@ -8,26 +8,37 @@ on:
- apps/js-sdk/firecrawl/**
env:
- TEST_API_KEY: ${{ secrets.TEST_API_KEY }}
+ IDMUX_URL: ${{ secrets.IDMUX_URL }}
jobs:
test:
name: Run tests
- runs-on: ubuntu-latest
+ runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- uses: actions/checkout@v5
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- cache: "npm"
- cache-dependency-path: './apps/js-sdk/firecrawl/package-lock.json'
+ cache: "pnpm"
+ cache-dependency-path: './apps/js-sdk/firecrawl/pnpm-lock.yaml'
+ - name: Tailscale
+ uses: tailscale/github-action@v4
+ with:
+ oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
+ oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
+ tags: tag:ci
+ use-cache: 'true'
- name: Install dependencies
- run: npm install
+ run: pnpm install
working-directory: ./apps/js-sdk/firecrawl
- name: Build
- run: npm run build
+ run: pnpm run build
working-directory: ./apps/js-sdk/firecrawl
- name: Run tests
- run: npm run test
+ run: pnpm run test
working-directory: ./apps/js-sdk/firecrawl
diff --git a/.github/workflows/test-rust-sdk.yml b/.github/workflows/test-rust-sdk.yml
new file mode 100644
index 0000000000..ed85ac6858
--- /dev/null
+++ b/.github/workflows/test-rust-sdk.yml
@@ -0,0 +1,51 @@
+name: Rust SDK Test Suite
+
+on:
+ pull_request:
+ branches:
+ - main
+ paths:
+ - apps/rust-sdk/**
+
+jobs:
+ test:
+ name: Build and Test
+ runs-on: blacksmith-4vcpu-ubuntu-2404
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install Rust toolchain
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ components: clippy
+
+ - name: Cache cargo registry
+ uses: actions/cache@v4
+ with:
+ path: |
+ ~/.cargo/registry
+ ~/.cargo/git
+ apps/rust-sdk/target
+ key: ${{ runner.os }}-cargo-${{ hashFiles('apps/rust-sdk/Cargo.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-cargo-
+
+ - name: Check formatting
+ working-directory: ./apps/rust-sdk
+ run: cargo fmt --check
+
+ - name: Build
+ working-directory: ./apps/rust-sdk
+ run: cargo build --all-targets
+
+ - name: Run clippy
+ working-directory: ./apps/rust-sdk
+ run: cargo clippy --all-targets -- -D warnings -A clippy::needless_borrows_for_generic_args -A clippy::redundant_closure -A clippy::large_enum_variant -A clippy::extra_unused_lifetimes
+
+ - name: Run unit tests (mocked)
+ working-directory: ./apps/rust-sdk
+ run: cargo test --lib
+
+ - name: Build examples
+ working-directory: ./apps/rust-sdk
+ run: cargo build --examples
diff --git a/.github/workflows/test-server.yml b/.github/workflows/test-server.yml
index 6eb8a5c98a..ebe8fd664e 100644
--- a/.github/workflows/test-server.yml
+++ b/.github/workflows/test-server.yml
@@ -15,17 +15,17 @@ jobs:
strategy:
fail-fast: false
matrix:
- engine: ["playwright", "fetch"] # unsure if we need both of these
- proxy: ["proxy", "no-proxy"] # proxy / no-proxy run different tests, keep both
- search: ["searxng"] # disabled google for now, should be fine with just Searxng
- ai: ["openai"] # AI only should be fine, as it simply adds tests, if non-AI fails, AI will fail.
+ engine: ['playwright', 'fetch'] # unsure if we need both of these
+ proxy: ['proxy', 'no-proxy'] # proxy / no-proxy run different tests, keep both
+ search: ['searxng'] # disabled google for now, should be fine with just Searxng
+ ai: ['openai'] # AI only should be fine, as it simply adds tests, if non-AI fails, AI will fail.
# legacy matrix:
# engine: ["playwright", "fetch"]
# proxy: ["proxy", "no-proxy"]
# search: ["searxng", "google"]
# ai: ["openai", "no-ai"]
- runs-on: big-runner
+ runs-on: blacksmith-4vcpu-ubuntu-2404
services:
redis:
image: redis
@@ -68,7 +68,7 @@ jobs:
apps/api/pnpm-lock.yaml
apps/test-site/pnpm-lock.yaml
apps/playwright-service-ts/pnpm-lock.yaml
-
+
- run: pnpm fetch
working-directory: apps/api
- run: pnpm fetch
@@ -105,6 +105,18 @@ jobs:
go-version: 1.24
cache-dependency-path: apps/api/sharedLibs/go-html-to-md/go.sum
+ - name: Verify go.sum is up to date (sharedLibs/go-html-to-md)
+ run: |
+ cd apps/api/sharedLibs/go-html-to-md
+ go mod tidy
+ git diff --exit-code go.mod go.sum || (echo "go.mod/go.sum is out of sync -- run 'go mod tidy' and commit" && exit 1)
+
+ - name: Verify go.sum is up to date (go-html-to-md-service)
+ run: |
+ cd apps/go-html-to-md-service
+ go mod tidy
+ git diff --exit-code go.mod go.sum || (echo "go.mod/go.sum is out of sync -- run 'go mod tidy' and commit" && exit 1)
+
- name: Restore Go lib
id: golib_restore
uses: actions/cache/restore@v4
@@ -116,7 +128,6 @@ jobs:
if: steps.golib_restore.outputs.cache-hit != 'true'
run: |
cd apps/api/sharedLibs/go-html-to-md
- go mod tidy
go build -o libhtml-to-markdown.so -buildmode=c-shared html-to-markdown.go
- name: Cache Go lib
@@ -165,12 +176,12 @@ jobs:
docker run -d -p 3434:8080 -v "${PWD}/searxng:/etc/searxng" --name searxng searxng/searxng
pnpx wait-on tcp:3434 -t 30s
working-directory: ./
-
+
- name: Install API dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
working-directory: apps/api
env:
- npm_config_ignore_scripts: "true"
+ npm_config_ignore_scripts: 'true'
- name: Install test site dependencies
run: pnpm install --frozen-lockfile
@@ -191,7 +202,7 @@ jobs:
working-directory: ./apps/playwright-service-ts
env:
PORT: 3003
-
+
- name: Run Docker Postgres
run: |
docker build -t firecrawl/nuq-postgres:latest ./apps/nuq-postgres
@@ -201,7 +212,7 @@ jobs:
run: pnpm harness pnpm test:snips
working-directory: apps/api
env:
- npm_config_ignore_scripts: "true" # required currently to prevent re-building cached native lib
+ npm_config_ignore_scripts: 'true' # required currently to prevent re-building cached native lib
- name: Publish test report
if: always()
@@ -377,7 +388,7 @@ jobs:
# working-directory: apps/api
# env:
# npm_config_ignore_scripts: "true"
-
+
# - name: Run Docker Postgres
# run: |
# docker build -t firecrawl/nuq-postgres:latest ./apps/nuq-postgres
diff --git a/.gitignore b/.gitignore
index 749ce29c71..10a36c2a36 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,4 +52,6 @@ apps/python-sdk/.venv/
/apps/go-html-to-md-service/.gomodcache/
-target/
\ No newline at end of file
+target/
+
+.cursor/
\ No newline at end of file
diff --git a/README.md b/README.md
index d042f7f1c4..fe4123696f 100644
--- a/README.md
+++ b/README.md
@@ -5,654 +5,596 @@
height="200"
>
+
+
-# 🔥 Firecrawl
+---
-Empower your AI apps with clean data from any website. Featuring advanced scraping, crawling, and data extraction capabilities.
+# **🔥 Firecrawl**
-_This repository is in development, and we’re still integrating custom modules into the mono repo. It's not fully ready for self-hosted deployment yet, but you can run it locally._
+**Turn websites into LLM-ready data.**
-## What is Firecrawl?
+[**Firecrawl**](https://firecrawl.dev/?ref=github) is an API that scrapes, crawls, and extracts structured data from any website, powering AI agents and apps with real-time context from the web.
-[Firecrawl](https://firecrawl.dev?ref=github) is an API service that takes a URL, crawls it, and converts it into clean markdown or structured data. We crawl all accessible subpages and give you clean data for each. No sitemap required. Check out our [documentation](https://docs.firecrawl.dev).
+Looking for our MCP? Check out the repo [here](https://github.com/firecrawl/firecrawl-mcp-server).
-Looking for our MCP? Check out the [repo here](https://github.com/firecrawl/firecrawl-mcp-server).
+*This repository is in development, and we're still integrating custom modules into the mono repo. It's not fully ready for self-hosted deployment yet, but you can run it locally.*
-_Pst. hey, you, join our stargazers :)_
+_Pst. Hey, you, join our stargazers :)_
-## How to use it?
-
-We provide an easy to use API with our hosted version. You can find the playground and documentation [here](https://firecrawl.dev/playground). You can also self host the backend if you'd like.
+---
-Check out the following resources to get started:
-- [x] **API**: [Documentation](https://docs.firecrawl.dev/api-reference/introduction)
-- [x] **SDKs**: [Python](https://docs.firecrawl.dev/sdks/python), [Node](https://docs.firecrawl.dev/sdks/node)
-- [x] **LLM Frameworks**: [Langchain (python)](https://python.langchain.com/docs/integrations/document_loaders/firecrawl/), [Langchain (js)](https://js.langchain.com/docs/integrations/document_loaders/web_loaders/firecrawl), [Llama Index](https://docs.llamaindex.ai/en/latest/examples/data_connectors/WebPageDemo/#using-firecrawl-reader), [Crew.ai](https://docs.crewai.com/), [Composio](https://composio.dev/tools/firecrawl/all), [PraisonAI](https://docs.praison.ai/firecrawl/), [Superinterface](https://superinterface.ai/docs/assistants/functions/firecrawl), [Vectorize](https://docs.vectorize.io/integrations/source-connectors/firecrawl)
-- [x] **Low-code Frameworks**: [Dify](https://dify.ai/blog/dify-ai-blog-integrated-with-firecrawl), [Langflow](https://docs.langflow.org/), [Flowise AI](https://docs.flowiseai.com/integrations/langchain/document-loaders/firecrawl), [Cargo](https://docs.getcargo.io/integration/firecrawl), [Pipedream](https://pipedream.com/apps/firecrawl/)
-- [x] **Community SDKs**: [Go](https://docs.firecrawl.dev/sdks/go), [Rust](https://docs.firecrawl.dev/sdks/rust)
-- [x] **Others**: [Zapier](https://zapier.com/apps/firecrawl/integrations), [Pabbly Connect](https://www.pabbly.com/connect/integrations/firecrawl/)
-- [ ] Want an SDK or Integration? Let us know by opening an issue.
+## Why Firecrawl?
-To run locally, refer to guide [here](https://github.com/firecrawl/firecrawl/blob/main/CONTRIBUTING.md).
+- **LLM-ready output**: Clean markdown, structured JSON, screenshots, HTML, and more
+- **Industry-leading reliability**: >80% coverage on [benchmark evaluations](https://www.firecrawl.dev/blog/the-worlds-best-web-data-api-v25), outperforming every other provider tested
+- **Handles the hard stuff**: Proxies, JavaScript rendering, and dynamic content that breaks other scrapers
+- **Customization**: Exclude tags, crawl behind auth walls, max depth, and more
+- **Media parsing**: Automatic text extraction from PDFs, DOCX, and images
+- **Actions**: Click, scroll, input, wait, and more before extracting
+- **Batch processing**: Scrape thousands of URLs asynchronously
+- **Change tracking**: Monitor website content changes over time
-### API Key
+---
-To use the API, you need to sign up on [Firecrawl](https://firecrawl.dev) and get an API key.
+## Quick Start
-### Features
-
-- [**Scrape**](#scraping): scrapes a URL and get its content in LLM-ready format (markdown, structured data via [LLM Extract](#llm-extraction-beta), screenshot, html)
-- [**Crawl**](#crawling): scrapes all the URLs of a web page and return content in LLM-ready format
-- [**Map**](#map): input a website and get all the website urls - extremely fast
-- [**Search**](#search): search the web and get full content from results
-- [**Extract**](#extract): get structured data from single page, multiple pages or entire websites with AI.
-
-### Powerful Capabilities
-- **LLM-ready formats**: markdown, structured data, screenshot, HTML, links, metadata
-- **The hard stuff**: proxies, anti-bot mechanisms, dynamic content (js-rendered), output parsing, orchestration
-- **Customizability**: exclude tags, crawl behind auth walls with custom headers, max crawl depth, etc...
-- **Media parsing**: pdfs, docx, images
-- **Reliability first**: designed to get the data you need - no matter how hard it is
-- **Actions**: click, scroll, input, wait and more before extracting data
-- **Batching**: scrape thousands of URLs at the same time with a new async endpoint
-- **Change Tracking**: monitor and detect changes in website content over time
-
-You can find all of Firecrawl's capabilities and how to use them in our [documentation](https://docs.firecrawl.dev)
-
-### Crawling
-
-Used to crawl a URL and all accessible subpages. This submits a crawl job and returns a job ID to check the status of the crawl.
+Sign up at [firecrawl.dev](https://firecrawl.dev) to get your API key and start extracting data in seconds. Try the [playground](https://firecrawl.dev/playground) to test it out.
+### Make Your First API Request
```bash
-curl -X POST https://api.firecrawl.dev/v2/crawl \
- -H 'Content-Type: application/json' \
- -H 'Authorization: Bearer fc-YOUR_API_KEY' \
- -d '{
- "url": "https://docs.firecrawl.dev",
- "limit": 10,
- "scrapeOptions": {
- "formats": ["markdown", "html"]
- }
- }'
+curl -X POST 'https://api.firecrawl.dev/v2/scrape' \
+ -H 'Authorization: Bearer fc-YOUR_API_KEY' \
+ -H 'Content-Type: application/json' \
+ -d '{"url": "https://example.com"}'
```
-Returns a crawl job id and the url to check the status of the crawl.
-
+Response:
```json
{
"success": true,
- "id": "123-456-789",
- "url": "https://api.firecrawl.dev/v2/crawl/123-456-789"
+ "data": {
+ "markdown": "# Example Domain\n\nThis domain is for use in illustrative examples...",
+ "metadata": {
+ "title": "Example Domain",
+ "sourceURL": "https://example.com"
+ }
+ }
}
```
-### Check Crawl Job
+---
-Used to check the status of a crawl job and get its result.
+## Feature Overview
-```bash
-curl -X GET https://api.firecrawl.dev/v2/crawl/123-456-789 \
- -H 'Content-Type: application/json' \
- -H 'Authorization: Bearer YOUR_API_KEY'
-```
+| Feature | Description |
+|---------|-------------|
+| [**Scrape**](#scraping) | Convert any URL to markdown, HTML, screenshots, or structured JSON |
+| [**Search**](#search) | Search the web and get full page content from results |
+| [**Map**](#map) | Discover all URLs on a website instantly |
+| [**Crawl**](#crawling) | Scrape all URLs of a website with a single request |
+| [**Agent**](#agent) | Automated data gathering, just describe what you need |
+---
-```json
-{
- "status": "completed",
- "total": 36,
- "creditsUsed": 36,
- "expiresAt": "2024-00-00T00:00:00.000Z",
- "data": [
- {
- "markdown": "[Firecrawl Docs home page!...",
- "html": "...",
- "metadata": {
- "title": "Build a 'Chat with website' using Groq Llama 3 | Firecrawl",
- "language": "en",
- "sourceURL": "https://docs.firecrawl.dev/learn/rag-llama3",
- "description": "Learn how to use Firecrawl, Groq Llama 3, and Langchain to build a 'Chat with your website' bot.",
- "ogLocaleAlternate": [],
- "statusCode": 200
- }
- }
- ]
-}
-```
-
-### Scraping
-
-Used to scrape a URL and get its content in the specified formats.
+## Scrape
+Convert any URL to clean markdown, HTML, or structured data.
```bash
-curl -X POST https://api.firecrawl.dev/v2/scrape \
- -H 'Content-Type: application/json' \
- -H 'Authorization: Bearer YOUR_API_KEY' \
- -d '{
- "url": "https://docs.firecrawl.dev",
- "formats" : ["markdown", "html"]
- }'
+curl -X POST 'https://api.firecrawl.dev/v2/scrape' \
+ -H 'Authorization: Bearer fc-YOUR_API_KEY' \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "url": "https://docs.firecrawl.dev",
+ "formats": ["markdown", "html"]
+ }'
```
Response:
-
```json
{
"success": true,
"data": {
- "markdown": "Launch Week I is here! [See our Day 2 Release 🚀](https://www.firecrawl.dev/blog/launch-week-i-day-2-doubled-rate-limits)[💥 Get 2 months free...",
- "html": "...",
"metadata": {
- "title": "Home - Firecrawl",
- "description": "Firecrawl crawls and converts any website into clean markdown.",
- "language": "en",
- "keywords": "Firecrawl,Markdown,Data,Mendable,Langchain",
- "robots": "follow, index",
- "ogTitle": "Firecrawl",
- "ogDescription": "Turn any website into LLM-ready data.",
- "ogUrl": "https://www.firecrawl.dev/",
- "ogImage": "https://www.firecrawl.dev/og.png?123",
- "ogLocaleAlternate": [],
- "ogSiteName": "Firecrawl",
- "sourceURL": "https://firecrawl.dev",
+ "title": "Quickstart | Firecrawl",
+ "description": "Firecrawl allows you to turn entire websites into LLM-ready markdown",
+ "sourceURL": "https://docs.firecrawl.dev",
"statusCode": 200
}
}
}
```
-### Map
+### Extract Structured Data (JSON Mode)
-Used to map a URL and get urls of the website. This returns most links present on the website.
+Extract structured data using a schema:
+```python
+from firecrawl import Firecrawl
+from pydantic import BaseModel
-```bash cURL
-curl -X POST https://api.firecrawl.dev/v2/map \
- -H 'Content-Type: application/json' \
- -H 'Authorization: Bearer YOUR_API_KEY' \
- -d '{
- "url": "https://firecrawl.dev"
- }'
-```
+app = Firecrawl(api_key="fc-YOUR_API_KEY")
-Response:
+class CompanyInfo(BaseModel):
+ company_mission: str
+ is_open_source: bool
+ is_in_yc: bool
+result = app.scrape(
+ 'https://firecrawl.dev',
+ formats=[{"type": "json", "schema": CompanyInfo.model_json_schema()}]
+)
+
+print(result.json)
+```
```json
-{
- "success": true,
- "links": [
- { "url": "https://firecrawl.dev", "title": "Firecrawl", "description": "Firecrawl is a tool that allows you to crawl a website and get the data you need." },
- { "url": "https://www.firecrawl.dev/pricing", "title": "Firecrawl Pricing", "description": "Firecrawl Pricing" },
- { "url": "https://www.firecrawl.dev/blog", "title": "Firecrawl Blog", "description": "Firecrawl Blog" },
- { "url": "https://www.firecrawl.dev/playground", "title": "Firecrawl Playground", "description": "Firecrawl Playground" },
- { "url": "https://www.firecrawl.dev/smart-crawl", "title": "Firecrawl Smart Crawl", "description": "Firecrawl Smart Crawl" }
- ]
-}
+{"company_mission": "Turn websites into LLM-ready data", "is_open_source": true, "is_in_yc": true}
```
-#### Map with search
+Or extract with just a prompt (no schema):
+```python
+result = app.scrape(
+ 'https://firecrawl.dev',
+ formats=[{"type": "json", "prompt": "Extract the company mission"}]
+)
+```
-Map with `search` param allows you to search for specific urls inside a website.
+### Scrape Formats
-```bash cURL
-curl -X POST https://api.firecrawl.dev/v2/map \
- -H 'Content-Type: application/json' \
- -H 'Authorization: Bearer YOUR_API_KEY' \
- -d '{
- "url": "https://firecrawl.dev",
- "search": "docs"
- }'
-```
+Available formats: `markdown`, `html`, `rawHtml`, `screenshot`, `links`, `json`, `branding`
-Response will be an ordered list from the most relevant to the least relevant.
+**Get a screenshot**
+```python
+doc = app.scrape("https://firecrawl.dev", formats=["screenshot"])
+print(doc.screenshot) # Base64 encoded image
+```
-```json
-{
- "success": true,
- "links": [
- { "url": "https://docs.firecrawl.dev", "title": "Firecrawl Docs", "description": "Firecrawl Docs" },
- { "url": "https://docs.firecrawl.dev/sdks/python", "title": "Firecrawl Python SDK", "description": "Firecrawl Python SDK" },
- { "url": "https://docs.firecrawl.dev/learn/rag-llama3", "title": "Firecrawl RAG Llama 3", "description": "Firecrawl RAG Llama 3" }
- ]
-}
+**Extract brand identity (colors, fonts, typography)**
+```python
+doc = app.scrape("https://firecrawl.dev", formats=["branding"])
+print(doc.branding) # {"colors": {...}, "fonts": [...], "typography": {...}}
```
-### Search
+### Actions (Interact Before Scraping)
-Search the web and get full content from results
+Click, type, scroll, and more before extracting:
+```python
+doc = app.scrape(
+ url="https://example.com/login",
+ formats=["markdown"],
+ actions=[
+ {"type": "write", "text": "user@example.com"},
+ {"type": "press", "key": "Tab"},
+ {"type": "write", "text": "password"},
+ {"type": "click", "selector": 'button[type="submit"]'},
+ {"type": "wait", "milliseconds": 2000},
+ {"type": "screenshot"}
+ ]
+)
+```
-Firecrawl’s search API allows you to perform web searches and optionally scrape the search results in one operation.
+---
-- Choose specific output formats (markdown, HTML, links, screenshots)
-- Search the web with customizable parameters (language, country, etc.)
-- Optionally retrieve content from search results in various formats
-- Control the number of results and set timeouts
+## Search
+Search the web and optionally scrape the results.
```bash
-curl -X POST https://api.firecrawl.dev/v2/search \
- -H "Content-Type: application/json" \
- -H "Authorization: Bearer fc-YOUR_API_KEY" \
+curl -X POST 'https://api.firecrawl.dev/v2/search' \
+ -H 'Authorization: Bearer fc-YOUR_API_KEY' \
+ -H 'Content-Type: application/json' \
-d '{
- "query": "what is firecrawl?",
+ "query": "firecrawl web scraping",
"limit": 5
}'
```
-#### Response
-
+Response:
```json
{
"success": true,
- "data": [
- {
- "url": "https://firecrawl.dev",
- "title": "Firecrawl | Home Page",
- "description": "Turn websites into LLM-ready data with Firecrawl"
- },
- {
- "url": "https://docs.firecrawl.dev",
- "title": "Documentation | Firecrawl",
- "description": "Learn how to use Firecrawl in your own applications"
- }
- ]
+ "data": {
+ "web": [
+ {
+ "url": "https://www.firecrawl.dev/",
+ "title": "Firecrawl - The Web Data API for AI",
+ "description": "The web crawling, scraping, and search API for AI.",
+ "position": 1
+ }
+ ],
+ "images": [...],
+ "news": [...]
+ }
}
```
-#### With content scraping
+### Search with Content Scraping
-```bash
-curl -X POST https://api.firecrawl.dev/v2/search \
- -H "Content-Type: application/json" \
- -H "Authorization: Bearer fc-YOUR_API_KEY" \
- -d '{
- "query": "what is firecrawl?",
- "limit": 5,
- "scrapeOptions": {
- "formats": ["markdown", "links"]
- }
- }'
-```
-
-### Extract (Beta)
+Get the full content of search results:
+```python
+from firecrawl import Firecrawl
-Get structured data from entire websites with a prompt and/or a schema.
+firecrawl = Firecrawl(api_key="fc-YOUR_API_KEY")
-You can extract structured data from one or multiple URLs, including wildcards:
+results = firecrawl.search(
+ "firecrawl web scraping",
+ limit=3,
+ scrape_options={
+ "formats": ["markdown", "links"]
+ }
+)
+```
-Single Page:
-Example: https://firecrawl.dev/some-page
+---
-Multiple Pages / Full Domain
-Example: https://firecrawl.dev/*
+## Agent
-When you use /*, Firecrawl will automatically crawl and parse all URLs it can discover in that domain, then extract the requested data.
+**The easiest way to get data from the web.** Describe what you need, and our AI agent searches, navigates, and extracts it. No URLs required.
+Agent is the evolution of our `/extract` endpoint: faster, more reliable, and doesn't require you to know the URLs upfront.
```bash
-curl -X POST https://api.firecrawl.dev/v2/extract \
- -H 'Content-Type: application/json' \
- -H 'Authorization: Bearer YOUR_API_KEY' \
- -d '{
- "urls": [
- "https://firecrawl.dev/*",
- "https://docs.firecrawl.dev/",
- "https://www.ycombinator.com/companies"
- ],
- "prompt": "Extract the company mission, whether it is open source, and whether it is in Y Combinator from the page.",
- "schema": {
- "type": "object",
- "properties": {
- "company_mission": {
- "type": "string"
- },
- "is_open_source": {
- "type": "boolean"
- },
- "is_in_yc": {
- "type": "boolean"
- }
- },
- "required": [
- "company_mission",
- "is_open_source",
- "is_in_yc"
- ]
- }
- }'
+curl -X POST 'https://api.firecrawl.dev/v2/agent' \
+ -H 'Authorization: Bearer fc-YOUR_API_KEY' \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "prompt": "Find the pricing plans for Notion"
+ }'
```
+Response:
```json
{
"success": true,
- "id": "44aa536d-f1cb-4706-ab87-ed0386685740",
- "urlTrace": []
+ "data": {
+ "result": "Notion offers the following pricing plans:\n\n1. Free - $0/month...\n2. Plus - $10/seat/month...\n3. Business - $18/seat/month...",
+ "sources": ["https://www.notion.so/pricing"]
+ }
}
```
-If you are using the sdks, it will auto pull the response for you:
+### Agent with Structured Output
+Use a schema to get structured data:
+```python
+from firecrawl import Firecrawl
+from pydantic import BaseModel, Field
+from typing import List, Optional
+
+app = Firecrawl(api_key="fc-YOUR_API_KEY")
+
+class Founder(BaseModel):
+ name: str = Field(description="Full name of the founder")
+ role: Optional[str] = Field(None, description="Role or position")
+
+class FoundersSchema(BaseModel):
+ founders: List[Founder] = Field(description="List of founders")
+
+result = app.agent(
+ prompt="Find the founders of Firecrawl",
+ schema=FoundersSchema
+)
+
+print(result.data)
+```
```json
{
- "success": true,
- "data": {
- "company_mission": "Firecrawl is the easiest way to extract data from the web. Developers use us to reliably convert URLs into LLM-ready markdown or structured data with a single API call.",
- "supports_sso": false,
- "is_open_source": true,
- "is_in_yc": true
- }
+ "founders": [
+ {"name": "Eric Ciarla", "role": "Co-founder"},
+ {"name": "Nicolas Camara", "role": "Co-founder"},
+ {"name": "Caleb Peffer", "role": "Co-founder"}
+ ]
}
```
-### LLM Extraction (Beta)
+### Agent with URLs (Optional)
+
+Focus the agent on specific pages:
+```python
+result = app.agent(
+ urls=["https://docs.firecrawl.dev", "https://firecrawl.dev/pricing"],
+ prompt="Compare the features and pricing information"
+)
+```
+
+### Model Selection
+
+Choose between two models based on your needs:
+
+| Model | Cost | Best For |
+|-------|------|----------|
+| `spark-1-mini` (default) | 60% cheaper | Most tasks |
+| `spark-1-pro` | Standard | Complex research, critical extraction |
+```python
+result = app.agent(
+ prompt="Compare enterprise features across Firecrawl, Apify, and ScrapingBee",
+ model="spark-1-pro"
+)
+```
+
+**When to use Pro:**
+- Comparing data across multiple websites
+- Extracting from sites with complex navigation or auth
+- Research tasks where the agent needs to explore multiple paths
+- Critical data where accuracy is paramount
+
+Learn more about Spark models in our [Agent documentation](https://docs.firecrawl.dev/features/agent).
-Used to extract structured data from scraped pages.
+### Using Firecrawl with AI agents
+Install the Firecrawl skill to let AI agents like Claude Code, Codex, and OpenCode use Firecrawl automatically:
```bash
-curl -X POST https://api.firecrawl.dev/v2/scrape \
+npx skills add firecrawl/cli
+```
+
+Restart your agent after installing. See the [Skill + CLI docs](https://docs.firecrawl.dev/sdks/cli) for full setup.
+
+---
+
+## Crawling
+
+Crawl an entire website and get content from all pages.
+```bash
+curl -X POST 'https://api.firecrawl.dev/v2/crawl' \
+ -H 'Authorization: Bearer fc-YOUR_API_KEY' \
-H 'Content-Type: application/json' \
- -H 'Authorization: Bearer YOUR_API_KEY' \
-d '{
- "url": "https://www.mendable.ai/",
- "formats": [
- {
- "type": "json",
- "schema": {
- "type": "object",
- "properties": {
- "company_mission": { "type": "string" },
- "supports_sso": { "type": "boolean" },
- "is_open_source": { "type": "boolean" },
- "is_in_yc": { "type": "boolean" }
- }
- }
- }
- ]
+ "url": "https://docs.firecrawl.dev",
+ "limit": 100,
+ "scrapeOptions": {
+ "formats": ["markdown"]
+ }
}'
```
+Returns a job ID:
```json
{
"success": true,
- "data": {
- "content": "Raw Content",
- "metadata": {
- "title": "Mendable",
- "description": "Mendable allows you to easily build AI chat applications. Ingest, customize, then deploy with one line of code anywhere you want. Brought to you by SideGuide",
- "robots": "follow, index",
- "ogTitle": "Mendable",
- "ogDescription": "Mendable allows you to easily build AI chat applications. Ingest, customize, then deploy with one line of code anywhere you want. Brought to you by SideGuide",
- "ogUrl": "https://mendable.ai/",
- "ogImage": "https://mendable.ai/mendable_new_og1.png",
- "ogLocaleAlternate": [],
- "ogSiteName": "Mendable",
- "sourceURL": "https://mendable.ai/"
- },
- "json": {
- "company_mission": "Train a secure AI on your technical resources that answers customer and employee questions so your team doesn't have to",
- "supports_sso": true,
- "is_open_source": false,
- "is_in_yc": true
- }
- }
+ "id": "123-456-789",
+ "url": "https://api.firecrawl.dev/v2/crawl/123-456-789"
}
```
-### Extracting without a schema (New)
-
-You can now extract without a schema by just passing a `prompt` to the endpoint. The llm chooses the structure of the data.
-
+### Check Crawl Status
```bash
-curl -X POST https://api.firecrawl.dev/v2/scrape \
- -H 'Content-Type: application/json' \
- -H 'Authorization: Bearer YOUR_API_KEY' \
- -d '{
- "url": "https://docs.firecrawl.dev/",
- "formats": [
- {
- "type": "json",
- "prompt": "Extract the company mission from the page."
- }
- ]
- }'
+curl -X GET 'https://api.firecrawl.dev/v2/crawl/123-456-789' \
+ -H 'Authorization: Bearer fc-YOUR_API_KEY'
+```
+```json
+{
+ "status": "completed",
+ "total": 50,
+ "completed": 50,
+ "creditsUsed": 50,
+ "data": [
+ {
+ "markdown": "# Page Title\n\nContent...",
+ "metadata": {"title": "Page Title", "sourceURL": "https://..."}
+ }
+ ]
+}
```
-### Interacting with the page with Actions (Cloud-only)
-
-Firecrawl allows you to perform various actions on a web page before scraping its content. This is particularly useful for interacting with dynamic content, navigating through pages, or accessing content that requires user interaction.
+**Note:** The [SDKs](#sdks) handle polling automatically for a better developer experience.
-Here is an example of how to use actions to navigate to google.com, search for Firecrawl, click on the first result, and take a screenshot.
+---
-```bash
-curl -X POST https://api.firecrawl.dev/v2/scrape \
- -H 'Content-Type: application/json' \
- -H 'Authorization: Bearer YOUR_API_KEY' \
- -d '{
- "url": "google.com",
- "formats": ["markdown"],
- "actions": [
- {"type": "wait", "milliseconds": 2000},
- {"type": "click", "selector": "textarea[title=\"Search\"]"},
- {"type": "wait", "milliseconds": 2000},
- {"type": "write", "text": "firecrawl"},
- {"type": "wait", "milliseconds": 2000},
- {"type": "press", "key": "ENTER"},
- {"type": "wait", "milliseconds": 3000},
- {"type": "click", "selector": "h3"},
- {"type": "wait", "milliseconds": 3000},
- {"type": "screenshot"}
- ]
- }'
-```
-
-### Batch Scraping Multiple URLs (New)
-
-You can now batch scrape multiple URLs at the same time. It is very similar to how the /crawl endpoint works. It submits a batch scrape job and returns a job ID to check the status of the batch scrape.
+## Map
+Discover all URLs on a website instantly.
```bash
-curl -X POST https://api.firecrawl.dev/v2/batch/scrape \
- -H 'Content-Type: application/json' \
- -H 'Authorization: Bearer YOUR_API_KEY' \
- -d '{
- "urls": ["https://docs.firecrawl.dev", "https://docs.firecrawl.dev/sdks/overview"],
- "formats" : ["markdown", "html"]
- }'
+curl -X POST 'https://api.firecrawl.dev/v2/map' \
+ -H 'Authorization: Bearer fc-YOUR_API_KEY' \
+ -H 'Content-Type: application/json' \
+ -d '{"url": "https://firecrawl.dev"}'
```
+Response:
+```json
+{
+ "success": true,
+ "links": [
+ {"url": "https://firecrawl.dev", "title": "Firecrawl", "description": "Turn websites into LLM-ready data"},
+ {"url": "https://firecrawl.dev/pricing", "title": "Pricing", "description": "Firecrawl pricing plans"},
+ {"url": "https://firecrawl.dev/blog", "title": "Blog", "description": "Firecrawl blog"}
+ ]
+}
+```
+### Map with Search
-## Using Python SDK
+Find specific URLs within a site:
+```python
+from firecrawl import Firecrawl
-### Installing Python SDK
+app = Firecrawl(api_key="fc-YOUR_API_KEY")
-```bash
-pip install firecrawl-py
+result = app.map("https://firecrawl.dev", search="pricing")
+# Returns URLs ordered by relevance to "pricing"
```
-### Crawl a website
+---
+
+## Batch Scraping
+Scrape multiple URLs at once:
```python
from firecrawl import Firecrawl
-firecrawl = Firecrawl(api_key="fc-YOUR_API_KEY")
+app = Firecrawl(api_key="fc-YOUR_API_KEY")
-# Scrape a website (returns a Document)
-doc = firecrawl.scrape(
+job = app.batch_scrape([
"https://firecrawl.dev",
- formats=["markdown", "html"],
-)
-print(doc.markdown)
+ "https://docs.firecrawl.dev",
+ "https://firecrawl.dev/pricing"
+], formats=["markdown"])
-# Crawl a website
-response = firecrawl.crawl(
- "https://firecrawl.dev",
- limit=100,
- scrape_options={"formats": ["markdown", "html"]},
- poll_interval=30,
-)
-print(response)
+for doc in job.data:
+ print(doc.metadata.source_url)
```
-### Extracting structured data from a URL
+---
+
+## SDKs
-With LLM extraction, you can easily extract structured data from any URL. We support pydantic schemas to make it easier for you too. Here is how you to use it:
+Our SDKs provide a convenient way to interact with all Firecrawl features and automatically handle polling for async operations like crawling and batch scraping.
+### Python
+
+Install the SDK:
+```bash
+pip install firecrawl-py
+```
```python
-from pydantic import BaseModel, Field
-from typing import List
+from firecrawl import Firecrawl
-class Article(BaseModel):
- title: str
- points: int
- by: str
- commentsURL: str
+app = Firecrawl(api_key="fc-YOUR_API_KEY")
-class TopArticles(BaseModel):
- top: List[Article] = Field(..., description="Top 5 stories")
+# Scrape a single URL
+doc = app.scrape("https://firecrawl.dev", formats=["markdown"])
+print(doc.markdown)
-# Use JSON format with a Pydantic schema
-doc = firecrawl.scrape(
- "https://news.ycombinator.com",
- formats=[{"type": "json", "schema": TopArticles}],
-)
-print(doc.json)
-```
+# Use the Agent for autonomous data gathering
+result = app.agent(prompt="Find the founders of Stripe")
+print(result.data)
-## Using the Node SDK
+# Crawl a website (automatically waits for completion)
+docs = app.crawl("https://docs.firecrawl.dev", limit=50)
+for doc in docs.data:
+ print(doc.metadata.source_url, doc.markdown[:100])
-### Installation
+# Search the web
+results = app.search("best web scraping tools 2024", limit=10)
+print(results)
+```
-To install the Firecrawl Node SDK, you can use npm:
+### Node.js
+Install the SDK:
```bash
npm install @mendable/firecrawl-js
```
+```javascript
+import Firecrawl from '@mendable/firecrawl-js';
-### Usage
-
-1. Get an API key from [firecrawl.dev](https://firecrawl.dev)
-2. Set the API key as an environment variable named `FIRECRAWL_API_KEY` or pass it as a parameter to the `Firecrawl` class.
+const app = new Firecrawl({ apiKey: 'fc-YOUR_API_KEY' });
-```js
-import Firecrawl from '@mendable/firecrawl-js';
+// Scrape a single URL
+const doc = await app.scrape('https://firecrawl.dev', { formats: ['markdown'] });
+console.log(doc.markdown);
-const firecrawl = new Firecrawl({ apiKey: 'fc-YOUR_API_KEY' });
+// Use the Agent for autonomous data gathering
+const result = await app.agent({ prompt: 'Find the founders of Stripe' });
+console.log(result.data);
-// Scrape a website
-const doc = await firecrawl.scrape('https://firecrawl.dev', {
- formats: ['markdown', 'html'],
+// Crawl a website (automatically waits for completion)
+const docs = await app.crawl('https://docs.firecrawl.dev', { limit: 50 });
+docs.data.forEach(doc => {
+ console.log(doc.metadata.sourceURL, doc.markdown.substring(0, 100));
});
-console.log(doc);
-// Crawl a website
-const response = await firecrawl.crawl('https://firecrawl.dev', {
- limit: 100,
- scrapeOptions: { formats: ['markdown', 'html'] },
+// Search the web
+const results = await app.search('best web scraping tools 2024', { limit: 10 });
+results.data.web.forEach(result => {
+ console.log(`${result.title}: ${result.url}`);
});
-console.log(response);
```
+### Community SDKs
-### Extracting structured data from a URL
+- [Go SDK](https://github.com/mendableai/firecrawl-go)
+- [Rust SDK](https://docs.firecrawl.dev/sdks/rust)
-With LLM extraction, you can easily extract structured data from any URL. We support zod schema to make it easier for you too. Here is how to use it:
+---
-```js
-import Firecrawl from '@mendable/firecrawl-js';
-import { z } from 'zod';
-
-const firecrawl = new Firecrawl({ apiKey: 'fc-YOUR_API_KEY' });
-
-// Define schema to extract contents into
-const schema = z.object({
- top: z
- .array(
- z.object({
- title: z.string(),
- points: z.number(),
- by: z.string(),
- commentsURL: z.string(),
- })
- )
- .length(5)
- .describe('Top 5 stories on Hacker News'),
-});
+## Integrations
-// Use the v2 extract API with direct Zod schema support
-const extractRes = await firecrawl.extract({
- urls: ['https://news.ycombinator.com'],
- schema,
- prompt: 'Extract the top 5 stories',
-});
+**Agents & AI Tools**
+- [Firecrawl Skill](https://docs.firecrawl.dev/sdks/cli)
+- [Firecrawl MCP](https://github.com/mendableai/firecrawl-mcp-server)
-console.log(extractRes);
-```
+**Platforms**
+- [Lovable](https://docs.lovable.dev/integrations/firecrawl)
+- [Zapier](https://zapier.com/apps/firecrawl/integrations)
+- [n8n](https://n8n.io/integrations/firecrawl/)
-## Open Source vs Cloud Offering
+[View all integrations →](https://www.firecrawl.dev/integrations)
-Firecrawl is open source available under the AGPL-3.0 license.
+**Missing your favorite tool?** [Open an issue](https://github.com/mendableai/firecrawl/issues) and let us know!
-To deliver the best possible product, we offer a hosted version of Firecrawl alongside our open-source offering. The cloud solution allows us to continuously innovate and maintain a high-quality, sustainable service for all users.
+---
-Firecrawl Cloud is available at [firecrawl.dev](https://firecrawl.dev) and offers a range of features that are not available in the open source version:
+## Resources
-
+- [Documentation](https://docs.firecrawl.dev)
+- [API Reference](https://docs.firecrawl.dev/api-reference/introduction)
+- [Playground](https://firecrawl.dev/playground)
+- [Changelog](https://firecrawl.dev/changelog)
+---
-## Contributing
+## Open Source vs Cloud
+
+Firecrawl is open source under the AGPL-3.0 license. The cloud version at [firecrawl.dev](https://firecrawl.dev) includes additional features:
-We love contributions! Please read our [contributing guide](CONTRIBUTING.md) before submitting a pull request. If you'd like to self-host, refer to the [self-hosting guide](SELF_HOST.md).
+
-_It is the sole responsibility of the end users to respect websites' policies when scraping, searching and crawling with Firecrawl. Users are advised to adhere to the applicable privacy policies and terms of use of the websites prior to initiating any scraping activities. By default, Firecrawl respects the directives specified in the websites' robots.txt files when crawling. By utilizing Firecrawl, you expressly agree to comply with these conditions._
+To run locally, see the [Contributing Guide](https://github.com/firecrawl/firecrawl/blob/main/CONTRIBUTING.md). To self-host, see [Self-Hosting Guide](https://docs.firecrawl.dev/contributing/self-host).
-## Contributors
+---
+
+## Contributing
+
+We love contributions! Please read our [Contributing Guide](https://github.com/firecrawl/firecrawl/blob/main/CONTRIBUTING.md) before submitting a pull request.
+
+### Contributors
-## License Disclaimer
-
-This project is primarily licensed under the GNU Affero General Public License v3.0 (AGPL-3.0), as specified in the LICENSE file in the root directory of this repository. However, certain components of this project are licensed under the MIT License. Refer to the LICENSE files in these specific directories for details.
+---
-Please note:
+## License
-- The AGPL-3.0 license applies to all parts of the project unless otherwise specified.
-- The SDKs and some UI components are licensed under the MIT License. Refer to the LICENSE files in these specific directories for details.
-- When using or contributing to this project, ensure you comply with the appropriate license terms for the specific component you are working with.
+This project is primarily licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). The SDKs and some UI components are licensed under the MIT License. See the LICENSE files in specific directories for details.
-For more details on the licensing of specific components, please refer to the LICENSE files in the respective directories or contact the project maintainers.
+---
+**It is the sole responsibility of end users to respect websites' policies when scraping.** Users are advised to adhere to applicable privacy policies and terms of use. By default, Firecrawl respects robots.txt directives. By using Firecrawl, you agree to comply with these conditions.
-
- ↑ Back to Top ↑
-
+
+ ↑ Back to Top ↑
+
diff --git a/SELF_HOST.md b/SELF_HOST.md
index 0642d70527..74848bca52 100644
--- a/SELF_HOST.md
+++ b/SELF_HOST.md
@@ -6,7 +6,7 @@ Welcome to [Firecrawl](https://firecrawl.dev) 🔥! Here are some instructions o
If you're contributing, note that the process is similar to other open-source repos, i.e., fork Firecrawl, make changes, run tests, PR.
-If you have any questions or would like help getting on board, join our Discord community [here](https://discord.gg/gSmWdAkdwd) for more information or submit an issue on Github [here](https://github.com/firecrawl/firecrawl/issues/new/choose)!
+If you have any questions or would like help getting on board, join our Discord community [here](https://discord.gg/firecrawl) for more information or submit an issue on Github [here](https://github.com/firecrawl/firecrawl/issues/new/choose)!
## Why?
diff --git a/apps/api/.gitignore b/apps/api/.gitignore
index 7efd97aede..1cc479f833 100644
--- a/apps/api/.gitignore
+++ b/apps/api/.gitignore
@@ -15,3 +15,7 @@ dump.rdb
firecrawl.log
test-results/
+
+# Branding script build artifacts (dev-only, generated at runtime)
+branding-script.pasteable.js
+bundle.generated.ts
diff --git a/apps/api/audit-ci.jsonc b/apps/api/audit-ci.jsonc
index 1ba12f29f3..5539375da1 100644
--- a/apps/api/audit-ci.jsonc
+++ b/apps/api/audit-ci.jsonc
@@ -1,17 +1,5 @@
{
"$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
"low": true,
- "allowlist": [
- "GHSA-33vc-wfww-vjfv|ai>jsondiffpatch", // we don't care about the HTML coming out of jsondiffpatch
- "GHSA-3gc7-fjrx-p6mg|@coinbase/x402>@coinbase/cdp-sdk>@solana/spl-token>@solana/buffer-layout-utils>bigint-buffer", // never gets called in our code paths
- "GHSA-qj3p-xc97-xw74|@coinbase/x402>x402>wagmi>@wagmi/connectors>@metamask/sdk", // we don't use the Metamask SDK in the browser
- "GHSA-qj3p-xc97-xw74|@coinbase/x402>x402>wagmi>@wagmi/connectors>@metamask/sdk>@metamask/sdk-communication-layer", // we don't use the Metamask SDK in the browser
- "GHSA-ffrw-9mx8-89p8|@coinbase/x402>x402>wagmi>@wagmi/connectors>@walletconnect/ethereum-provider>@reown/appkit>@reown/appkit-utils>@walletconnect/logger>pino>fast-redact", // unused
- "GHSA-m732-5p4w-x69g|@coinbase/x402>x402>wagmi>@wagmi/connectors>porto>hono", // we don't use hono
- "GHSA-q7jf-gf43-6x6p|@coinbase/x402>x402>wagmi>@wagmi/connectors>porto>hono", // we don't use hono
- "GHSA-rwvc-j5jr-mgvh|ai", // file upload vulnerability - not exposed in our usage
- "GHSA-5j98-mcp5-4vw2|jest>@jest/core>@jest/reporters>glob", // we do not use the glob CLI
- "GHSA-mh29-5h37-fv8m|@jest/globals>@jest/expect>jest-snapshot>@jest/transform>babel-plugin-istanbul>@istanbuljs/load-nyc-config>js-yaml", // not impacted by this
- "GHSA-mh29-5h37-fv8m|native>@napi-rs/cli>js-yaml" // not impacted by this
- ]
+ "allowlist": []
}
diff --git a/apps/api/knip.config.ts b/apps/api/knip.config.ts
index ada00cb169..94f57cd5f2 100644
--- a/apps/api/knip.config.ts
+++ b/apps/api/knip.config.ts
@@ -9,14 +9,9 @@ const config: KnipConfig = {
},
ignore: [
"native/**",
- "src/services/search-index-db.ts", // WIP
- "src/lib/search-index-client.ts", // WIP
- ],
- ignoreDependencies: [
- "openai",
- "undici-types",
- "@pinecone-database/pinecone", // WIP
+ "src/scraper/scrapeURL/engines/fire-engine/branding-script/**",
],
+ ignoreDependencies: ["openai", "undici-types"],
};
export default config;
diff --git a/apps/api/native/Cargo.toml b/apps/api/native/Cargo.toml
index 3172bbb8f5..5626496dd1 100644
--- a/apps/api/native/Cargo.toml
+++ b/apps/api/native/Cargo.toml
@@ -12,7 +12,7 @@ crate-type = ["cdylib"]
chrono = { version = "0.4", features = ["serde"] }
kuchikiki = "0.8.2"
lol_html = "2.6.0"
-lopdf = "0.38.0"
+pdf-inspector = { git = "https://github.com/firecrawl/pdf-inspector", rev = "5ab92e0" }
maud = "0.27.0"
napi = { version = "3.0.0", features = ["serde-json", "tokio_rt"] }
napi-derive = "3.0.0"
@@ -27,6 +27,7 @@ texting_robots = "0.2.2"
url = "2.5.7"
zip = "5.0.0"
calamine = "0.26"
+cfb = "0.10"
tokio = "1.48.0"
[build-dependencies]
diff --git a/apps/api/native/src/document/providers/doc.rs b/apps/api/native/src/document/providers/doc.rs
new file mode 100644
index 0000000000..1c94b656b0
--- /dev/null
+++ b/apps/api/native/src/document/providers/doc.rs
@@ -0,0 +1,420 @@
+use crate::document::model::*;
+use crate::document::providers::DocumentProvider;
+use cfb::CompoundFile;
+use std::error::Error;
+use std::io::Cursor;
+use std::io::Read;
+
+pub struct DocProvider;
+
+impl DocProvider {
+ pub fn new() -> Self {
+ Self
+ }
+}
+
+impl DocumentProvider for DocProvider {
+ fn parse_buffer(&self, data: &[u8]) -> Result> {
+ let cursor = Cursor::new(data);
+ let mut cfb = CompoundFile::open(cursor)?;
+
+ let mut metadata = DocumentMetadata::default();
+
+ // Try to extract metadata from SummaryInformation stream
+ if let Ok(summary_info) = extract_summary_info(&mut cfb) {
+ metadata.title = summary_info.title;
+ metadata.author = summary_info.author;
+ }
+
+ // Extract text content from the document
+ let text_content = extract_text_content(&mut cfb)?;
+
+ // Convert the extracted text to document blocks
+ let blocks = text_to_blocks(&text_content);
+
+ Ok(Document {
+ blocks,
+ metadata,
+ notes: Vec::new(),
+ comments: Vec::new(),
+ })
+ }
+
+ fn name(&self) -> &'static str {
+ "doc"
+ }
+}
+
+#[derive(Default)]
+struct SummaryInfo {
+ title: Option,
+ author: Option,
+}
+
+fn extract_summary_info(
+ cfb: &mut CompoundFile,
+) -> Result> {
+ let mut info = SummaryInfo::default();
+
+ // Try to read the SummaryInformation stream
+ if let Ok(mut stream) = cfb.open_stream("\x05SummaryInformation") {
+ let mut buf = Vec::new();
+ stream.read_to_end(&mut buf)?;
+
+ // Parse the OLE property set stream to extract title and author
+ if let Some((title, author)) = parse_summary_info_stream(&buf) {
+ info.title = title;
+ info.author = author;
+ }
+ }
+
+ Ok(info)
+}
+
+fn parse_summary_info_stream(data: &[u8]) -> Option<(Option, Option)> {
+ // MS-OLEPS: Property Set Stream format
+ // This is a simplified parser that extracts strings from the property stream
+
+ if data.len() < 48 {
+ return None;
+ }
+
+ // Byte order mark at offset 0 should be 0xFFFE (little-endian)
+ if data.len() >= 2 && (data[0] != 0xFE || data[1] != 0xFF) {
+ return None;
+ }
+
+ let mut title: Option = None;
+ let mut author: Option = None;
+
+ // Extract readable strings from the property stream
+ let strings = extract_ascii_strings(data, 3);
+
+ // Filter out common non-title/author strings
+ let filtered: Vec<&str> = strings
+ .iter()
+ .map(|s| s.as_str())
+ .filter(|s| {
+ !s.contains("Microsoft")
+ && !s.contains("Normal")
+ && !s.contains("template")
+ && !s.starts_with("http")
+ && s.len() >= 2
+ && s.len() <= 200
+ })
+ .collect();
+
+ // Title and author are typically the first meaningful strings
+ if let Some(t) = filtered.first() {
+ title = Some(t.to_string());
+ }
+ if let Some(a) = filtered.get(1) {
+ author = Some(a.to_string());
+ }
+
+ Some((title, author))
+}
+
+fn extract_text_content(
+ cfb: &mut CompoundFile,
+) -> Result> {
+ // Try to read the WordDocument stream
+ if let Ok(mut stream) = cfb.open_stream("WordDocument") {
+ let mut doc_data = Vec::new();
+ stream.read_to_end(&mut doc_data)?;
+
+ // Extract text from the WordDocument stream
+ if let Some(text) = extract_text_from_word_document(&doc_data) {
+ if !text.trim().is_empty() {
+ return Ok(text);
+ }
+ }
+ }
+
+ // Fallback: scan all streams for text
+ extract_text_fallback(cfb)
+}
+
+fn extract_text_from_word_document(doc_data: &[u8]) -> Option {
+ if doc_data.len() < 32 {
+ return None;
+ }
+
+ // Check for Word magic number (0xA5EC for Word 97-2003, 0xA5DC for older)
+ let magic = u16::from_le_bytes([doc_data[0], doc_data[1]]);
+ if magic != 0xA5EC && magic != 0xA5DC {
+ return None;
+ }
+
+ // Read the FIB (File Information Block) to get text encoding info
+ // Bit 9 of flags (offset 0x0A) indicates which table stream to use
+ // But for text extraction, we'll use a more robust approach
+
+ // The FIB contains ccpText at offset 0x4C (character count of main text)
+ let ccp_text = if doc_data.len() > 0x50 {
+ u32::from_le_bytes([
+ doc_data[0x4C],
+ doc_data[0x4D],
+ doc_data[0x4E],
+ doc_data[0x4F],
+ ]) as usize
+ } else {
+ 0
+ };
+
+ // For complex documents, text may be in pieces. For simple ones, it's contiguous.
+ // Either way, we'll scan for text runs since the piece table parsing is complex.
+
+ // .doc files typically store text as CP1252 (single-byte) or UTF-16LE
+ // We'll try to detect which one by looking for patterns
+
+ // First, try to find substantial ASCII/CP1252 text runs
+ let ascii_text = extract_document_text_cp1252(doc_data, ccp_text);
+ if !ascii_text.trim().is_empty() && has_enough_words(&ascii_text, 10) {
+ return Some(ascii_text);
+ }
+
+ // If ASCII extraction didn't work well, try UTF-16LE
+ let utf16_text = extract_document_text_utf16(doc_data, ccp_text);
+ if !utf16_text.trim().is_empty() && has_enough_words(&utf16_text, 10) {
+ return Some(utf16_text);
+ }
+
+ // Return whichever has more content
+ if ascii_text.len() > utf16_text.len() {
+ Some(ascii_text)
+ } else if !utf16_text.is_empty() {
+ Some(utf16_text)
+ } else {
+ None
+ }
+}
+
+fn extract_document_text_cp1252(data: &[u8], expected_chars: usize) -> String {
+ // Find long runs of printable ASCII/CP1252 characters
+ // This works well for most .doc files where text is stored as single-byte
+ let mut text_runs: Vec = Vec::new();
+ let mut current_run = String::new();
+ let mut total_chars = 0;
+ let max_chars = if expected_chars > 0 && expected_chars < 10_000_000 {
+ expected_chars * 2 // Allow some extra for headers/footers
+ } else {
+ 10_000_000
+ };
+
+ for &byte in data.iter() {
+ if total_chars >= max_chars {
+ break;
+ }
+
+ let ch = decode_cp1252(byte);
+
+ if is_text_char(ch) {
+ current_run.push(ch);
+ } else if byte == 0x0D || byte == 0x0A {
+ // Carriage return or line feed - end of paragraph
+ if current_run.len() >= 20 && has_word_chars(¤t_run) {
+ text_runs.push(current_run.clone());
+ total_chars += current_run.len();
+ }
+ current_run.clear();
+ } else if byte == 0x09 {
+ // Tab
+ current_run.push('\t');
+ } else {
+ // Non-text byte - might be end of a text run
+ if current_run.len() >= 20 && has_word_chars(¤t_run) {
+ text_runs.push(current_run.clone());
+ total_chars += current_run.len();
+ }
+ current_run.clear();
+ }
+ }
+
+ // Don't forget the last run
+ if current_run.len() >= 20 && has_word_chars(¤t_run) {
+ text_runs.push(current_run);
+ }
+
+ // Join text runs with newlines
+ text_runs.join("\n")
+}
+
+fn extract_document_text_utf16(data: &[u8], expected_chars: usize) -> String {
+ let mut text = String::new();
+ let max_chars = if expected_chars > 0 && expected_chars < 10_000_000 {
+ expected_chars * 2
+ } else {
+ 10_000_000
+ };
+
+ let mut i = 0;
+ let mut char_count = 0;
+ while i + 1 < data.len() && char_count < max_chars {
+ let code = u16::from_le_bytes([data[i], data[i + 1]]);
+
+ if let Some(ch) = char::from_u32(code as u32) {
+ if is_text_char(ch) || ch == '\r' || ch == '\n' || ch == '\t' {
+ if ch == '\r' {
+ text.push('\n');
+ } else {
+ text.push(ch);
+ }
+ char_count += 1;
+ }
+ }
+ i += 2;
+ }
+
+ // Filter to only keep substantial text portions
+ let lines: Vec<&str> = text
+ .lines()
+ .filter(|line| line.len() >= 10 && has_word_chars(line))
+ .collect();
+
+ lines.join("\n")
+}
+
+fn has_word_chars(s: &str) -> bool {
+ // Check if the string contains actual word characters (letters)
+ let letter_count = s.chars().filter(|c| c.is_alphabetic()).count();
+ let total_count = s.chars().count();
+ // At least 30% should be letters
+ letter_count > 0 && (letter_count * 100 / total_count.max(1)) >= 30
+}
+
+fn has_enough_words(s: &str, min_words: usize) -> bool {
+ s.split_whitespace().count() >= min_words
+}
+
+fn is_text_char(ch: char) -> bool {
+ // Printable character (not control chars, but allow some special ones)
+ (ch >= ' ' && ch != '\x7F') || ch == '\t'
+}
+
+fn extract_ascii_strings(data: &[u8], min_length: usize) -> Vec {
+ let mut strings = Vec::new();
+ let mut current = String::new();
+
+ for &byte in data {
+ let ch = decode_cp1252(byte);
+ if ch.is_ascii_graphic() || ch == ' ' {
+ current.push(ch);
+ } else {
+ if current.len() >= min_length {
+ strings.push(current.clone());
+ }
+ current.clear();
+ }
+ }
+
+ if current.len() >= min_length {
+ strings.push(current);
+ }
+
+ strings
+}
+
+fn extract_text_fallback(
+ cfb: &mut CompoundFile,
+) -> Result> {
+ let mut all_text = String::new();
+
+ // List all streams and try to extract text from each
+ let entries: Vec = cfb
+ .walk()
+ .filter(|e| e.is_stream())
+ .map(|e| e.path().to_string_lossy().to_string())
+ .collect();
+
+ for entry in entries {
+ // Skip known non-text streams
+ if entry.contains("CompObj")
+ || entry.contains("Data")
+ || entry.contains("ObjectPool")
+ || entry.contains("Pictures")
+ {
+ continue;
+ }
+
+ if let Ok(mut stream) = cfb.open_stream(&entry) {
+ let mut buf = Vec::new();
+ if stream.read_to_end(&mut buf).is_ok() {
+ let stream_text = extract_document_text_cp1252(&buf, 0);
+ if !stream_text.trim().is_empty() && has_enough_words(&stream_text, 5) {
+ if !all_text.is_empty() {
+ all_text.push('\n');
+ }
+ all_text.push_str(&stream_text);
+ }
+ }
+ }
+ }
+
+ Ok(all_text)
+}
+
+fn decode_cp1252(b: u8) -> char {
+ if b < 0x80 {
+ return b as char;
+ }
+ match b {
+ 0x80 => '\u{20AC}', // Euro sign
+ 0x82 => '\u{201A}', // Single low-9 quotation mark
+ 0x83 => '\u{0192}', // Latin small letter f with hook
+ 0x84 => '\u{201E}', // Double low-9 quotation mark
+ 0x85 => '\u{2026}', // Horizontal ellipsis
+ 0x86 => '\u{2020}', // Dagger
+ 0x87 => '\u{2021}', // Double dagger
+ 0x88 => '\u{02C6}', // Modifier letter circumflex accent
+ 0x89 => '\u{2030}', // Per mille sign
+ 0x8A => '\u{0160}', // Latin capital letter S with caron
+ 0x8B => '\u{2039}', // Single left-pointing angle quotation mark
+ 0x8C => '\u{0152}', // Latin capital ligature OE
+ 0x8E => '\u{017D}', // Latin capital letter Z with caron
+ 0x91 => '\u{2018}', // Left single quotation mark
+ 0x92 => '\u{2019}', // Right single quotation mark
+ 0x93 => '\u{201C}', // Left double quotation mark
+ 0x94 => '\u{201D}', // Right double quotation mark
+ 0x95 => '\u{2022}', // Bullet
+ 0x96 => '\u{2013}', // En dash
+ 0x97 => '\u{2014}', // Em dash
+ 0x98 => '\u{02DC}', // Small tilde
+ 0x99 => '\u{2122}', // Trade mark sign
+ 0x9A => '\u{0161}', // Latin small letter s with caron
+ 0x9B => '\u{203A}', // Single right-pointing angle quotation mark
+ 0x9C => '\u{0153}', // Latin small ligature oe
+ 0x9E => '\u{017E}', // Latin small letter z with caron
+ 0x9F => '\u{0178}', // Latin capital letter Y with diaeresis
+ _ => char::from_u32(b as u32).unwrap_or('?'),
+ }
+}
+
+fn text_to_blocks(text: &str) -> Vec {
+ let mut blocks = Vec::new();
+
+ // Split text into paragraphs and create blocks
+ for paragraph in text.split('\n') {
+ let trimmed = paragraph.trim();
+ if trimmed.is_empty() {
+ continue;
+ }
+
+ // Clean up the text - remove control characters except tabs
+ let cleaned: String = trimmed
+ .chars()
+ .filter(|c| !c.is_control() || *c == '\t')
+ .collect();
+
+ if cleaned.is_empty() {
+ continue;
+ }
+
+ blocks.push(Block::Paragraph(Paragraph {
+ kind: ParagraphKind::Normal,
+ inlines: vec![Inline::Text(cleaned)],
+ }));
+ }
+
+ blocks
+}
diff --git a/apps/api/native/src/document/providers/factory.rs b/apps/api/native/src/document/providers/factory.rs
index 9fc935bc4e..e9b98480f8 100644
--- a/apps/api/native/src/document/providers/factory.rs
+++ b/apps/api/native/src/document/providers/factory.rs
@@ -1,3 +1,4 @@
+use super::doc::DocProvider;
use super::docx::DocxProvider;
use super::odt::OdtProvider;
use super::rtf::RtfProvider;
@@ -8,6 +9,7 @@ use napi_derive::napi;
#[napi]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DocumentType {
+ Doc,
Docx,
Rtf,
Odt,
@@ -15,6 +17,7 @@ pub enum DocumentType {
}
pub struct ProviderFactory {
+ doc_provider: DocProvider,
docx_provider: DocxProvider,
rtf_provider: RtfProvider,
odt_provider: OdtProvider,
@@ -24,6 +27,7 @@ pub struct ProviderFactory {
impl ProviderFactory {
pub fn new() -> Self {
Self {
+ doc_provider: DocProvider::new(),
docx_provider: DocxProvider::new(),
rtf_provider: RtfProvider::new(),
odt_provider: OdtProvider::new(),
@@ -33,6 +37,7 @@ impl ProviderFactory {
pub fn get_provider(&self, doc_type: DocumentType) -> &dyn DocumentProvider {
match doc_type {
+ DocumentType::Doc => &self.doc_provider,
DocumentType::Docx => &self.docx_provider,
DocumentType::Rtf => &self.rtf_provider,
DocumentType::Odt => &self.odt_provider,
diff --git a/apps/api/native/src/document/providers/mod.rs b/apps/api/native/src/document/providers/mod.rs
index 67899c7412..645d0fdba2 100644
--- a/apps/api/native/src/document/providers/mod.rs
+++ b/apps/api/native/src/document/providers/mod.rs
@@ -1,6 +1,7 @@
use crate::document::model::Document;
use std::error::Error;
+pub mod doc;
pub mod docx;
pub mod factory;
pub mod odt;
diff --git a/apps/api/native/src/html.rs b/apps/api/native/src/html.rs
index db6505dd47..d0cd70a573 100644
--- a/apps/api/native/src/html.rs
+++ b/apps/api/native/src/html.rs
@@ -292,6 +292,22 @@ fn _extract_metadata(
}
}
+ // Backfill title from og:title, twitter:title, or meta[name="title"] if primary extraction failed
+ if !out.contains_key("title") {
+ let fallback_title = out
+ .get("ogTitle")
+ .or_else(|| out.get("og:title"))
+ .or_else(|| out.get("twitter:title"))
+ .and_then(|v| match v {
+ Value::String(s) if !s.is_empty() => Some(s.clone()),
+ _ => None,
+ });
+
+ if let Some(title) = fallback_title {
+ out.insert("title".to_string(), Value::String(title));
+ }
+ }
+
Ok(out)
}
diff --git a/apps/api/native/src/pdf.rs b/apps/api/native/src/pdf.rs
index 67f64de42c..14a6801855 100644
--- a/apps/api/native/src/pdf.rs
+++ b/apps/api/native/src/pdf.rs
@@ -1,56 +1,67 @@
use napi::bindgen_prelude::*;
use napi_derive::napi;
-use serde::Serialize;
+use pdf_inspector::{
+ PdfOptions, PdfType,
+ process_pdf_with_options as rust_process_pdf,
+};
-#[derive(Debug, Clone, Serialize)]
#[napi(object)]
-pub struct PDFMetadata {
- pub num_pages: i32,
- #[serde(skip_serializing_if = "Option::is_none")]
+pub struct PdfProcessResult {
+ pub pdf_type: String,
+ pub markdown: Option,
+ pub page_count: i32,
+ pub processing_time_ms: f64,
+ pub pages_needing_ocr: Vec,
pub title: Option,
+ pub confidence: f64,
+ pub is_complex: bool,
}
-fn _get_pdf_metadata(path: &str) -> std::result::Result {
- let doc = match lopdf::Document::load(path) {
- Ok(x) => x,
- Err(_) => {
- return Err("Failed to load PDF".to_string());
- }
- };
+fn pdf_type_str(t: PdfType) -> &'static str {
+ match t {
+ PdfType::TextBased => "TextBased",
+ PdfType::Scanned => "Scanned",
+ PdfType::ImageBased => "ImageBased",
+ PdfType::Mixed => "Mixed",
+ }
+}
- let num_pages = doc.get_pages().len() as i32;
+fn to_napi_result(result: pdf_inspector::PdfProcessResult) -> PdfProcessResult {
+ PdfProcessResult {
+ pdf_type: pdf_type_str(result.pdf_type).to_string(),
+ markdown: result.markdown,
+ page_count: result.page_count as i32,
+ processing_time_ms: result.processing_time_ms as f64,
+ pages_needing_ocr: result.pages_needing_ocr.iter().map(|&p| p as i32).collect(),
+ title: result.title,
+ confidence: result.confidence as f64,
+ is_complex: result.layout.is_complex,
+ }
+}
- let title = doc
- .trailer
- .get(b"Info")
- .and_then(|info| {
- info
- .as_dict()
- .and_then(|info| info.get(b"Title"))
- .and_then(lopdf::decode_text_string)
- })
- .ok()
- .or_else(|| {
- doc.objects.iter().find_map(|(_i, obj)| {
- obj
- .as_dict()
- .and_then(|obj| obj.get(b"Title"))
- .and_then(lopdf::decode_text_string)
- .ok()
- })
- })
- .map(|x| x.trim().to_string());
+/// Process a PDF file: detect type, extract text + markdown if text-based.
+#[napi]
+pub fn process_pdf(path: String) -> Result {
+ let result = rust_process_pdf(&path, PdfOptions::new()).map_err(|e| {
+ Error::new(
+ Status::GenericFailure,
+ format!("Failed to process PDF: {e}"),
+ )
+ })?;
- Ok(PDFMetadata { num_pages, title })
+ Ok(to_napi_result(result))
}
-/// Extract metadata from PDF file.
+/// Fast metadata-only detection: page count, title, type, confidence.
+/// Skips text extraction, markdown generation, and layout analysis.
#[napi]
-pub fn get_pdf_metadata(path: String) -> Result {
- _get_pdf_metadata(&path).map_err(|e| {
+pub fn detect_pdf(path: String) -> Result {
+ let result = rust_process_pdf(&path, PdfOptions::detect_only()).map_err(|e| {
Error::new(
Status::GenericFailure,
- format!("Failed to get PDF metadata: {e}"),
+ format!("Failed to detect PDF: {e}"),
)
- })
+ })?;
+
+ Ok(to_napi_result(result))
}
diff --git a/apps/api/openapi.json b/apps/api/openapi.json
index 3b759eeac0..8c6c8771c9 100644
--- a/apps/api/openapi.json
+++ b/apps/api/openapi.json
@@ -2366,8 +2366,8 @@
},
"proxy": {
"type": "string",
- "enum": ["basic", "stealth", "auto"],
- "description": "Specifies the type of proxy to use.\n\n - **basic**: Proxies for scraping sites with none to basic anti-bot solutions. Fast and usually works.\n - **stealth**: Stealth proxies for scraping sites with advanced anti-bot solutions. Slower, but more reliable on certain sites. Costs up to 5 credits per request.\n - **auto**: Firecrawl will automatically retry scraping with stealth proxies if the basic proxy fails. If the retry with stealth is successful, 5 credits will be billed for the scrape. If the first attempt with basic is successful, only the regular cost will be billed.\n\nIf you do not specify a proxy, Firecrawl will default to basic."
+ "enum": ["basic", "enhanced", "auto"],
+ "description": "Specifies the type of proxy to use.\n\n - **basic**: Proxies for scraping sites with none to basic anti-bot solutions. Fast and usually works.\n - **enhanced**: Enhanced proxies for scraping sites with advanced anti-bot solutions. Slower, but more reliable on certain sites. Costs up to 5 credits per request.\n - **auto**: Firecrawl will automatically retry scraping with enhanced proxies if the basic proxy fails. If the retry with enhanced is successful, 5 credits will be billed for the scrape. If the first attempt with basic is successful, only the regular cost will be billed.\n\nIf you do not specify a proxy, Firecrawl will default to basic."
},
"changeTrackingOptions": {
"type": "object",
diff --git a/apps/api/package.json b/apps/api/package.json
index 05d99a2f9d..bd162867e3 100644
--- a/apps/api/package.json
+++ b/apps/api/package.json
@@ -13,6 +13,7 @@
"flyio": "node dist/src/index.js",
"start:dev": "tsc-watch --onSuccess \"node dist/src/index.js\"",
"build": "tsc",
+ "branding:print": "node src/scraper/scrapeURL/engines/fire-engine/branding-script/print-script.js",
"build:nosentry": "tsc",
"test": "jest --testPathIgnorePatterns=\"src/__tests__/e2e_noAuth/*\"",
"test:local-no-auth": "jest --testPathIgnorePatterns=\"src/__tests__/e2e_withAuth/*\"",
@@ -26,13 +27,14 @@
"nuq-worker:production": "node dist/src/services/worker/nuq-worker.js",
"nuq-prefetch-worker": "tsc-watch --onSuccess \"node dist/src/services/worker/nuq-prefetch-worker.js\"",
"nuq-prefetch-worker:production": "node dist/src/services/worker/nuq-prefetch-worker.js",
+ "nuq-reconciler-worker": "tsc-watch --onSuccess \"node dist/src/services/worker/nuq-reconciler-worker.js\"",
+ "nuq-reconciler-worker:production": "node dist/src/services/worker/nuq-reconciler-worker.js",
"extract-worker": "tsc-watch --onSuccess \"node dist/src/services/extract-worker.js\"",
"extract-worker:production": "node dist/src/services/extract-worker.js",
"index-worker": "tsc-watch --onSuccess \"node dist/src/services/indexing/index-worker.js\"",
"index-worker:production": "node dist/src/services/indexing/index-worker.js",
"mongo-docker": "docker run -d -p 2717:27017 -v ./mongo-data:/data/db --name mongodb mongo:latest",
"mongo-docker-console": "docker exec -it mongodb mongosh",
- "run-example": "npx ts-node src/example.ts",
"sentry:sourcemaps": "sentry-cli sourcemaps inject --org caleb-peffer --project firecrawl-scraper-js ./dist && sentry-cli sourcemaps upload --org caleb-peffer --project firecrawl-scraper-js ./dist",
"prepare": "cd ../.. && husky ./apps/api/.husky",
"knip": "knip"
@@ -54,6 +56,7 @@
"@types/node": "^22.19.1",
"@types/pdf-parse": "^1.1.4",
"@types/pg": "^8.15.5",
+ "@types/qs": "^6.14.0",
"@types/supertest": "^6.0.2",
"@types/tough-cookie": "^4.0.5",
"husky": "^9.1.7",
@@ -63,7 +66,6 @@
"lint-staged": "^16.1.6",
"supertest": "^6.3.3",
"ts-jest": "^29.4.5",
- "ts-node": "^10.9.1",
"tsc-watch": "^7.1.1",
"tsx": "^4.20.3",
"typescript": "^5.8.3",
@@ -80,21 +82,23 @@
"@apidevtools/json-schema-ref-parser": "^15.1.2",
"@bull-board/api": "^6.14.0",
"@bull-board/express": "^6.14.0",
- "@coinbase/x402": "^0.6.6",
"@dqbd/tiktoken": "^1.0.22",
- "@google-cloud/storage": "^7.16.0",
+ "@google-cloud/storage": "^7.18.0",
"@mendable/firecrawl-rs": "workspace:*",
"@openrouter/ai-sdk-provider": "^0.4.5",
"@sentry/cli": "^2.58.2",
"@sentry/node": "^10.27.0",
"@supabase/supabase-js": "^2.52.0",
"@types/ws": "^8.5.12",
+ "@x402/core": "^2.4.0",
+ "@x402/evm": "^2.4.0",
+ "@x402/express": "^2.4.0",
"ai": "5.0.89",
- "ajv": "^8.16.0",
+ "ajv": "^8.18.0",
"ajv-formats": "^3.0.1",
"amqplib": "^0.10.9",
"async-mutex": "^0.5.0",
- "axios": "^1.12.2",
+ "axios": "^1.13.5",
"body-parser": "^1.20.3",
"bullmq": "^5.56.7",
"cacheable-lookup": "^6.1.0",
@@ -102,6 +106,7 @@
"cors": "^2.8.5",
"culori": "^4.0.2",
"dotenv": "^16.3.1",
+ "esbuild": "^0.27.2",
"escape-html": "^1.0.3",
"express": "4.22.0",
"express-ws": "^5.0.2",
@@ -113,7 +118,7 @@
"joplin-turndown-plugin-gfm": "^1.0.12",
"jsdom": "^26.0.0",
"koffi": "^2.9.0",
- "lodash": "^4.17.21",
+ "lodash": "^4.17.23",
"marked": "^14.1.2",
"ollama-ai-provider": "^1.2.0",
"openai": "^5.20.2",
@@ -123,21 +128,21 @@
"prettier": "^3.6.2",
"prom-client": "^15.1.3",
"psl": "^1.15.0",
+ "qs": "^6.15.0",
"rate-limiter-flexible": "2.4.2",
"redlock": "5.0.0-beta.2",
"resend": "^3.5.0",
"response-time": "^2.3.4",
"robots-parser": "^3.0.1",
"stripe": "^16.1.0",
- "systeminformation": "^5.27.14",
+ "systeminformation": "^5.31.0",
"tldts": "^6.1.75",
"tough-cookie": "^4.1.4",
"turndown": "^7.1.3",
- "undici": "^7.10.0",
+ "undici": "^7.18.2",
"uuid": "^13.0.0",
"winston": "^3.14.2",
"ws": "^8.18.0",
- "x402-express": "^0.6.5",
"xml2js": "^0.6.2",
"zod": "4.1.12"
},
@@ -150,16 +155,15 @@
},
"pnpm": {
"allowScripts": {
- "@coinbase/x402": true,
"oxc-resolver": true
},
"onlyBuiltDependencies": [
- "@coinbase/x402",
"@mendable/firecrawl-rs",
"@sentry-internal/node-cpu-profiler",
"@sentry/cli",
"bigint-buffer",
"bufferutil",
+ "four-flap-bigint-buffer",
"esbuild",
"keccak",
"koffi",
@@ -172,11 +176,16 @@
"wordpos"
],
"overrides": {
- "brace-expansion@>=2.0.0 <=2.0.1": "2.0.2",
- "debug": ">=4.4.3",
- "express@>=4.0.0 <4.22.0": "4.22.0",
- "jws": "4.0.1",
- "qs": ">=6.14.1"
+ "bigint-buffer": "npm:four-flap-bigint-buffer@1.1.6",
+ "diff": "^8.0.3",
+ "ajv": "^8.18.0",
+ "fast-xml-parser": "^5.3.8",
+ "glob@>=10.2.0 <10.5.0": ">=10.5.0",
+ "js-yaml@<3.14.2": ">=3.14.2",
+ "qs@<6.14.2": ">=6.14.2",
+ "minimatch@<10.2.3": ">=10.2.3",
+ "bn.js@<5.2.3": ">=5.2.3",
+ "@tootallnate/once@<3.0.1": ">=3.0.1"
}
},
"lint-staged": {
diff --git a/apps/api/pnpm-lock.yaml b/apps/api/pnpm-lock.yaml
index 9dc2c0b091..3e55f106cc 100644
--- a/apps/api/pnpm-lock.yaml
+++ b/apps/api/pnpm-lock.yaml
@@ -6,11 +6,16 @@ settings:
injectWorkspacePackages: true
overrides:
- brace-expansion@>=2.0.0 <=2.0.1: 2.0.2
- debug: '>=4.4.3'
- express@>=4.0.0 <4.22.0: 4.22.0
- jws: 4.0.1
- qs: '>=6.14.1'
+ bigint-buffer: npm:four-flap-bigint-buffer@1.1.6
+ diff: ^8.0.3
+ ajv: ^8.18.0
+ fast-xml-parser: ^5.3.8
+ glob@>=10.2.0 <10.5.0: '>=10.5.0'
+ js-yaml@<3.14.2: '>=3.14.2'
+ qs@<6.14.2: '>=6.14.2'
+ minimatch@<10.2.3: '>=10.2.3'
+ bn.js@<5.2.3: '>=5.2.3'
+ '@tootallnate/once@<3.0.1': '>=3.0.1'
importers:
@@ -46,15 +51,12 @@ importers:
'@bull-board/express':
specifier: ^6.14.0
version: 6.14.2
- '@coinbase/x402':
- specifier: ^0.6.6
- version: 0.6.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
'@dqbd/tiktoken':
specifier: ^1.0.22
version: 1.0.22
'@google-cloud/storage':
- specifier: ^7.16.0
- version: 7.16.0(encoding@0.1.13)
+ specifier: ^7.18.0
+ version: 7.18.0(encoding@0.1.13)
'@mendable/firecrawl-rs':
specifier: workspace:*
version: link:native
@@ -73,15 +75,24 @@ importers:
'@types/ws':
specifier: ^8.5.12
version: 8.5.12
+ '@x402/core':
+ specifier: ^2.4.0
+ version: 2.4.0
+ '@x402/evm':
+ specifier: ^2.4.0
+ version: 2.4.0(bufferutil@4.0.9)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.8.3)(utf-8-validate@5.0.10)
+ '@x402/express':
+ specifier: ^2.4.0
+ version: 2.4.0(bufferutil@4.0.9)(encoding@0.1.13)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(express@4.22.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
ai:
specifier: 5.0.89
version: 5.0.89(zod@4.1.12)
ajv:
- specifier: ^8.16.0
- version: 8.16.0
+ specifier: ^8.18.0
+ version: 8.18.0
ajv-formats:
specifier: ^3.0.1
- version: 3.0.1(ajv@8.16.0)
+ version: 3.0.1(ajv@8.18.0)
amqplib:
specifier: ^0.10.9
version: 0.10.9
@@ -89,8 +100,8 @@ importers:
specifier: ^0.5.0
version: 0.5.0
axios:
- specifier: ^1.12.2
- version: 1.12.2
+ specifier: ^1.13.5
+ version: 1.13.5
body-parser:
specifier: ^1.20.3
version: 1.20.3
@@ -112,6 +123,9 @@ importers:
dotenv:
specifier: ^16.3.1
version: 16.4.5
+ esbuild:
+ specifier: ^0.27.2
+ version: 0.27.2
escape-html:
specifier: ^1.0.3
version: 1.0.3
@@ -129,7 +143,7 @@ importers:
version: 2.0.6
http-cookie-agent:
specifier: ^7.0.1
- version: 7.0.1(tough-cookie@4.1.4)(undici@7.10.0)
+ version: 7.0.1(tough-cookie@4.1.4)(undici@7.18.2)
ioredis:
specifier: ^5.6.1
version: 5.6.1
@@ -146,8 +160,8 @@ importers:
specifier: ^2.9.0
version: 2.9.0
lodash:
- specifier: ^4.17.21
- version: 4.17.21
+ specifier: ^4.17.23
+ version: 4.17.23
marked:
specifier: ^14.1.2
version: 14.1.2
@@ -175,6 +189,9 @@ importers:
psl:
specifier: ^1.15.0
version: 1.15.0
+ qs:
+ specifier: ^6.15.0
+ version: 6.15.0
rate-limiter-flexible:
specifier: 2.4.2
version: 2.4.2
@@ -194,8 +211,8 @@ importers:
specifier: ^16.1.0
version: 16.1.0
systeminformation:
- specifier: ^5.27.14
- version: 5.27.14
+ specifier: ^5.31.0
+ version: 5.31.1
tldts:
specifier: ^6.1.75
version: 6.1.75
@@ -206,8 +223,8 @@ importers:
specifier: ^7.1.3
version: 7.2.0
undici:
- specifier: ^7.10.0
- version: 7.10.0
+ specifier: ^7.18.2
+ version: 7.18.2
uuid:
specifier: ^13.0.0
version: 13.0.0
@@ -217,9 +234,6 @@ importers:
ws:
specifier: ^8.18.0
version: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- x402-express:
- specifier: ^0.6.5
- version: 0.6.5(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
xml2js:
specifier: ^0.6.2
version: 0.6.2
@@ -269,6 +283,9 @@ importers:
'@types/pg':
specifier: ^8.15.5
version: 8.15.5
+ '@types/qs':
+ specifier: ^6.14.0
+ version: 6.14.0
'@types/supertest':
specifier: ^6.0.2
version: 6.0.2
@@ -295,10 +312,7 @@ importers:
version: 6.3.4
ts-jest:
specifier: ^29.4.5
- version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@30.2.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.8.3)))(typescript@5.8.3)
- ts-node:
- specifier: ^10.9.1
- version: 10.9.2(@types/node@22.19.1)(typescript@5.8.3)
+ version: 29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.27.2)(jest-util@30.2.0)(jest@30.2.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.8.3)))(typescript@5.8.3)
tsc-watch:
specifier: ^7.1.1
version: 7.1.1(typescript@5.8.3)
@@ -338,6 +352,9 @@ importers:
packages:
+ '@adraffy/ens-normalize@1.10.1':
+ resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==}
+
'@adraffy/ens-normalize@1.11.1':
resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==}
@@ -608,10 +625,6 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/runtime@7.28.2':
- resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==}
- engines: {node: '>=6.9.0'}
-
'@babel/runtime@7.28.4':
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
engines: {node: '>=6.9.0'}
@@ -628,9 +641,6 @@ packages:
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
engines: {node: '>=6.9.0'}
- '@base-org/account@1.1.1':
- resolution: {integrity: sha512-IfVJPrDPhHfqXRDb89472hXkpvJuQQR7FDI9isLPHEqSYt/45whIoBxSPgZ0ssTt379VhQo4+87PWI1DoLSfAQ==}
-
'@bcoe/v8-coverage@0.2.3':
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
@@ -648,15 +658,6 @@ packages:
'@coinbase/cdp-sdk@1.33.0':
resolution: {integrity: sha512-DqgPk/JednX4Tpi1a0EP7zEYi2EH9rsFULIkb8BbjuUUldTh4VCSp624JC3k6b2IJlibRD7oFHVnEAz2+ykSnw==}
- '@coinbase/wallet-sdk@3.9.3':
- resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==}
-
- '@coinbase/wallet-sdk@4.3.6':
- resolution: {integrity: sha512-4q8BNG1ViL4mSAAvPAtpwlOs1gpC+67eQtgIwNvT3xyeyFFd+guwkc8bcX5rTmQhXpqnhzC4f0obACbP9CqMSA==}
-
- '@coinbase/x402@0.6.6':
- resolution: {integrity: sha512-a/Z4TK7ijR8WOqVtNtcOy0PxPF9kt+0ytvTJuNxjbjM14JcW2bQx9L2/8X7DwpkSuXJG8L01cukWUrLrh6v4zw==}
-
'@colors/colors@1.6.0':
resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==}
engines: {node: '>=0.1.90'}
@@ -699,12 +700,6 @@ packages:
'@dqbd/tiktoken@1.0.22':
resolution: {integrity: sha512-RYhO8xeHkMNX5Ixqf4M1Ve3siCYJY/dI0yLnlX4M4oIEDOvjMIQ+E+3OUpAaZcWTaMtQJzGcDAghYfllpx3i/w==}
- '@ecies/ciphers@0.2.4':
- resolution: {integrity: sha512-t+iX+Wf5nRKyNzk8dviW3Ikb/280+aEJAnw9YXvCp2tYGPSkMki+NRY+8aNLmVFv3eNtMdvViPNOPxS8SZNP+w==}
- engines: {bun: '>=1', deno: '>=2', node: '>=16'}
- peerDependencies:
- '@noble/ciphers': ^1.0.0
-
'@emnapi/core@1.5.0':
resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==}
@@ -720,176 +715,311 @@ packages:
cpu: [ppc64]
os: [aix]
+ '@esbuild/aix-ppc64@0.27.2':
+ resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
'@esbuild/android-arm64@0.25.8':
resolution: {integrity: sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
+ '@esbuild/android-arm64@0.27.2':
+ resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
'@esbuild/android-arm@0.25.8':
resolution: {integrity: sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
+ '@esbuild/android-arm@0.27.2':
+ resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
'@esbuild/android-x64@0.25.8':
resolution: {integrity: sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
+ '@esbuild/android-x64@0.27.2':
+ resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
'@esbuild/darwin-arm64@0.25.8':
resolution: {integrity: sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
+ '@esbuild/darwin-arm64@0.27.2':
+ resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
'@esbuild/darwin-x64@0.25.8':
resolution: {integrity: sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
+ '@esbuild/darwin-x64@0.27.2':
+ resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
'@esbuild/freebsd-arm64@0.25.8':
resolution: {integrity: sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
+ '@esbuild/freebsd-arm64@0.27.2':
+ resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
'@esbuild/freebsd-x64@0.25.8':
resolution: {integrity: sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
+ '@esbuild/freebsd-x64@0.27.2':
+ resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
'@esbuild/linux-arm64@0.25.8':
resolution: {integrity: sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
+ '@esbuild/linux-arm64@0.27.2':
+ resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
'@esbuild/linux-arm@0.25.8':
resolution: {integrity: sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
+ '@esbuild/linux-arm@0.27.2':
+ resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
'@esbuild/linux-ia32@0.25.8':
resolution: {integrity: sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
+ '@esbuild/linux-ia32@0.27.2':
+ resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
'@esbuild/linux-loong64@0.25.8':
resolution: {integrity: sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
+ '@esbuild/linux-loong64@0.27.2':
+ resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
'@esbuild/linux-mips64el@0.25.8':
resolution: {integrity: sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
+ '@esbuild/linux-mips64el@0.27.2':
+ resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
'@esbuild/linux-ppc64@0.25.8':
resolution: {integrity: sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
+ '@esbuild/linux-ppc64@0.27.2':
+ resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
'@esbuild/linux-riscv64@0.25.8':
resolution: {integrity: sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
+ '@esbuild/linux-riscv64@0.27.2':
+ resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
'@esbuild/linux-s390x@0.25.8':
resolution: {integrity: sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
+ '@esbuild/linux-s390x@0.27.2':
+ resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
'@esbuild/linux-x64@0.25.8':
resolution: {integrity: sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
+ '@esbuild/linux-x64@0.27.2':
+ resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
'@esbuild/netbsd-arm64@0.25.8':
resolution: {integrity: sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
+ '@esbuild/netbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
'@esbuild/netbsd-x64@0.25.8':
resolution: {integrity: sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
+ '@esbuild/netbsd-x64@0.27.2':
+ resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
'@esbuild/openbsd-arm64@0.25.8':
resolution: {integrity: sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
+ '@esbuild/openbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
'@esbuild/openbsd-x64@0.25.8':
resolution: {integrity: sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
+ '@esbuild/openbsd-x64@0.27.2':
+ resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
'@esbuild/openharmony-arm64@0.25.8':
resolution: {integrity: sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
+ '@esbuild/openharmony-arm64@0.27.2':
+ resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
'@esbuild/sunos-x64@0.25.8':
resolution: {integrity: sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
+ '@esbuild/sunos-x64@0.27.2':
+ resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
'@esbuild/win32-arm64@0.25.8':
resolution: {integrity: sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
+ '@esbuild/win32-arm64@0.27.2':
+ resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
'@esbuild/win32-ia32@0.25.8':
resolution: {integrity: sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
+ '@esbuild/win32-ia32@0.27.2':
+ resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
'@esbuild/win32-x64@0.25.8':
resolution: {integrity: sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
- '@ethereumjs/common@3.2.0':
- resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==}
-
- '@ethereumjs/rlp@4.0.1':
- resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==}
- engines: {node: '>=14'}
- hasBin: true
-
- '@ethereumjs/tx@4.2.0':
- resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==}
- engines: {node: '>=14'}
-
- '@ethereumjs/util@8.1.0':
- resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==}
- engines: {node: '>=14'}
-
- '@gemini-wallet/core@0.2.0':
- resolution: {integrity: sha512-vv9aozWnKrrPWQ3vIFcWk7yta4hQW1Ie0fsNNPeXnjAxkbXr2hqMagEptLuMxpEP2W3mnRu05VDNKzcvAuuZDw==}
- peerDependencies:
- viem: '>=2.0.0'
+ '@esbuild/win32-x64@0.27.2':
+ resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
'@google-cloud/paginator@5.0.2':
resolution: {integrity: sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==}
@@ -903,8 +1033,8 @@ packages:
resolution: {integrity: sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==}
engines: {node: '>=14'}
- '@google-cloud/storage@7.16.0':
- resolution: {integrity: sha512-7/5LRgykyOfQENcm6hDKP8SX/u9XxE5YOiWOkgkwcoO+cG8xT/cyOvp9wwN3IxfdYgpHs8CE7Nq2PKX2lNaEXw==}
+ '@google-cloud/storage@7.18.0':
+ resolution: {integrity: sha512-r3ZwDMiz4nwW6R922Z1pwpePxyRwE5GdevYX63hRmAQUkUQJcBH/79EnQPDv5cOv1mFBgevdNWQfi3tie3dHrQ==}
engines: {node: '>=14'}
'@inquirer/checkbox@4.2.2':
@@ -1040,10 +1170,6 @@ packages:
'@ioredis/commands@1.2.0':
resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==}
- '@isaacs/cliui@8.0.2':
- resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
- engines: {node: '>=12'}
-
'@istanbuljs/load-nyc-config@1.1.0':
resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
engines: {node: '>=8'}
@@ -1144,9 +1270,6 @@ packages:
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
- '@jridgewell/sourcemap-codec@1.4.15':
- resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
-
'@jridgewell/sourcemap-codec@1.5.5':
resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
@@ -1156,92 +1279,6 @@ packages:
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
- '@lit-labs/ssr-dom-shim@1.4.0':
- resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==}
-
- '@lit/reactive-element@2.1.1':
- resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==}
-
- '@metamask/eth-json-rpc-provider@1.0.1':
- resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==}
- engines: {node: '>=14.0.0'}
-
- '@metamask/json-rpc-engine@7.3.3':
- resolution: {integrity: sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg==}
- engines: {node: '>=16.0.0'}
-
- '@metamask/json-rpc-engine@8.0.2':
- resolution: {integrity: sha512-IoQPmql8q7ABLruW7i4EYVHWUbF74yrp63bRuXV5Zf9BQwcn5H9Ww1eLtROYvI1bUXwOiHZ6qT5CWTrDc/t/AA==}
- engines: {node: '>=16.0.0'}
-
- '@metamask/json-rpc-middleware-stream@7.0.2':
- resolution: {integrity: sha512-yUdzsJK04Ev98Ck4D7lmRNQ8FPioXYhEUZOMS01LXW8qTvPGiRVXmVltj2p4wrLkh0vW7u6nv0mNl5xzC5Qmfg==}
- engines: {node: '>=16.0.0'}
-
- '@metamask/object-multiplex@2.1.0':
- resolution: {integrity: sha512-4vKIiv0DQxljcXwfpnbsXcfa5glMj5Zg9mqn4xpIWqkv6uJ2ma5/GtUfLFSxhlxnR8asRMv8dDmWya1Tc1sDFA==}
- engines: {node: ^16.20 || ^18.16 || >=20}
-
- '@metamask/onboarding@1.0.1':
- resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==}
-
- '@metamask/providers@16.1.0':
- resolution: {integrity: sha512-znVCvux30+3SaUwcUGaSf+pUckzT5ukPRpcBmy+muBLC0yaWnBcvDqGfcsw6CBIenUdFrVoAFa8B6jsuCY/a+g==}
- engines: {node: ^18.18 || >=20}
-
- '@metamask/rpc-errors@6.4.0':
- resolution: {integrity: sha512-1ugFO1UoirU2esS3juZanS/Fo8C8XYocCuBpfZI5N7ECtoG+zu0wF+uWZASik6CkO6w9n/Iebt4iI4pT0vptpg==}
- engines: {node: '>=16.0.0'}
-
- '@metamask/rpc-errors@7.0.2':
- resolution: {integrity: sha512-YYYHsVYd46XwY2QZzpGeU4PSdRhHdxnzkB8piWGvJW2xbikZ3R+epAYEL4q/K8bh9JPTucsUdwRFnACor1aOYw==}
- engines: {node: ^18.20 || ^20.17 || >=22}
-
- '@metamask/safe-event-emitter@2.0.0':
- resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==}
-
- '@metamask/safe-event-emitter@3.1.2':
- resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==}
- engines: {node: '>=12.0.0'}
-
- '@metamask/sdk-analytics@0.0.5':
- resolution: {integrity: sha512-fDah+keS1RjSUlC8GmYXvx6Y26s3Ax1U9hGpWb6GSY5SAdmTSIqp2CvYy6yW0WgLhnYhW+6xERuD0eVqV63QIQ==}
-
- '@metamask/sdk-communication-layer@0.33.1':
- resolution: {integrity: sha512-0bI9hkysxcfbZ/lk0T2+aKVo1j0ynQVTuB3sJ5ssPWlz+Z3VwveCkP1O7EVu1tsVVCb0YV5WxK9zmURu2FIiaA==}
- peerDependencies:
- cross-fetch: ^4.0.0
- eciesjs: '*'
- eventemitter2: ^6.4.9
- readable-stream: ^3.6.2
- socket.io-client: ^4.5.1
-
- '@metamask/sdk-install-modal-web@0.32.1':
- resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==}
-
- '@metamask/sdk@0.33.1':
- resolution: {integrity: sha512-1mcOQVGr9rSrVcbKPNVzbZ8eCl1K0FATsYH3WJ/MH4WcZDWGECWrXJPNMZoEAkLxWiMe8jOQBumg2pmcDa9zpQ==}
-
- '@metamask/superstruct@3.2.1':
- resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==}
- engines: {node: '>=16.0.0'}
-
- '@metamask/utils@11.8.1':
- resolution: {integrity: sha512-DIbsNUyqWLFgqJlZxi1OOCMYvI23GqFCvNJAtzv8/WXWzJfnJnvp1M24j7VvUe3URBi3S86UgQ7+7aWU9p/cnQ==}
- engines: {node: ^18.18 || ^20.14 || >=22}
-
- '@metamask/utils@5.0.2':
- resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==}
- engines: {node: '>=14.0.0'}
-
- '@metamask/utils@8.5.0':
- resolution: {integrity: sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ==}
- engines: {node: '>=16.0.0'}
-
- '@metamask/utils@9.3.0':
- resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==}
- engines: {node: '>=16.0.0'}
-
'@mixmark-io/domino@2.2.0':
resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==}
@@ -1628,49 +1665,25 @@ packages:
resolution: {integrity: sha512-enkZYyuCdo+9jneCPE/0fjIta4wWnvVN9hBo2HuiMpRF0q3lzv1J6b/cl7i0mxZUKhBrV3aCKDBQnCOhwKbPmQ==}
engines: {node: '>= 10'}
- '@noble/ciphers@1.2.1':
- resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==}
- engines: {node: ^14.21.3 || >=16}
-
'@noble/ciphers@1.3.0':
resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==}
engines: {node: ^14.21.3 || >=16}
- '@noble/curves@1.4.2':
- resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==}
-
- '@noble/curves@1.8.0':
- resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==}
- engines: {node: ^14.21.3 || >=16}
-
- '@noble/curves@1.8.1':
- resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==}
- engines: {node: ^14.21.3 || >=16}
+ '@noble/curves@1.2.0':
+ resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==}
'@noble/curves@1.9.1':
resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==}
engines: {node: ^14.21.3 || >=16}
- '@noble/curves@1.9.2':
- resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==}
- engines: {node: ^14.21.3 || >=16}
-
'@noble/curves@1.9.6':
resolution: {integrity: sha512-GIKz/j99FRthB8icyJQA51E8Uk5hXmdyThjgQXRKiv9h0zeRlzSCLIzFw6K1LotZ3XuB7yzlf76qk7uBmTdFqA==}
engines: {node: ^14.21.3 || >=16}
- '@noble/hashes@1.4.0':
- resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==}
+ '@noble/hashes@1.3.2':
+ resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
engines: {node: '>= 16'}
- '@noble/hashes@1.7.0':
- resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==}
- engines: {node: ^14.21.3 || >=16}
-
- '@noble/hashes@1.7.1':
- resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==}
- engines: {node: ^14.21.3 || >=16}
-
'@noble/hashes@1.8.0':
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
engines: {node: ^14.21.3 || >=16}
@@ -2092,14 +2105,6 @@ packages:
'@paralleldrive/cuid2@2.2.2':
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
- '@paulmillr/qr@0.2.1':
- resolution: {integrity: sha512-IHnV6A+zxU7XwmKFinmYjUcwlyK9+xkG3/s9KcQhI9BjQKycrJ1JRO+FbNYPwZiPKW3je/DR0k7w8/gLa5eaxQ==}
- deprecated: 'The package is now available as "qr": npm install qr'
-
- '@pkgjs/parseargs@0.11.0':
- resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
- engines: {node: '>=14'}
-
'@pkgr/core@0.2.9':
resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
@@ -2116,66 +2121,12 @@ packages:
react: ^18.2.0
react-dom: ^18.2.0
- '@reown/appkit-common@1.7.8':
- resolution: {integrity: sha512-ridIhc/x6JOp7KbDdwGKY4zwf8/iK8EYBl+HtWrruutSLwZyVi5P8WaZa+8iajL6LcDcDF7LoyLwMTym7SRuwQ==}
-
- '@reown/appkit-controllers@1.7.8':
- resolution: {integrity: sha512-IdXlJlivrlj6m63VsGLsjtPHHsTWvKGVzWIP1fXZHVqmK+rZCBDjCi9j267Rb9/nYRGHWBtlFQhO8dK35WfeDA==}
-
- '@reown/appkit-pay@1.7.8':
- resolution: {integrity: sha512-OSGQ+QJkXx0FEEjlpQqIhT8zGJKOoHzVnyy/0QFrl3WrQTjCzg0L6+i91Ad5Iy1zb6V5JjqtfIFpRVRWN4M3pw==}
-
- '@reown/appkit-polyfills@1.7.8':
- resolution: {integrity: sha512-W/kq786dcHHAuJ3IV2prRLEgD/2iOey4ueMHf1sIFjhhCGMynMkhsOhQMUH0tzodPqUgAC494z4bpIDYjwWXaA==}
-
- '@reown/appkit-scaffold-ui@1.7.8':
- resolution: {integrity: sha512-RCeHhAwOrIgcvHwYlNWMcIDibdI91waaoEYBGw71inE0kDB8uZbE7tE6DAXJmDkvl0qPh+DqlC4QbJLF1FVYdQ==}
-
- '@reown/appkit-ui@1.7.8':
- resolution: {integrity: sha512-1hjCKjf6FLMFzrulhl0Y9Vb9Fu4royE+SXCPSWh4VhZhWqlzUFc7kutnZKx8XZFVQH4pbBvY62SpRC93gqoHow==}
-
- '@reown/appkit-utils@1.7.8':
- resolution: {integrity: sha512-8X7UvmE8GiaoitCwNoB86pttHgQtzy4ryHZM9kQpvjQ0ULpiER44t1qpVLXNM4X35O0v18W0Dk60DnYRMH2WRw==}
- peerDependencies:
- valtio: 1.13.2
-
- '@reown/appkit-wallet@1.7.8':
- resolution: {integrity: sha512-kspz32EwHIOT/eg/ZQbFPxgXq0B/olDOj3YMu7gvLEFz4xyOFd/wgzxxAXkp5LbG4Cp++s/elh79rVNmVFdB9A==}
-
- '@reown/appkit@1.7.8':
- resolution: {integrity: sha512-51kTleozhA618T1UvMghkhKfaPcc9JlKwLJ5uV+riHyvSoWPKPRIa5A6M1Wano5puNyW0s3fwywhyqTHSilkaA==}
-
- '@safe-global/safe-apps-provider@0.18.6':
- resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==}
-
- '@safe-global/safe-apps-sdk@9.1.0':
- resolution: {integrity: sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==}
-
- '@safe-global/safe-gateway-typescript-sdk@3.23.1':
- resolution: {integrity: sha512-6ORQfwtEJYpalCeVO21L4XXGSdbEMfyp2hEv6cP82afKXSwvse6d3sdelgaPWUxHIsFRkWvHDdzh8IyyKHZKxw==}
- engines: {node: '>=16'}
-
- '@scure/base@1.1.9':
- resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==}
-
'@scure/base@1.2.6':
resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==}
- '@scure/bip32@1.4.0':
- resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==}
-
- '@scure/bip32@1.6.2':
- resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==}
-
'@scure/bip32@1.7.0':
resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==}
- '@scure/bip39@1.3.0':
- resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==}
-
- '@scure/bip39@1.5.4':
- resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==}
-
'@scure/bip39@1.6.0':
resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==}
@@ -2277,25 +2228,6 @@ packages:
'@sinonjs/fake-timers@13.0.5':
resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==}
- '@socket.io/component-emitter@3.1.2':
- resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==}
-
- '@solana-program/compute-budget@0.8.0':
- resolution: {integrity: sha512-qPKxdxaEsFxebZ4K5RPuy7VQIm/tfJLa1+Nlt3KNA8EYQkz9Xm8htdoEaXVrer9kpgzzp9R3I3Bh6omwCM06tQ==}
- peerDependencies:
- '@solana/kit': ^2.1.0
-
- '@solana-program/token-2022@0.4.2':
- resolution: {integrity: sha512-zIpR5t4s9qEU3hZKupzIBxJ6nUV5/UVyIT400tu9vT1HMs5JHxaTTsb5GUhYjiiTvNwU0MQavbwc4Dl29L0Xvw==}
- peerDependencies:
- '@solana/kit': ^2.1.0
- '@solana/sysvars': ^2.1.0
-
- '@solana-program/token@0.5.1':
- resolution: {integrity: sha512-bJvynW5q9SFuVOZ5vqGVkmaPGA0MCC+m9jgJj1nk5m20I389/ms69ASnhWGoOPNcie7S9OwBX0gTj2fiyWpfag==}
- peerDependencies:
- '@solana/kit': ^2.1.0
-
'@solana/accounts@2.3.0':
resolution: {integrity: sha512-QgQTj404Z6PXNOyzaOpSzjgMOuGwG8vC66jSDB+3zHaRcEPRVRd2sVSrd1U6sHtnV3aiaS6YyDuPQMheg4K2jw==}
engines: {node: '>=20.18.0'}
@@ -2581,6 +2513,21 @@ packages:
'@solana/web3.js@1.98.4':
resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==}
+ '@spruceid/siwe-parser@2.1.2':
+ resolution: {integrity: sha512-d/r3S1LwJyMaRAKQ0awmo9whfXeE88Qt00vRj91q5uv5ATtWIQEGJ67Yr5eSZw5zp1/fZCXZYuEckt8lSkereQ==}
+
+ '@stablelib/binary@1.0.1':
+ resolution: {integrity: sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==}
+
+ '@stablelib/int@1.0.1':
+ resolution: {integrity: sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==}
+
+ '@stablelib/random@1.0.2':
+ resolution: {integrity: sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==}
+
+ '@stablelib/wipe@1.0.1':
+ resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==}
+
'@standard-schema/spec@1.0.0':
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
@@ -2609,24 +2556,16 @@ packages:
'@swc/helpers@0.5.17':
resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==}
- '@tanstack/query-core@5.83.1':
- resolution: {integrity: sha512-OG69LQgT7jSp+5pPuCfzltq/+7l2xoweggjme9vlbCPa/d7D7zaqv5vN/S82SzSYZ4EDLTxNO1PWrv49RAS64Q==}
-
- '@tanstack/react-query@5.84.1':
- resolution: {integrity: sha512-zo7EUygcWJMQfFNWDSG7CBhy8irje/XY0RDVKKV4IQJAysb+ZJkkJPcnQi+KboyGUgT+SQebRFoTqLuTtfoDLw==}
- peerDependencies:
- react: ^18 || ^19
-
'@taplo/cli@0.7.0':
resolution: {integrity: sha512-Ck3zFhQhIhi02Hl6T4ZmJsXdnJE+wXcJz5f8klxd4keRYgenMnip3JDPMGDRLbnC/2iGd8P0sBIQqI3KxfVjBg==}
hasBin: true
- '@tootallnate/once@2.0.0':
- resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==}
+ '@tootallnate/once@3.0.1':
+ resolution: {integrity: sha512-VyMVKRrpHTT8PnotUeV8L/mDaMwD5DaAKCFLP73zAqAtvF0FCqky+Ki7BYbFCYQmqFyTe9316Ed5zS70QUR9eg==}
engines: {node: '>= 10'}
- '@tsconfig/node10@1.0.11':
- resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
+ '@tsconfig/node10@1.0.12':
+ resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==}
'@tsconfig/node12@1.0.11':
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
@@ -2676,9 +2615,6 @@ packages:
'@types/culori@4.0.1':
resolution: {integrity: sha512-43M51r/22CjhbOXyGT361GZ9vncSVQ39u62x5eJdBQFviI8zWp2X5jzqg7k4M6PVgDQAClpy2bUe2dtwEgEDVQ==}
- '@types/debug@4.1.12':
- resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
-
'@types/escape-html@1.0.4':
resolution: {integrity: sha512-qZ72SFTgUAZ5a7Tj6kf2SHLetiH5S6f8G5frB2SPQ3EyF02kxdyBFf4Tz4banE3xCgGnKgWLt//a6VuYHKYJTg==}
@@ -2712,18 +2648,12 @@ packages:
'@types/lodash@4.17.14':
resolution: {integrity: sha512-jsxagdikDiDBeIRaPYtArcT8my4tN1og7MtMRquFT3XNA6axxyHDRUemqDz/taRDdOUn0GnGHRCuff4q48sW9A==}
- '@types/lodash@4.17.20':
- resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==}
-
'@types/methods@1.1.4':
resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==}
'@types/mime@1.3.5':
resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
- '@types/ms@2.1.0':
- resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
-
'@types/mysql@2.15.27':
resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==}
@@ -2733,6 +2663,9 @@ packages:
'@types/node@22.19.1':
resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==}
+ '@types/node@22.7.5':
+ resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==}
+
'@types/node@24.10.1':
resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==}
@@ -2751,8 +2684,8 @@ packages:
'@types/phoenix@1.6.6':
resolution: {integrity: sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==}
- '@types/qs@6.9.15':
- resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==}
+ '@types/qs@6.14.0':
+ resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==}
'@types/range-parser@1.2.7':
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
@@ -2784,9 +2717,6 @@ packages:
'@types/triple-beam@1.3.5':
resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==}
- '@types/trusted-types@2.0.7':
- resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
-
'@types/uuid@8.3.4':
resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==}
@@ -2915,120 +2845,23 @@ packages:
resolution: {integrity: sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==}
engines: {node: '>= 20'}
- '@wagmi/connectors@5.11.2':
- resolution: {integrity: sha512-OkiElOI8xXGPDZE5UdG6NgDT3laSkEh9llX1DDapUnfnKecK3Tr/HUf5YzgwDhEoox8mdxp+8ZCjtnTKz56SdA==}
- peerDependencies:
- '@wagmi/core': 2.21.2
- typescript: '>=5.0.4'
- viem: 2.x
- peerDependenciesMeta:
- typescript:
- optional: true
-
- '@wagmi/core@2.21.2':
- resolution: {integrity: sha512-Rp4waam2z0FQUDINkJ91jq38PI5wFUHCv1YBL2LXzAQswaEk1ZY8d6+WG3vYGhFHQ22DXy2AlQ8IWmj+2EG3zQ==}
- peerDependencies:
- '@tanstack/query-core': '>=5.0.0'
- typescript: '>=5.0.4'
- viem: 2.x
- peerDependenciesMeta:
- '@tanstack/query-core':
- optional: true
- typescript:
- optional: true
-
- '@walletconnect/core@2.21.0':
- resolution: {integrity: sha512-o6R7Ua4myxR8aRUAJ1z3gT9nM+jd2B2mfamu6arzy1Cc6vi10fIwFWb6vg3bC8xJ6o9H3n/cN5TOW3aA9Y1XVw==}
- engines: {node: '>=18'}
-
- '@walletconnect/core@2.21.1':
- resolution: {integrity: sha512-Tp4MHJYcdWD846PH//2r+Mu4wz1/ZU/fr9av1UWFiaYQ2t2TPLDiZxjLw54AAEpMqlEHemwCgiRiAmjR1NDdTQ==}
- engines: {node: '>=18'}
-
- '@walletconnect/environment@1.0.1':
- resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==}
-
- '@walletconnect/ethereum-provider@2.21.1':
- resolution: {integrity: sha512-SSlIG6QEVxClgl1s0LMk4xr2wg4eT3Zn/Hb81IocyqNSGfXpjtawWxKxiC5/9Z95f1INyBD6MctJbL/R1oBwIw==}
- deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases'
-
- '@walletconnect/events@1.0.1':
- resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==}
-
- '@walletconnect/heartbeat@1.2.2':
- resolution: {integrity: sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==}
-
- '@walletconnect/jsonrpc-http-connection@1.0.8':
- resolution: {integrity: sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==}
+ '@x402/core@2.4.0':
+ resolution: {integrity: sha512-g4K5dAVjevQftxCcpFlUDjO2AHE43FkO43VxwLCQ8ET3ki4aj2fzCcgvnXEj2eloJoocFS/Evt4pSTnP/4cFJw==}
- '@walletconnect/jsonrpc-provider@1.0.14':
- resolution: {integrity: sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==}
+ '@x402/evm@2.4.0':
+ resolution: {integrity: sha512-k9qIEhJ5m8jZLPA44hcLEP9I1WC8nF375A7pX/3XGPA+H2UPUoY8fzBaQA2U+4lMv/eIyfz05klSj/8LzP1saA==}
- '@walletconnect/jsonrpc-types@1.0.4':
- resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==}
-
- '@walletconnect/jsonrpc-utils@1.0.8':
- resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==}
-
- '@walletconnect/jsonrpc-ws-connection@1.0.16':
- resolution: {integrity: sha512-G81JmsMqh5nJheE1mPst1W0WfVv0SG3N7JggwLLGnI7iuDZJq8cRJvQwLGKHn5H1WTW7DEPCo00zz5w62AbL3Q==}
-
- '@walletconnect/keyvaluestorage@1.1.1':
- resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==}
+ '@x402/express@2.4.0':
+ resolution: {integrity: sha512-ZnjAD/th0RsxsI15zwgbeFqKLitJJhdNRu9TPrJ0L6M2ZX1eDZb0fCtuCj0P+o7/qIoETeI8r/edYVlg4PFh+w==}
peerDependencies:
- '@react-native-async-storage/async-storage': 1.x
+ '@x402/paywall': 2.4.0
+ express: ^4.0.0 || ^5.0.0
peerDependenciesMeta:
- '@react-native-async-storage/async-storage':
+ '@x402/paywall':
optional: true
- '@walletconnect/logger@2.1.2':
- resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==}
-
- '@walletconnect/relay-api@1.0.11':
- resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==}
-
- '@walletconnect/relay-auth@1.1.0':
- resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==}
-
- '@walletconnect/safe-json@1.0.2':
- resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==}
-
- '@walletconnect/sign-client@2.21.0':
- resolution: {integrity: sha512-z7h+PeLa5Au2R591d/8ZlziE0stJvdzP9jNFzFolf2RG/OiXulgFKum8PrIyXy+Rg2q95U9nRVUF9fWcn78yBA==}
- deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases'
-
- '@walletconnect/sign-client@2.21.1':
- resolution: {integrity: sha512-QaXzmPsMnKGV6tc4UcdnQVNOz4zyXgarvdIQibJ4L3EmLat73r5ZVl4c0cCOcoaV7rgM9Wbphgu5E/7jNcd3Zg==}
- deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases'
-
- '@walletconnect/time@1.0.2':
- resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==}
-
- '@walletconnect/types@2.21.0':
- resolution: {integrity: sha512-ll+9upzqt95ZBWcfkOszXZkfnpbJJ2CmxMfGgE5GmhdxxxCcO5bGhXkI+x8OpiS555RJ/v/sXJYMSOLkmu4fFw==}
-
- '@walletconnect/types@2.21.1':
- resolution: {integrity: sha512-UeefNadqP6IyfwWC1Yi7ux+ljbP2R66PLfDrDm8izmvlPmYlqRerJWJvYO4t0Vvr9wrG4Ko7E0c4M7FaPKT/sQ==}
-
- '@walletconnect/universal-provider@2.21.0':
- resolution: {integrity: sha512-mtUQvewt+X0VBQay/xOJBvxsB3Xsm1lTwFjZ6WUwSOTR1X+FNb71hSApnV5kbsdDIpYPXeQUbGt2se1n5E5UBg==}
- deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases'
-
- '@walletconnect/universal-provider@2.21.1':
- resolution: {integrity: sha512-Wjx9G8gUHVMnYfxtasC9poGm8QMiPCpXpbbLFT+iPoQskDDly8BwueWnqKs4Mx2SdIAWAwuXeZ5ojk5qQOxJJg==}
- deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases'
-
- '@walletconnect/utils@2.21.0':
- resolution: {integrity: sha512-zfHLiUoBrQ8rP57HTPXW7rQMnYxYI4gT9yTACxVW6LhIFROTF6/ytm5SKNoIvi4a5nX5dfXG4D9XwQUCu8Ilig==}
-
- '@walletconnect/utils@2.21.1':
- resolution: {integrity: sha512-VPZvTcrNQCkbGOjFRbC24mm/pzbRMUq2DSQoiHlhh0X1U7ZhuIrzVtAoKsrzu6rqjz0EEtGxCr3K1TGRqDG4NA==}
-
- '@walletconnect/window-getters@1.0.1':
- resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==}
-
- '@walletconnect/window-metadata@1.0.1':
- resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==}
+ '@x402/extensions@2.4.0':
+ resolution: {integrity: sha512-tg/mSAS+NgwUaOdjt8agSjVkO1s9NYy+kSPubVlZf/Fy884qu7dSW81Ixu1NRYEz+vBk0rtz6b+eEvS0v72tMQ==}
abbrev@2.0.0:
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
@@ -3045,22 +2878,11 @@ packages:
zod:
optional: true
- abitype@1.0.8:
- resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==}
+ abitype@1.2.3:
+ resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==}
peerDependencies:
typescript: '>=5.0.4'
- zod: ^3 >=3.22.0
- peerDependenciesMeta:
- typescript:
- optional: true
- zod:
- optional: true
-
- abitype@1.1.1:
- resolution: {integrity: sha512-Loe5/6tAgsBukY95eGaPSDmQHIjRZYQq8PB1MpsNccDIK8WiV+Uw6WzaIXipvaxTEL2yEB0OpEaQv3gs8pkS9Q==}
- peerDependencies:
- typescript: '>=5.0.4'
- zod: ^3.22.0 || ^4.0.0
+ zod: ^3.22.0 || ^4.0.0
peerDependenciesMeta:
typescript:
optional: true
@@ -3080,20 +2902,18 @@ packages:
peerDependencies:
acorn: ^8
- acorn-walk@8.3.2:
- resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
+ acorn-walk@8.3.4:
+ resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
engines: {node: '>=0.4.0'}
- acorn@8.11.3:
- resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==}
- engines: {node: '>=0.4.0'}
- hasBin: true
-
acorn@8.15.0:
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
engines: {node: '>=0.4.0'}
hasBin: true
+ aes-js@4.0.0-beta.5:
+ resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==}
+
agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
@@ -3115,13 +2935,13 @@ packages:
ajv-formats@3.0.1:
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
peerDependencies:
- ajv: ^8.0.0
+ ajv: ^8.18.0
peerDependenciesMeta:
ajv:
optional: true
- ajv@8.16.0:
- resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==}
+ ajv@8.18.0:
+ resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
amqplib@0.10.9:
resolution: {integrity: sha512-jwSftI4QjS3mizvnSnOrPGYiUnm1vI2OP1iXeOUz5pb74Ua0nbf6nPyyTzuiCLEE3fMpaJORXh2K/TQ08H5xGA==}
@@ -3163,12 +2983,12 @@ packages:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
+ apg-js@4.4.0:
+ resolution: {integrity: sha512-fefmXFknJmtgtNEXfPwZKYkMFX4Fyeyz+fNF6JWp87biGOPslJbCBVU158zvKRZfHBKnJDy8CMM40oLFGkXT8Q==}
+
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
- argparse@1.0.10:
- resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
-
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@@ -3182,9 +3002,6 @@ packages:
asap@2.0.6:
resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
- async-mutex@0.2.6:
- resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==}
-
async-mutex@0.5.0:
resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==}
@@ -3200,21 +3017,13 @@ packages:
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
- atomic-sleep@1.0.0:
- resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
- engines: {node: '>=8.0.0'}
-
- available-typed-arrays@1.0.7:
- resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
- engines: {node: '>= 0.4'}
-
axios-retry@4.5.0:
resolution: {integrity: sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==}
peerDependencies:
axios: 0.x || 1.x
- axios@1.12.2:
- resolution: {integrity: sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==}
+ axios@1.13.5:
+ resolution: {integrity: sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==}
babel-jest@30.2.0:
resolution: {integrity: sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==}
@@ -3241,15 +3050,13 @@ packages:
peerDependencies:
'@babel/core': ^7.11.0 || ^8.0.0-beta.1
- balanced-match@1.0.2:
- resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ balanced-match@4.0.3:
+ resolution: {integrity: sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g==}
+ engines: {node: 20 || >=22}
base-x@3.0.11:
resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==}
- base-x@5.0.1:
- resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==}
-
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
@@ -3260,13 +3067,6 @@ packages:
before-after-hook@4.0.0:
resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==}
- big.js@6.2.2:
- resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==}
-
- bigint-buffer@1.1.5:
- resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==}
- engines: {node: '>= 10.0.0'}
-
bignumber.js@9.2.0:
resolution: {integrity: sha512-JocpCSOixzy5XFJi2ub6IMmV/G9i8Lrm2lZvwBv9xPdglmZM0ufDVBbjbrfU/zuLvBfD7Bv2eYxz9i+OHTgkew==}
deprecated: pkg version number incorrect
@@ -3277,8 +3077,8 @@ packages:
bintrees@1.0.2:
resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==}
- bn.js@5.2.2:
- resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==}
+ bn.js@5.2.3:
+ resolution: {integrity: sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==}
body-parser@1.20.3:
resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
@@ -3290,17 +3090,9 @@ packages:
borsh@0.7.0:
resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==}
- bowser@2.11.0:
- resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==}
-
- bowser@2.12.1:
- resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==}
-
- brace-expansion@1.1.12:
- resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
-
- brace-expansion@2.0.2:
- resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
+ brace-expansion@5.0.2:
+ resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==}
+ engines: {node: 20 || >=22}
braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
@@ -3318,9 +3110,6 @@ packages:
bs58@4.0.1:
resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==}
- bs58@6.0.0:
- resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==}
-
bser@2.1.1:
resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
@@ -3358,10 +3147,6 @@ packages:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
- call-bind@1.0.8:
- resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
- engines: {node: '>= 0.4'}
-
call-bound@1.0.4:
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
engines: {node: '>= 0.4'}
@@ -3410,10 +3195,6 @@ packages:
resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==}
engines: {node: '>= 6'}
- chokidar@4.0.3:
- resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
- engines: {node: '>= 14.16.0'}
-
ci-info@4.3.1:
resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==}
engines: {node: '>=8'}
@@ -3441,17 +3222,10 @@ packages:
peerDependencies:
typanion: '*'
- cliui@6.0.0:
- resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
-
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
- clsx@1.2.1:
- resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==}
- engines: {node: '>=6'}
-
cluster-key-slot@1.1.2:
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
engines: {node: '>=0.10.0'}
@@ -3510,9 +3284,6 @@ packages:
component-emitter@1.3.1:
resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==}
- concat-map@0.0.1:
- resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
-
config-chain@1.1.13:
resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
@@ -3527,9 +3298,6 @@ packages:
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
- cookie-es@1.2.2:
- resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==}
-
cookie-signature@1.0.6:
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
@@ -3540,9 +3308,6 @@ packages:
cookiejar@2.1.4:
resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==}
- core-util-is@1.0.3:
- resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
-
cors@2.8.5:
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
engines: {node: '>= 0.10'}
@@ -3550,11 +3315,6 @@ packages:
countries-list@3.1.1:
resolution: {integrity: sha512-nPklKJ5qtmY5MdBKw1NiBAoyx5Sa7p2yPpljZyQ7gyCN1m+eMFs9I6CT37Mxt8zvR5L3VzD3DJBE4WQzX3WF4A==}
- crc-32@1.2.2:
- resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
- engines: {node: '>=0.8'}
- hasBin: true
-
create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
@@ -3562,19 +3322,10 @@ packages:
resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==}
engines: {node: '>=12.0.0'}
- cross-fetch@3.1.8:
- resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==}
-
- cross-fetch@4.1.0:
- resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==}
-
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
- crossws@0.3.5:
- resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==}
-
crypt@0.0.2:
resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==}
@@ -3601,12 +3352,21 @@ packages:
resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==}
engines: {node: '>=18'}
- date-fns@2.30.0:
- resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
- engines: {node: '>=0.11'}
+ debug@2.6.9:
+ resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
- dayjs@1.11.13:
- resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
+ debug@3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
@@ -3617,17 +3377,9 @@ packages:
supports-color:
optional: true
- decamelize@1.2.0:
- resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
- engines: {node: '>=0.10.0'}
-
decimal.js@10.5.0:
resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==}
- decode-uri-component@0.2.2:
- resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==}
- engines: {node: '>=0.10'}
-
dedent@1.7.0:
resolution: {integrity: sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==}
peerDependencies:
@@ -3640,13 +3392,6 @@ packages:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
- define-data-property@1.1.4:
- resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
- engines: {node: '>= 0.4'}
-
- defu@6.1.4:
- resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
-
delay@5.0.0:
resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==}
engines: {node: '>=10'}
@@ -3663,21 +3408,10 @@ packages:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
- derive-valtio@0.1.0:
- resolution: {integrity: sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A==}
- peerDependencies:
- valtio: '*'
-
- destr@2.0.5:
- resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
-
destroy@1.2.0:
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
- detect-browser@5.3.0:
- resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==}
-
detect-libc@2.1.2:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
@@ -3689,17 +3423,10 @@ packages:
dezalgo@1.0.4:
resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==}
- diff@3.5.0:
- resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==}
+ diff@8.0.3:
+ resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==}
engines: {node: '>=0.3.1'}
- diff@4.0.2:
- resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
- engines: {node: '>=0.3.1'}
-
- dijkstrajs@1.0.3:
- resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
-
dom-serializer@2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
@@ -3727,16 +3454,9 @@ packages:
duplexify@4.1.3:
resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==}
- eastasianwidth@0.2.0:
- resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
-
ecdsa-sig-formatter@1.0.11:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
- eciesjs@0.4.15:
- resolution: {integrity: sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==}
- engines: {bun: '>=1', deno: '>=2', node: '>=16'}
-
editorconfig@1.0.4:
resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==}
engines: {node: '>=14'}
@@ -3771,15 +3491,9 @@ packages:
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
- emoji-regex@9.2.2:
- resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
-
enabled@2.0.0:
resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==}
- encode-utf8@1.0.3:
- resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==}
-
encodeurl@1.0.2:
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
engines: {node: '>= 0.8'}
@@ -3794,13 +3508,6 @@ packages:
end-of-stream@1.4.4:
resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
- engine.io-client@6.6.3:
- resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==}
-
- engine.io-parser@5.2.3:
- resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==}
- engines: {node: '>=10.0.0'}
-
entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
@@ -3812,10 +3519,6 @@ packages:
error-ex@1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
- es-define-property@1.0.0:
- resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
- engines: {node: '>= 0.4'}
-
es-define-property@1.0.1:
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
engines: {node: '>= 0.4'}
@@ -3832,9 +3535,6 @@ packages:
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
engines: {node: '>= 0.4'}
- es-toolkit@1.33.0:
- resolution: {integrity: sha512-X13Q/ZSc+vsO1q600bvNK4bxgXMkHcf//RxCmYDaRY5DAcT+eoXjY5hoAPGMdRnWQjvyLEcyauG3b6hz76LNqg==}
-
es-toolkit@1.39.10:
resolution: {integrity: sha512-E0iGnTtbDhkeczB0T+mxmoVlT4YNweEKBLq7oaU4p11mecdsZpNWOglI4895Vh4usbQ+LsJiuLuI2L0Vdmfm2w==}
@@ -3849,6 +3549,11 @@ packages:
engines: {node: '>=18'}
hasBin: true
+ esbuild@0.27.2:
+ resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
escalade@3.2.0:
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
engines: {node: '>=6'}
@@ -3864,32 +3569,14 @@ packages:
resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
engines: {node: '>=8'}
- esprima@4.0.1:
- resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
- engines: {node: '>=4'}
- hasBin: true
-
etag@1.8.1:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
- eth-block-tracker@7.1.0:
- resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==}
- engines: {node: '>=14.0.0'}
-
- eth-json-rpc-filters@6.0.1:
- resolution: {integrity: sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==}
+ ethers@6.16.0:
+ resolution: {integrity: sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==}
engines: {node: '>=14.0.0'}
- eth-query@2.1.2:
- resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==}
-
- eth-rpc-errors@4.0.3:
- resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==}
-
- ethereum-cryptography@2.2.1:
- resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==}
-
event-stream@3.3.4:
resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==}
@@ -3897,9 +3584,6 @@ packages:
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
engines: {node: '>=6'}
- eventemitter2@6.4.9:
- resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==}
-
eventemitter3@5.0.1:
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
@@ -3931,7 +3615,7 @@ packages:
resolution: {integrity: sha512-0uvmuk61O9HXgLhGl3QhNSEtRsQevtmbL94/eILaliEADZBHZOQUAiHFrGPrgsjikohyrmSG5g+sCfASTt0lkQ==}
engines: {node: '>=4.5.0'}
peerDependencies:
- express: 4.22.0
+ express: ^4.0.0 || ^5.0.0-alpha.1
express@4.22.0:
resolution: {integrity: sha512-c2iPh3xp5vvCLgaHK03+mWLFPhox7j1LwyxcZwFVApEv5i0X+IjPpbT50SJJwwLpdBVfp45AkK/v+AFgv/XlfQ==}
@@ -3940,10 +3624,6 @@ packages:
extend@3.0.2:
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
- extension-port-stream@3.0.0:
- resolution: {integrity: sha512-an2S5quJMiy5bnZKEf6AkfH/7r8CzHvhchU40gxN+OM6HPhe7Z9T1FUychcf2M9PpPOO0Hf7BAEfJkw2TDIBDw==}
- engines: {node: '>=12.0.0'}
-
eyes@0.1.8:
resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==}
engines: {node: '> 0.1.90'}
@@ -3964,18 +3644,20 @@ packages:
fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
- fast-redact@3.5.0:
- resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==}
- engines: {node: '>=6'}
-
fast-safe-stringify@2.1.1:
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
fast-stable-stringify@1.0.0:
resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==}
- fast-xml-parser@4.4.1:
- resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==}
+ fast-uri@3.1.0:
+ resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
+
+ fast-xml-builder@1.0.0:
+ resolution: {integrity: sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==}
+
+ fast-xml-parser@5.4.1:
+ resolution: {integrity: sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==}
hasBin: true
fastestsmallesttextencoderdecoder@1.0.22:
@@ -4010,10 +3692,6 @@ packages:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
- filter-obj@1.1.0:
- resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==}
- engines: {node: '>=0.10.0'}
-
finalhandler@1.3.1:
resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==}
engines: {node: '>= 0.8'}
@@ -4025,8 +3703,8 @@ packages:
fn.name@1.1.0:
resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==}
- follow-redirects@1.15.6:
- resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
+ follow-redirects@1.15.11:
+ resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
@@ -4034,14 +3712,6 @@ packages:
debug:
optional: true
- for-each@0.3.5:
- resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
- engines: {node: '>= 0.4'}
-
- foreground-child@3.2.1:
- resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==}
- engines: {node: '>=14'}
-
form-data@2.5.5:
resolution: {integrity: sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==}
engines: {node: '>= 0.12'}
@@ -4050,6 +3720,10 @@ packages:
resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==}
engines: {node: '>= 6'}
+ form-data@4.0.5:
+ resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
+ engines: {node: '>= 6'}
+
formatly@0.3.0:
resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==}
engines: {node: '>=18.3.0'}
@@ -4069,6 +3743,10 @@ packages:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
engines: {node: '>= 0.6'}
+ four-flap-bigint-buffer@1.1.6:
+ resolution: {integrity: sha512-hJOBnKk2e89/FCSXU0UN7B2CpMnqtN6RrIKzoG3qWSjLUXGCTEU86aTdNEio/1Eu2NyExIAVJUyHuZvmEA9iuw==}
+ engines: {node: '>= 10.0.0'}
+
fresh@0.5.2:
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
engines: {node: '>= 0.6'}
@@ -4146,14 +3824,13 @@ packages:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
- glob@10.4.2:
- resolution: {integrity: sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==}
- engines: {node: '>=16 || 14 >=14.18'}
- hasBin: true
+ glob@13.0.1:
+ resolution: {integrity: sha512-B7U/vJpE3DkJ5WXTgTpTRN63uV42DseiXXKMwG14LQBXmsdeIoHAPbU/MEo6II0k5ED74uc2ZGTC6MwHFQhF6w==}
+ engines: {node: 20 || >=22}
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
- deprecated: Glob versions prior to v9 are no longer supported
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
google-auth-library@10.5.0:
resolution: {integrity: sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==}
@@ -4171,9 +3848,6 @@ packages:
resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==}
engines: {node: '>=14'}
- gopd@1.0.1:
- resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
-
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
@@ -4189,9 +3863,6 @@ packages:
resolution: {integrity: sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==}
engines: {node: '>=18'}
- h3@1.15.4:
- resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==}
-
handlebars@4.7.8:
resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==}
engines: {node: '>=0.4.7'}
@@ -4205,9 +3876,6 @@ packages:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
- has-property-descriptors@1.0.2:
- resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
-
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
@@ -4220,10 +3888,6 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
- hono@4.9.10:
- resolution: {integrity: sha512-AlI15ijFyKTXR7eHo7QK7OR4RoKIedZvBuRjO8iy4zrxvlY5oFCdiRG/V/lFJHCNXJ0k72ATgnyzx8Yqa5arug==}
- engines: {node: '>=16.9.0'}
-
html-encoding-sniffer@4.0.0:
resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
engines: {node: '>=18'}
@@ -4291,12 +3955,6 @@ packages:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
- idb-keyval@6.2.1:
- resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==}
-
- idb-keyval@6.2.2:
- resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==}
-
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
@@ -4342,13 +4000,6 @@ packages:
resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==}
engines: {node: '>= 10'}
- iron-webcrypto@1.2.1:
- resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
-
- is-arguments@1.2.0:
- resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==}
- engines: {node: '>= 0.4'}
-
is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
@@ -4358,10 +4009,6 @@ packages:
is-buffer@1.1.6:
resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
- is-callable@1.2.7:
- resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
- engines: {node: '>= 0.4'}
-
is-core-module@2.13.1:
resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
@@ -4385,10 +4032,6 @@ packages:
resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
engines: {node: '>=6'}
- is-generator-function@1.1.0:
- resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==}
- engines: {node: '>= 0.4'}
-
is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
@@ -4400,10 +4043,6 @@ packages:
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
- is-regex@1.2.1:
- resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
- engines: {node: '>= 0.4'}
-
is-retry-allowed@2.2.0:
resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==}
engines: {node: '>=10'}
@@ -4412,16 +4051,6 @@ packages:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
engines: {node: '>=8'}
- is-typed-array@1.1.15:
- resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
- engines: {node: '>= 0.4'}
-
- isarray@1.0.0:
- resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
-
- isarray@2.0.5:
- resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
-
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
@@ -4434,11 +4063,6 @@ packages:
peerDependencies:
ws: '*'
- isows@1.0.6:
- resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==}
- peerDependencies:
- ws: '*'
-
isows@1.0.7:
resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==}
peerDependencies:
@@ -4464,10 +4088,6 @@ packages:
resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==}
engines: {node: '>=8'}
- jackspeak@3.4.0:
- resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==}
- engines: {node: '>=14'}
-
jake@10.9.1:
resolution: {integrity: sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==}
engines: {node: '>=10'}
@@ -4632,10 +4252,6 @@ packages:
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
- js-yaml@3.14.1:
- resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
- hasBin: true
-
js-yaml@4.1.1:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
@@ -4667,13 +4283,6 @@ packages:
resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==}
engines: {node: ^18.17.0 || >=20.5.0}
- json-rpc-engine@6.1.0:
- resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==}
- engines: {node: '>=10.0.0'}
-
- json-rpc-random-id@1.0.1:
- resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==}
-
json-schema-traverse@1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
@@ -4694,13 +4303,6 @@ packages:
jws@4.0.1:
resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==}
- keccak@3.0.4:
- resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==}
- engines: {node: '>=10.0.0'}
-
- keyvaluestorage-interface@1.0.0:
- resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==}
-
knip@5.70.1:
resolution: {integrity: sha512-tGRjOivkHPV+YoVVDz0oKSlvCAY6d009Mlhufs4Y+7VWl/Ky073+KURcrgMLzJVy4pkpZvoxYu3wmC0gK7XS5g==}
engines: {node: '>=18.18.0'}
@@ -4722,8 +4324,8 @@ packages:
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
engines: {node: '>=6'}
- libpq@1.8.15:
- resolution: {integrity: sha512-4lSWmly2Nsj3LaTxxtFmJWuP3Kx+0hYHEd+aNrcXEWT0nKWaPd9/QZPiMkkC680zeALFGHQdQWjBvnilL+vgWA==}
+ libpq@1.9.0:
+ resolution: {integrity: sha512-/o/IlSJqHiwD5UoGUQnl/vxSEdsGEteuLyAQ1gYsZ/e/vqOP3E1AXp+4iqaGNYQJ+OVLb55iRiNv2Gml8usHrg==}
lilconfig@3.1.3:
resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
@@ -4741,15 +4343,6 @@ packages:
resolution: {integrity: sha512-0aeh5HHHgmq1KRdMMDHfhMWQmIT/m7nRDTlxlFqni2Sp0had9baqsjJRvDGdlvgd6NmPE0nPloOipiQJGFtTHQ==}
engines: {node: '>=20.0.0'}
- lit-element@4.2.1:
- resolution: {integrity: sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==}
-
- lit-html@3.3.1:
- resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==}
-
- lit@3.3.0:
- resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==}
-
locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
@@ -4778,8 +4371,8 @@ packages:
lodash.repeat@4.1.0:
resolution: {integrity: sha512-eWsgQW89IewS95ZOcr15HHCX6FVDxq3f2PNUIng3fyzsPev9imFQxIYdFZ6crl8L56UR6ZlGDLcEb3RZsCSSqw==}
- lodash@4.17.21:
- resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+ lodash@4.17.23:
+ resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==}
log-update@6.1.0:
resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==}
@@ -4804,6 +4397,10 @@ packages:
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
+ lru-cache@11.2.5:
+ resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==}
+ engines: {node: 20 || >=22}
+
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
@@ -4858,9 +4455,6 @@ packages:
resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
engines: {node: '>= 0.6'}
- micro-ftch@0.3.1:
- resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==}
-
micromatch@4.0.8:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
@@ -4896,20 +4490,9 @@ packages:
resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
engines: {node: '>=18'}
- minimatch@3.1.2:
- resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
-
- minimatch@5.1.6:
- resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
- engines: {node: '>=10'}
-
- minimatch@9.0.1:
- resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==}
- engines: {node: '>=16 || 14 >=14.17'}
-
- minimatch@9.0.5:
- resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
- engines: {node: '>=16 || 14 >=14.17'}
+ minimatch@10.2.4:
+ resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==}
+ engines: {node: 18 || 20 || >=22}
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
@@ -4918,14 +4501,6 @@ packages:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
- mipd@0.0.7:
- resolution: {integrity: sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==}
- peerDependencies:
- typescript: '>=5.0.4'
- peerDependenciesMeta:
- typescript:
- optional: true
-
mkdirp@1.0.4:
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
engines: {node: '>=10'}
@@ -4934,6 +4509,9 @@ packages:
module-details-from-path@1.0.4:
resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==}
+ ms@2.0.0:
+ resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@@ -4944,15 +4522,12 @@ packages:
msgpackr@1.11.2:
resolution: {integrity: sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==}
- multiformats@9.9.0:
- resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==}
-
mute-stream@2.0.0:
resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==}
engines: {node: ^18.17.0 || >=20.5.0}
- nan@2.22.2:
- resolution: {integrity: sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==}
+ nan@2.23.1:
+ resolution: {integrity: sha512-r7bBUGKzlqk8oPBDYxt6Z0aEdF1G1rwlMcLk8LCOMbOzf0mG+JUfUzG4fIMWwHWP0iyaLWEQZJmtB7nOHEm/qw==}
nano-spawn@1.0.2:
resolution: {integrity: sha512-21t+ozMQDAL/UGgQVBbZ/xXvNO10++ZPuTmKRO8k9V3AClVRht49ahtDjfY8l1q6nSHOrE5ASfthzH3ol6R/hg==}
@@ -4981,9 +4556,6 @@ packages:
node-abort-controller@3.1.1:
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
- node-addon-api@2.0.2:
- resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==}
-
node-cleanup@2.1.2:
resolution: {integrity: sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==}
@@ -4995,9 +4567,6 @@ packages:
node-ensure@0.0.0:
resolution: {integrity: sha512-DRI60hzo2oKN1ma0ckc6nQWlHU69RH6xN0sjQTjMpChPfTYvKZdcQFfdYK2RWbJcKyUizSIy/l8OTGxMAM1QDw==}
- node-fetch-native@1.6.7:
- resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
-
node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0}
@@ -5022,9 +4591,6 @@ packages:
node-int64@0.4.0:
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
- node-mock-http@1.0.2:
- resolution: {integrity: sha512-zWaamgDUdo9SSLw47we78+zYw/bDr5gH8pH7oRRs8V3KmBtu8GLgGIbV2p/gRPd3LWpEOpjQj7X1FOU3VFMJ8g==}
-
node-releases@2.0.27:
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
@@ -5056,9 +4622,6 @@ packages:
nwsapi@2.2.16:
resolution: {integrity: sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==}
- obj-multiplex@1.0.0:
- resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==}
-
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
@@ -5067,9 +4630,6 @@ packages:
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
engines: {node: '>= 0.4'}
- ofetch@1.4.1:
- resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==}
-
ollama-ai-provider@1.2.0:
resolution: {integrity: sha512-jTNFruwe3O/ruJeppI/quoOUxG7NA6blG3ZyQj3lei4+NnJo7bi3eIRWqlVpRlu/mbzbFXeJSBuYQWF6pzGKww==}
engines: {node: '>=18'}
@@ -5079,9 +4639,6 @@ packages:
zod:
optional: true
- on-exit-leak-free@0.2.0:
- resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==}
-
on-finished@2.4.1:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
engines: {node: '>= 0.8'}
@@ -5116,38 +4673,8 @@ packages:
zod:
optional: true
- openapi-fetch@0.13.8:
- resolution: {integrity: sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ==}
-
- openapi-typescript-helpers@0.0.15:
- resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==}
-
- ox@0.6.7:
- resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==}
- peerDependencies:
- typescript: '>=5.4.0'
- peerDependenciesMeta:
- typescript:
- optional: true
-
- ox@0.6.9:
- resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==}
- peerDependencies:
- typescript: '>=5.4.0'
- peerDependenciesMeta:
- typescript:
- optional: true
-
- ox@0.8.6:
- resolution: {integrity: sha512-eiKcgiVVEGDtEpEdFi1EGoVVI48j6icXHce9nFwCNM7CKG3uoCXKdr4TPhS00Iy1TR2aWSF1ltPD0x/YgqIL9w==}
- peerDependencies:
- typescript: '>=5.4.0'
- peerDependenciesMeta:
- typescript:
- optional: true
-
- ox@0.9.8:
- resolution: {integrity: sha512-bedy2pidGW8/XKVlXiAo/sIJxO4RAY9DsLyzZ7ppzGdPrECjS/7RN26CDoeABkbCtZWtGH5k/+Sx/KD/8J3xUQ==}
+ ox@0.11.3:
+ resolution: {integrity: sha512-1bWYGk/xZel3xro3l8WGg6eq4YEKlaqvyMtVhfMFpbJzK2F6rj4EDRtqDCWVEJMkzcmEi9uW2QxsqELokOlarw==}
peerDependencies:
typescript: '>=5.4.0'
peerDependenciesMeta:
@@ -5183,9 +4710,6 @@ packages:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
- package-json-from-dist@1.0.0:
- resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==}
-
parse-diff@0.11.1:
resolution: {integrity: sha512-Oq4j8LAOPOcssanQkIjxosjATBIEJhCxMCxPhMu+Ci4wdNmAEdx0O+a7gzbR2PyKXgKPvRLIN5g224+dJAsKHA==}
@@ -5227,9 +4751,9 @@ packages:
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
- path-scurry@1.11.1:
- resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
- engines: {node: '>=16 || 14 >=14.18'}
+ path-scurry@2.0.1:
+ resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==}
+ engines: {node: 20 || >=22}
path-to-regexp@0.1.12:
resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==}
@@ -5300,24 +4824,6 @@ packages:
engines: {node: '>=0.10'}
hasBin: true
- pify@3.0.0:
- resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==}
- engines: {node: '>=4'}
-
- pify@5.0.0:
- resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==}
- engines: {node: '>=10'}
-
- pino-abstract-transport@0.5.0:
- resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==}
-
- pino-std-serializers@4.0.0:
- resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==}
-
- pino@7.11.0:
- resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==}
- hasBin: true
-
pirates@4.0.7:
resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
engines: {node: '>= 6'}
@@ -5326,38 +4832,6 @@ packages:
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
engines: {node: '>=8'}
- pngjs@5.0.0:
- resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
- engines: {node: '>=10.13.0'}
-
- pony-cause@2.1.11:
- resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==}
- engines: {node: '>=12.0.0'}
-
- porto@0.2.19:
- resolution: {integrity: sha512-q1vEJgdtlEOf6byWgD31GHiMwpfLuxFSfx9f7Sw4RGdvpQs2ANBGfnzzardADZegr87ZXsebSp+3vaaznEUzPQ==}
- hasBin: true
- peerDependencies:
- '@tanstack/react-query': '>=5.59.0'
- '@wagmi/core': '>=2.16.3'
- react: '>=18'
- typescript: '>=5.4.0'
- viem: '>=2.37.0'
- wagmi: '>=2.0.0'
- peerDependenciesMeta:
- '@tanstack/react-query':
- optional: true
- react:
- optional: true
- typescript:
- optional: true
- wagmi:
- optional: true
-
- possible-typed-array-names@1.1.0:
- resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
- engines: {node: '>= 0.4'}
-
postgres-array@2.0.0:
resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
engines: {node: '>=4'}
@@ -5374,12 +4848,6 @@ packages:
resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
engines: {node: '>=0.10.0'}
- preact@10.24.2:
- resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==}
-
- preact@10.27.2:
- resolution: {integrity: sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==}
-
prettier@3.6.2:
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
engines: {node: '>=14'}
@@ -5389,12 +4857,6 @@ packages:
resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==}
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
- process-nextick-args@2.0.1:
- resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
-
- process-warning@1.0.0:
- resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==}
-
process@0.11.10:
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
engines: {node: '>= 0.6.0'}
@@ -5414,9 +4876,6 @@ packages:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
- proxy-compare@2.6.0:
- resolution: {integrity: sha512-8xuCeM3l8yqdmbPoYeLbrAXCBWu19XEYc5/F28f5qOaoAIMyfmBUkl5axiK+x9olUvRlcekvnm98AP9RDngOIw==}
-
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
@@ -5428,9 +4887,6 @@ packages:
psl@1.15.0:
resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
- pump@3.0.3:
- resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==}
-
punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
@@ -5438,31 +4894,16 @@ packages:
pure-rand@7.0.1:
resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==}
- qrcode@1.5.3:
- resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==}
- engines: {node: '>=10.13.0'}
- hasBin: true
-
- qs@6.14.1:
- resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==}
+ qs@6.15.0:
+ resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==}
engines: {node: '>=0.6'}
- query-string@7.1.3:
- resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==}
- engines: {node: '>=6'}
-
querystringify@2.2.0:
resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
- quick-format-unescaped@4.0.4:
- resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
-
- radix3@1.1.2:
- resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==}
-
range-parser@1.2.1:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'}
@@ -5493,9 +4934,6 @@ packages:
resolution: {integrity: sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==}
engines: {node: ^18.17.0 || >=20.5.0}
- readable-stream@2.3.8:
- resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
-
readable-stream@3.6.2:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'}
@@ -5504,14 +4942,6 @@ packages:
resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- readdirp@4.1.2:
- resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
- engines: {node: '>= 14.18.0'}
-
- real-require@0.1.0:
- resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==}
- engines: {node: '>= 12.13.0'}
-
rechoir@0.6.2:
resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
engines: {node: '>= 0.10'}
@@ -5543,9 +4973,6 @@ packages:
resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==}
engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'}
- require-main-filename@2.0.0:
- resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
-
requires-port@1.0.0:
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
@@ -5608,16 +5035,9 @@ packages:
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
- safe-buffer@5.1.2:
- resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
-
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
- safe-regex-test@1.1.0:
- resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
- engines: {node: '>= 0.4'}
-
safe-stable-stringify@2.4.3:
resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==}
engines: {node: '>=10'}
@@ -5663,21 +5083,9 @@ packages:
resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==}
engines: {node: '>= 0.8.0'}
- set-blocking@2.0.0:
- resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
-
- set-function-length@1.2.2:
- resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
- engines: {node: '>= 0.4'}
-
setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
- sha.js@2.4.12:
- resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==}
- engines: {node: '>= 0.10'}
- hasBin: true
-
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -5725,6 +5133,11 @@ packages:
simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
+ siwe@2.3.2:
+ resolution: {integrity: sha512-aSf+6+Latyttbj5nMu6GF3doMfv2UYj83hhwZgUF20ky6fTS83uVhkQABdIVnEuS8y1bBdk7p6ltb9SmlhTTlA==}
+ peerDependencies:
+ ethers: ^5.6.8 || ^6.0.8
+
slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
@@ -5741,17 +5154,6 @@ packages:
resolution: {integrity: sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==}
engines: {node: '>= 18'}
- socket.io-client@4.8.1:
- resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==}
- engines: {node: '>=10.0.0'}
-
- socket.io-parser@4.2.4:
- resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==}
- engines: {node: '>=10.0.0'}
-
- sonic-boom@2.8.0:
- resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==}
-
source-map-support@0.5.13:
resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==}
@@ -5759,10 +5161,6 @@ packages:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
- split-on-first@1.1.0:
- resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==}
- engines: {node: '>=6'}
-
split2@4.2.0:
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
engines: {node: '>= 10.x'}
@@ -5770,9 +5168,6 @@ packages:
split@0.3.3:
resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==}
- sprintf-js@1.0.3:
- resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
-
sprintf-js@1.1.2:
resolution: {integrity: sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==}
@@ -5805,10 +5200,6 @@ packages:
stream-shift@1.0.3:
resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==}
- strict-uri-encode@2.0.0:
- resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==}
- engines: {node: '>=4'}
-
string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
engines: {node: '>=0.6.19'}
@@ -5821,17 +5212,10 @@ packages:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
- string-width@5.1.2:
- resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
- engines: {node: '>=12'}
-
string-width@7.2.0:
resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
engines: {node: '>=18'}
- string_decoder@1.1.1:
- resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
-
string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
@@ -5863,8 +5247,8 @@ packages:
resolution: {integrity: sha512-syeEEd112om/waJ5gOQ+SaYi+setuidQ4ZIPiQREF4yJeegXhn2HKy6C0JYm7uhVQKfMAvuZ22dIRsnoDv7AMw==}
engines: {node: '>=12.*'}
- strnum@1.0.5:
- resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==}
+ strnum@2.1.2:
+ resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==}
stubs@3.0.0:
resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==}
@@ -5874,10 +5258,6 @@ packages:
engines: {node: '>=6.4.0 <13 || >=14'}
deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net
- superstruct@1.0.4:
- resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==}
- engines: {node: '>=14.0.0'}
-
superstruct@2.0.2:
resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==}
engines: {node: '>=14.0.0'}
@@ -5910,8 +5290,8 @@ packages:
resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==}
engines: {node: ^14.18.0 || >=16.0.0}
- systeminformation@5.27.14:
- resolution: {integrity: sha512-3DoNDYSZBLxBwaJtQGWNpq0fonga/VZ47HY1+7/G3YoIPaPz93Df6egSzzTKbEMmlzUpy3eQ0nR9REuYIycXGg==}
+ systeminformation@5.31.1:
+ resolution: {integrity: sha512-6pRwxoGeV/roJYpsfcP6tN9mep6pPeCtXbUOCdVa0nme05Brwcwdge/fVNhIZn2wuUitAKZm4IYa7QjnRIa9zA==}
engines: {node: '>=8.0.0'}
os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android]
hasBin: true
@@ -5933,9 +5313,6 @@ packages:
text-hex@1.0.0:
resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==}
- thread-stream@0.15.2:
- resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==}
-
through@2.3.8:
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
@@ -5949,10 +5326,6 @@ packages:
tmpl@1.0.5:
resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
- to-buffer@1.2.2:
- resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==}
- engines: {node: '>= 0.4'}
-
to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -6028,12 +5401,12 @@ packages:
peerDependencies:
typescript: '*'
- tslib@1.14.1:
- resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
-
tslib@2.6.3:
resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
+ tslib@2.7.0:
+ resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
+
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
@@ -6045,6 +5418,9 @@ packages:
turndown@7.2.0:
resolution: {integrity: sha512-eCZGBN4nNNqM9Owkv9HAtWRYfLA4h909E/WGAWWBpmB275ehNhZyk87/Tpvjbp0jjNl9XwCsbe6bm6CqFsgD+A==}
+ tweetnacl@1.0.3:
+ resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==}
+
typanion@3.14.0:
resolution: {integrity: sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==}
@@ -6064,10 +5440,6 @@ packages:
resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
engines: {node: '>= 0.6'}
- typed-array-buffer@1.0.3:
- resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
- engines: {node: '>= 0.4'}
-
typescript@5.8.3:
resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
engines: {node: '>=14.17'}
@@ -6078,28 +5450,25 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
- ufo@1.6.1:
- resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
-
uglify-js@3.19.3:
resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==}
engines: {node: '>=0.8.0'}
hasBin: true
- uint8arrays@3.1.0:
- resolution: {integrity: sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog==}
-
uncrypto@0.1.3:
resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
+ undici-types@6.19.8:
+ resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
+
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
- undici@7.10.0:
- resolution: {integrity: sha512-u5otvFBOBZvmdjWLVW+5DAc9Nkq8f24g0O9oY7qw2JVIF1VocIFoyz9JFkuVOS2j41AufeO0xnlweJ2RLT8nGw==}
+ undici@7.18.2:
+ resolution: {integrity: sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==}
engines: {node: '>=20.18.1'}
universal-user-agent@7.0.3:
@@ -6116,65 +5485,6 @@ packages:
unrs-resolver@1.11.1:
resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==}
- unstorage@1.16.1:
- resolution: {integrity: sha512-gdpZ3guLDhz+zWIlYP1UwQ259tG5T5vYRzDaHMkQ1bBY1SQPutvZnrRjTFaWUUpseErJIgAZS51h6NOcZVZiqQ==}
- peerDependencies:
- '@azure/app-configuration': ^1.8.0
- '@azure/cosmos': ^4.2.0
- '@azure/data-tables': ^13.3.0
- '@azure/identity': ^4.6.0
- '@azure/keyvault-secrets': ^4.9.0
- '@azure/storage-blob': ^12.26.0
- '@capacitor/preferences': ^6.0.3 || ^7.0.0
- '@deno/kv': '>=0.9.0'
- '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0
- '@planetscale/database': ^1.19.0
- '@upstash/redis': ^1.34.3
- '@vercel/blob': '>=0.27.1'
- '@vercel/kv': ^1.0.1
- aws4fetch: ^1.0.20
- db0: '>=0.2.1'
- idb-keyval: ^6.2.1
- ioredis: ^5.4.2
- uploadthing: ^7.4.4
- peerDependenciesMeta:
- '@azure/app-configuration':
- optional: true
- '@azure/cosmos':
- optional: true
- '@azure/data-tables':
- optional: true
- '@azure/identity':
- optional: true
- '@azure/keyvault-secrets':
- optional: true
- '@azure/storage-blob':
- optional: true
- '@capacitor/preferences':
- optional: true
- '@deno/kv':
- optional: true
- '@netlify/blobs':
- optional: true
- '@planetscale/database':
- optional: true
- '@upstash/redis':
- optional: true
- '@vercel/blob':
- optional: true
- '@vercel/kv':
- optional: true
- aws4fetch:
- optional: true
- db0:
- optional: true
- idb-keyval:
- optional: true
- ioredis:
- optional: true
- uploadthing:
- optional: true
-
update-browserslist-db@1.1.4:
resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==}
hasBin: true
@@ -6187,16 +5497,6 @@ packages:
url-parse@1.5.10:
resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
- use-sync-external-store@1.2.0:
- resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0
-
- use-sync-external-store@1.4.0:
- resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
-
utf-8-validate@5.0.10:
resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==}
engines: {node: '>=6.14.2'}
@@ -6204,9 +5504,6 @@ packages:
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
- util@0.12.5:
- resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==}
-
utils-merge@1.0.1:
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
engines: {node: '>= 0.4.0'}
@@ -6230,32 +5527,15 @@ packages:
resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==}
engines: {node: '>=10.12.0'}
- valtio@1.13.2:
- resolution: {integrity: sha512-Qik0o+DSy741TmkqmRfjq+0xpZBXi/Y6+fXZLn0xNF1z/waFMbE3rkivv5Zcf9RrMUp6zswf2J7sbh2KBlba5A==}
- engines: {node: '>=12.20.0'}
- peerDependencies:
- '@types/react': '>=16.8'
- react: '>=16.8'
- peerDependenciesMeta:
- '@types/react':
- optional: true
- react:
- optional: true
+ valid-url@1.0.9:
+ resolution: {integrity: sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==}
vary@1.1.2:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
- viem@2.23.2:
- resolution: {integrity: sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==}
- peerDependencies:
- typescript: '>=5.0.4'
- peerDependenciesMeta:
- typescript:
- optional: true
-
- viem@2.33.2:
- resolution: {integrity: sha512-/720OaM4dHWs8vXwNpyet+PRERhPaW+n/1UVSCzyb9jkmwwVfaiy/R6YfCFb4v+XXbo8s3Fapa3DM5yCRSkulA==}
+ viem@2.45.1:
+ resolution: {integrity: sha512-LN6Pp7vSfv50LgwhkfSbIXftAM5J89lP9x8TeDa8QM7o41IxlHrDh0F9X+FfnCWtsz11pEVV5sn+yBUoOHNqYA==}
peerDependencies:
typescript: '>=5.0.4'
peerDependenciesMeta:
@@ -6266,17 +5546,6 @@ packages:
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
engines: {node: '>=18'}
- wagmi@2.17.5:
- resolution: {integrity: sha512-Sk2e40gfo68gbJ6lHkpIwCMkH76rO0+toCPjf3PzdQX37rZo9042DdNTYcSg3zhnx8abFJtrk/5vAWfR8APTDw==}
- peerDependencies:
- '@tanstack/react-query': '>=5.0.0'
- react: '>=18'
- typescript: '>=5.0.4'
- viem: 2.x
- peerDependenciesMeta:
- typescript:
- optional: true
-
walk-up-path@4.0.0:
resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
engines: {node: 20 || >=22}
@@ -6288,9 +5557,6 @@ packages:
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
engines: {node: '>= 8'}
- webextension-polyfill@0.10.0:
- resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==}
-
webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
@@ -6301,6 +5567,7 @@ packages:
whatwg-encoding@3.1.1:
resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
engines: {node: '>=18'}
+ deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation
whatwg-mimetype@4.0.0:
resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
@@ -6313,13 +5580,6 @@ packages:
whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
- which-module@2.0.1:
- resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
-
- which-typed-array@1.1.19:
- resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
- engines: {node: '>= 0.4'}
-
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
@@ -6349,10 +5609,6 @@ packages:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
- wrap-ansi@8.1.0:
- resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
- engines: {node: '>=12'}
-
wrap-ansi@9.0.0:
resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
engines: {node: '>=18'}
@@ -6400,18 +5656,6 @@ packages:
utf-8-validate:
optional: true
- ws@8.18.2:
- resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==}
- 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.18.3:
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
engines: {node: '>=10.0.0'}
@@ -6424,12 +5668,6 @@ packages:
utf-8-validate:
optional: true
- x402-express@0.6.5:
- resolution: {integrity: sha512-sVuNr+02VmKUyUxKruVxNUx0j67ysrDS6n9sKUjAydNIhme+/L71WnEpTRYm5qB7v1c846/FDPTex1JylQrtrg==}
-
- x402@0.6.6:
- resolution: {integrity: sha512-gKkxqKBT0mH7fSLld6Mz9ML52dmu1XeOPhVtiUCA3EzkfY6p0EJ3ijKhIKN0Jh8Q6kVXrFlJ/4iAUS1dNDA2lA==}
-
xml-name-validator@5.0.0:
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
engines: {node: '>=18'}
@@ -6448,17 +5686,10 @@ packages:
xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
- xmlhttprequest-ssl@2.1.2:
- resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==}
- engines: {node: '>=0.4.0'}
-
xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
- y18n@4.0.3:
- resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
-
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@@ -6471,18 +5702,10 @@ packages:
engines: {node: '>= 14.6'}
hasBin: true
- yargs-parser@18.1.3:
- resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
- engines: {node: '>=6'}
-
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
- yargs@15.4.1:
- resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
- engines: {node: '>=8'}
-
yargs@17.7.2:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
@@ -6502,71 +5725,16 @@ packages:
resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==}
engines: {node: '>=18'}
- zod@3.22.4:
- resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
-
zod@3.25.76:
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
zod@4.1.12:
resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==}
- zustand@5.0.0:
- resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==}
- engines: {node: '>=12.20.0'}
- peerDependencies:
- '@types/react': '>=18.0.0'
- immer: '>=9.0.6'
- react: '>=18.0.0'
- use-sync-external-store: '>=1.2.0'
- peerDependenciesMeta:
- '@types/react':
- optional: true
- immer:
- optional: true
- react:
- optional: true
- use-sync-external-store:
- optional: true
-
- zustand@5.0.3:
- resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==}
- engines: {node: '>=12.20.0'}
- peerDependencies:
- '@types/react': '>=18.0.0'
- immer: '>=9.0.6'
- react: '>=18.0.0'
- use-sync-external-store: '>=1.2.0'
- peerDependenciesMeta:
- '@types/react':
- optional: true
- immer:
- optional: true
- react:
- optional: true
- use-sync-external-store:
- optional: true
-
- zustand@5.0.8:
- resolution: {integrity: sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==}
- engines: {node: '>=12.20.0'}
- peerDependencies:
- '@types/react': '>=18.0.0'
- immer: '>=9.0.6'
- react: '>=18.0.0'
- use-sync-external-store: '>=1.2.0'
- peerDependenciesMeta:
- '@types/react':
- optional: true
- immer:
- optional: true
- react:
- optional: true
- use-sync-external-store:
- optional: true
-
snapshots:
+ '@adraffy/ens-normalize@1.10.1': {}
+
'@adraffy/ens-normalize@1.11.1': {}
'@ai-sdk/anthropic@2.0.50(zod@4.1.12)':
@@ -6868,8 +6036,6 @@ snapshots:
'@babel/core': 7.28.5
'@babel/helper-plugin-utils': 7.27.1
- '@babel/runtime@7.28.2': {}
-
'@babel/runtime@7.28.4': {}
'@babel/template@7.27.2':
@@ -6895,26 +6061,6 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
- '@base-org/account@1.1.1(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@noble/hashes': 1.4.0
- clsx: 1.2.1
- eventemitter3: 5.0.1
- idb-keyval: 6.2.1
- ox: 0.6.9(typescript@5.8.3)(zod@3.25.76)
- preact: 10.24.2
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- zustand: 5.0.3(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1))
- transitivePeerDependencies:
- - '@types/react'
- - bufferutil
- - immer
- - react
- - typescript
- - use-sync-external-store
- - utf-8-validate
- - zod
-
'@bcoe/v8-coverage@0.2.3': {}
'@bull-board/api@6.14.2(@bull-board/ui@6.14.2)':
@@ -6940,100 +6086,27 @@ snapshots:
'@solana/spl-token': 0.4.13(@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)
'@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)
abitype: 1.0.6(typescript@5.8.3)(zod@3.25.76)
- axios: 1.12.2
- axios-retry: 4.5.0(axios@1.12.2)
+ axios: 1.13.5
+ axios-retry: 4.5.0(axios@1.13.5)
jose: 6.0.12
md5: 2.3.0
uncrypto: 0.1.3
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- zod: 3.25.76
- transitivePeerDependencies:
- - bufferutil
- - debug
- - encoding
- - fastestsmallesttextencoderdecoder
- - typescript
- - utf-8-validate
-
- '@coinbase/wallet-sdk@3.9.3':
- dependencies:
- bn.js: 5.2.2
- buffer: 6.0.3
- clsx: 1.2.1
- eth-block-tracker: 7.1.0
- eth-json-rpc-filters: 6.0.1
- eventemitter3: 5.0.1
- keccak: 3.0.4
- preact: 10.27.2
- sha.js: 2.4.12
- transitivePeerDependencies:
- - supports-color
-
- '@coinbase/wallet-sdk@4.3.6(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@noble/hashes': 1.4.0
- clsx: 1.2.1
- eventemitter3: 5.0.1
- idb-keyval: 6.2.1
- ox: 0.6.9(typescript@5.8.3)(zod@3.25.76)
- preact: 10.24.2
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- zustand: 5.0.3(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1))
- transitivePeerDependencies:
- - '@types/react'
- - bufferutil
- - immer
- - react
- - typescript
- - use-sync-external-store
- - utf-8-validate
- - zod
-
- '@coinbase/x402@0.6.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))':
- dependencies:
- '@coinbase/cdp-sdk': 1.33.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- x402: 0.6.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
+ viem: 2.45.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
zod: 3.25.76
transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@solana/sysvars'
- - '@tanstack/query-core'
- - '@tanstack/react-query'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- bufferutil
- - db0
- debug
- encoding
- fastestsmallesttextencoderdecoder
- - immer
- - ioredis
- - react
- - supports-color
- typescript
- - uploadthing
- utf-8-validate
- - ws
'@colors/colors@1.6.0': {}
'@cspotcode/source-map-support@0.8.1':
dependencies:
'@jridgewell/trace-mapping': 0.3.9
+ optional: true
'@csstools/color-helpers@5.0.1': {}
@@ -7063,10 +6136,6 @@ snapshots:
'@dqbd/tiktoken@1.0.22': {}
- '@ecies/ciphers@0.2.4(@noble/ciphers@1.3.0)':
- dependencies:
- '@noble/ciphers': 1.3.0
-
'@emnapi/core@1.5.0':
dependencies:
'@emnapi/wasi-threads': 1.1.0
@@ -7085,108 +6154,158 @@ snapshots:
'@esbuild/aix-ppc64@0.25.8':
optional: true
+ '@esbuild/aix-ppc64@0.27.2':
+ optional: true
+
'@esbuild/android-arm64@0.25.8':
optional: true
+ '@esbuild/android-arm64@0.27.2':
+ optional: true
+
'@esbuild/android-arm@0.25.8':
optional: true
+ '@esbuild/android-arm@0.27.2':
+ optional: true
+
'@esbuild/android-x64@0.25.8':
optional: true
+ '@esbuild/android-x64@0.27.2':
+ optional: true
+
'@esbuild/darwin-arm64@0.25.8':
optional: true
+ '@esbuild/darwin-arm64@0.27.2':
+ optional: true
+
'@esbuild/darwin-x64@0.25.8':
optional: true
+ '@esbuild/darwin-x64@0.27.2':
+ optional: true
+
'@esbuild/freebsd-arm64@0.25.8':
optional: true
+ '@esbuild/freebsd-arm64@0.27.2':
+ optional: true
+
'@esbuild/freebsd-x64@0.25.8':
optional: true
+ '@esbuild/freebsd-x64@0.27.2':
+ optional: true
+
'@esbuild/linux-arm64@0.25.8':
optional: true
+ '@esbuild/linux-arm64@0.27.2':
+ optional: true
+
'@esbuild/linux-arm@0.25.8':
optional: true
+ '@esbuild/linux-arm@0.27.2':
+ optional: true
+
'@esbuild/linux-ia32@0.25.8':
optional: true
+ '@esbuild/linux-ia32@0.27.2':
+ optional: true
+
'@esbuild/linux-loong64@0.25.8':
optional: true
+ '@esbuild/linux-loong64@0.27.2':
+ optional: true
+
'@esbuild/linux-mips64el@0.25.8':
optional: true
+ '@esbuild/linux-mips64el@0.27.2':
+ optional: true
+
'@esbuild/linux-ppc64@0.25.8':
optional: true
+ '@esbuild/linux-ppc64@0.27.2':
+ optional: true
+
'@esbuild/linux-riscv64@0.25.8':
optional: true
+ '@esbuild/linux-riscv64@0.27.2':
+ optional: true
+
'@esbuild/linux-s390x@0.25.8':
optional: true
+ '@esbuild/linux-s390x@0.27.2':
+ optional: true
+
'@esbuild/linux-x64@0.25.8':
optional: true
+ '@esbuild/linux-x64@0.27.2':
+ optional: true
+
'@esbuild/netbsd-arm64@0.25.8':
optional: true
+ '@esbuild/netbsd-arm64@0.27.2':
+ optional: true
+
'@esbuild/netbsd-x64@0.25.8':
optional: true
+ '@esbuild/netbsd-x64@0.27.2':
+ optional: true
+
'@esbuild/openbsd-arm64@0.25.8':
optional: true
+ '@esbuild/openbsd-arm64@0.27.2':
+ optional: true
+
'@esbuild/openbsd-x64@0.25.8':
optional: true
+ '@esbuild/openbsd-x64@0.27.2':
+ optional: true
+
'@esbuild/openharmony-arm64@0.25.8':
optional: true
- '@esbuild/sunos-x64@0.25.8':
+ '@esbuild/openharmony-arm64@0.27.2':
optional: true
- '@esbuild/win32-arm64@0.25.8':
+ '@esbuild/sunos-x64@0.25.8':
optional: true
- '@esbuild/win32-ia32@0.25.8':
+ '@esbuild/sunos-x64@0.27.2':
optional: true
- '@esbuild/win32-x64@0.25.8':
+ '@esbuild/win32-arm64@0.25.8':
optional: true
- '@ethereumjs/common@3.2.0':
- dependencies:
- '@ethereumjs/util': 8.1.0
- crc-32: 1.2.2
+ '@esbuild/win32-arm64@0.27.2':
+ optional: true
- '@ethereumjs/rlp@4.0.1': {}
+ '@esbuild/win32-ia32@0.25.8':
+ optional: true
- '@ethereumjs/tx@4.2.0':
- dependencies:
- '@ethereumjs/common': 3.2.0
- '@ethereumjs/rlp': 4.0.1
- '@ethereumjs/util': 8.1.0
- ethereum-cryptography: 2.2.1
+ '@esbuild/win32-ia32@0.27.2':
+ optional: true
- '@ethereumjs/util@8.1.0':
- dependencies:
- '@ethereumjs/rlp': 4.0.1
- ethereum-cryptography: 2.2.1
- micro-ftch: 0.3.1
+ '@esbuild/win32-x64@0.25.8':
+ optional: true
- '@gemini-wallet/core@0.2.0(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))':
- dependencies:
- '@metamask/rpc-errors': 7.0.2
- eventemitter3: 5.0.1
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- transitivePeerDependencies:
- - supports-color
+ '@esbuild/win32-x64@0.27.2':
+ optional: true
'@google-cloud/paginator@5.0.2':
dependencies:
@@ -7197,7 +6316,7 @@ snapshots:
'@google-cloud/promisify@4.0.0': {}
- '@google-cloud/storage@7.16.0(encoding@0.1.13)':
+ '@google-cloud/storage@7.18.0(encoding@0.1.13)':
dependencies:
'@google-cloud/paginator': 5.0.2
'@google-cloud/projectify': 4.0.0
@@ -7205,7 +6324,7 @@ snapshots:
abort-controller: 3.0.0
async-retry: 1.3.3
duplexify: 4.1.3
- fast-xml-parser: 4.4.1
+ fast-xml-parser: 5.4.1
gaxios: 6.7.1(encoding@0.1.13)
google-auth-library: 9.15.1(encoding@0.1.13)
html-entities: 2.6.0
@@ -7343,21 +6462,12 @@ snapshots:
'@ioredis/commands@1.2.0': {}
- '@isaacs/cliui@8.0.2':
- dependencies:
- string-width: 5.1.2
- string-width-cjs: string-width@4.2.3
- strip-ansi: 7.1.0
- strip-ansi-cjs: strip-ansi@6.0.1
- wrap-ansi: 8.1.0
- wrap-ansi-cjs: wrap-ansi@7.0.0
-
'@istanbuljs/load-nyc-config@1.1.0':
dependencies:
camelcase: 5.3.1
find-up: 4.1.0
get-package-type: 0.1.0
- js-yaml: 3.14.1
+ js-yaml: 4.1.1
resolve-from: 5.0.0
'@istanbuljs/schema@0.1.3': {}
@@ -7464,7 +6574,7 @@ snapshots:
chalk: 4.1.2
collect-v8-coverage: 1.0.2
exit-x: 0.2.2
- glob: 10.4.2
+ glob: 13.0.1
graceful-fs: 4.2.11
istanbul-lib-coverage: 3.2.2
istanbul-lib-instrument: 6.0.2
@@ -7553,8 +6663,6 @@ snapshots:
'@jridgewell/resolve-uri@3.1.2': {}
- '@jridgewell/sourcemap-codec@1.4.15': {}
-
'@jridgewell/sourcemap-codec@1.5.5': {}
'@jridgewell/trace-mapping@0.3.31':
@@ -7565,220 +6673,30 @@ snapshots:
'@jridgewell/trace-mapping@0.3.9':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
- '@jridgewell/sourcemap-codec': 1.4.15
-
- '@lit-labs/ssr-dom-shim@1.4.0': {}
-
- '@lit/reactive-element@2.1.1':
- dependencies:
- '@lit-labs/ssr-dom-shim': 1.4.0
-
- '@metamask/eth-json-rpc-provider@1.0.1':
- dependencies:
- '@metamask/json-rpc-engine': 7.3.3
- '@metamask/safe-event-emitter': 3.1.2
- '@metamask/utils': 5.0.2
- transitivePeerDependencies:
- - supports-color
+ '@jridgewell/sourcemap-codec': 1.5.5
+ optional: true
- '@metamask/json-rpc-engine@7.3.3':
- dependencies:
- '@metamask/rpc-errors': 6.4.0
- '@metamask/safe-event-emitter': 3.1.2
- '@metamask/utils': 8.5.0
- transitivePeerDependencies:
- - supports-color
+ '@mixmark-io/domino@2.2.0': {}
- '@metamask/json-rpc-engine@8.0.2':
- dependencies:
- '@metamask/rpc-errors': 6.4.0
- '@metamask/safe-event-emitter': 3.1.2
- '@metamask/utils': 8.5.0
- transitivePeerDependencies:
- - supports-color
+ '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3':
+ optional: true
- '@metamask/json-rpc-middleware-stream@7.0.2':
- dependencies:
- '@metamask/json-rpc-engine': 8.0.2
- '@metamask/safe-event-emitter': 3.1.2
- '@metamask/utils': 8.5.0
- readable-stream: 3.6.2
- transitivePeerDependencies:
- - supports-color
+ '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3':
+ optional: true
- '@metamask/object-multiplex@2.1.0':
- dependencies:
- once: 1.4.0
- readable-stream: 3.6.2
+ '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3':
+ optional: true
- '@metamask/onboarding@1.0.1':
- dependencies:
- bowser: 2.11.0
+ '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3':
+ optional: true
- '@metamask/providers@16.1.0':
- dependencies:
- '@metamask/json-rpc-engine': 8.0.2
- '@metamask/json-rpc-middleware-stream': 7.0.2
- '@metamask/object-multiplex': 2.1.0
- '@metamask/rpc-errors': 6.4.0
- '@metamask/safe-event-emitter': 3.1.2
- '@metamask/utils': 8.5.0
- detect-browser: 5.3.0
- extension-port-stream: 3.0.0
- fast-deep-equal: 3.1.3
- is-stream: 2.0.1
- readable-stream: 3.6.2
- webextension-polyfill: 0.10.0
- transitivePeerDependencies:
- - supports-color
+ '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3':
+ optional: true
- '@metamask/rpc-errors@6.4.0':
- dependencies:
- '@metamask/utils': 9.3.0
- fast-safe-stringify: 2.1.1
- transitivePeerDependencies:
- - supports-color
+ '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3':
+ optional: true
- '@metamask/rpc-errors@7.0.2':
- dependencies:
- '@metamask/utils': 11.8.1
- fast-safe-stringify: 2.1.1
- transitivePeerDependencies:
- - supports-color
-
- '@metamask/safe-event-emitter@2.0.0': {}
-
- '@metamask/safe-event-emitter@3.1.2': {}
-
- '@metamask/sdk-analytics@0.0.5':
- dependencies:
- openapi-fetch: 0.13.8
-
- '@metamask/sdk-communication-layer@0.33.1(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))':
- dependencies:
- '@metamask/sdk-analytics': 0.0.5
- bufferutil: 4.0.9
- cross-fetch: 4.1.0(encoding@0.1.13)
- date-fns: 2.30.0
- debug: 4.4.3
- eciesjs: 0.4.15
- eventemitter2: 6.4.9
- readable-stream: 3.6.2
- socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- utf-8-validate: 5.0.10
- uuid: 8.3.2
- transitivePeerDependencies:
- - supports-color
-
- '@metamask/sdk-install-modal-web@0.32.1':
- dependencies:
- '@paulmillr/qr': 0.2.1
-
- '@metamask/sdk@0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)':
- dependencies:
- '@babel/runtime': 7.28.4
- '@metamask/onboarding': 1.0.1
- '@metamask/providers': 16.1.0
- '@metamask/sdk-analytics': 0.0.5
- '@metamask/sdk-communication-layer': 0.33.1(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))
- '@metamask/sdk-install-modal-web': 0.32.1
- '@paulmillr/qr': 0.2.1
- bowser: 2.12.1
- cross-fetch: 4.1.0(encoding@0.1.13)
- debug: 4.4.3
- eciesjs: 0.4.15
- eth-rpc-errors: 4.0.3
- eventemitter2: 6.4.9
- obj-multiplex: 1.0.0
- pump: 3.0.3
- readable-stream: 3.6.2
- socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- tslib: 2.8.1
- util: 0.12.5
- uuid: 8.3.2
- transitivePeerDependencies:
- - bufferutil
- - encoding
- - supports-color
- - utf-8-validate
-
- '@metamask/superstruct@3.2.1': {}
-
- '@metamask/utils@11.8.1':
- dependencies:
- '@ethereumjs/tx': 4.2.0
- '@metamask/superstruct': 3.2.1
- '@noble/hashes': 1.8.0
- '@scure/base': 1.2.6
- '@types/debug': 4.1.12
- '@types/lodash': 4.17.20
- debug: 4.4.3
- lodash: 4.17.21
- pony-cause: 2.1.11
- semver: 7.7.3
- uuid: 9.0.1
- transitivePeerDependencies:
- - supports-color
-
- '@metamask/utils@5.0.2':
- dependencies:
- '@ethereumjs/tx': 4.2.0
- '@types/debug': 4.1.12
- debug: 4.4.3
- semver: 7.7.3
- superstruct: 1.0.4
- transitivePeerDependencies:
- - supports-color
-
- '@metamask/utils@8.5.0':
- dependencies:
- '@ethereumjs/tx': 4.2.0
- '@metamask/superstruct': 3.2.1
- '@noble/hashes': 1.8.0
- '@scure/base': 1.2.6
- '@types/debug': 4.1.12
- debug: 4.4.3
- pony-cause: 2.1.11
- semver: 7.7.3
- uuid: 9.0.1
- transitivePeerDependencies:
- - supports-color
-
- '@metamask/utils@9.3.0':
- dependencies:
- '@ethereumjs/tx': 4.2.0
- '@metamask/superstruct': 3.2.1
- '@noble/hashes': 1.8.0
- '@scure/base': 1.2.6
- '@types/debug': 4.1.12
- debug: 4.4.3
- pony-cause: 2.1.11
- semver: 7.7.3
- uuid: 9.0.1
- transitivePeerDependencies:
- - supports-color
-
- '@mixmark-io/domino@2.2.0': {}
-
- '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3':
- optional: true
-
- '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3':
- optional: true
-
- '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3':
- optional: true
-
- '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3':
- optional: true
-
- '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3':
- optional: true
-
- '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3':
- optional: true
-
- '@napi-rs/cli@3.4.1(@emnapi/runtime@1.5.0)(@types/node@24.10.1)':
+ '@napi-rs/cli@3.4.1(@emnapi/runtime@1.5.0)(@types/node@24.10.1)':
dependencies:
'@inquirer/prompts': 7.8.4(@types/node@24.10.1)
'@napi-rs/cross-toolchain': 1.0.3
@@ -8030,39 +6948,21 @@ snapshots:
'@napi-rs/wasm-tools-win32-ia32-msvc': 1.0.1
'@napi-rs/wasm-tools-win32-x64-msvc': 1.0.1
- '@noble/ciphers@1.2.1': {}
-
'@noble/ciphers@1.3.0': {}
- '@noble/curves@1.4.2':
- dependencies:
- '@noble/hashes': 1.4.0
-
- '@noble/curves@1.8.0':
- dependencies:
- '@noble/hashes': 1.7.0
-
- '@noble/curves@1.8.1':
+ '@noble/curves@1.2.0':
dependencies:
- '@noble/hashes': 1.7.1
+ '@noble/hashes': 1.3.2
'@noble/curves@1.9.1':
dependencies:
'@noble/hashes': 1.8.0
- '@noble/curves@1.9.2':
- dependencies:
- '@noble/hashes': 1.8.0
-
'@noble/curves@1.9.6':
dependencies:
'@noble/hashes': 1.8.0
- '@noble/hashes@1.4.0': {}
-
- '@noble/hashes@1.7.0': {}
-
- '@noble/hashes@1.7.1': {}
+ '@noble/hashes@1.3.2': {}
'@noble/hashes@1.8.0': {}
@@ -8473,11 +7373,6 @@ snapshots:
dependencies:
'@noble/hashes': 1.8.0
- '@paulmillr/qr@0.2.1': {}
-
- '@pkgjs/parseargs@0.11.0':
- optional: true
-
'@pkgr/core@0.2.9': {}
'@prisma/instrumentation@6.19.0(@opentelemetry/api@1.9.0)':
@@ -8495,315 +7390,14 @@ snapshots:
react-dom: 18.3.1(react@18.3.1)
react-promise-suspense: 0.3.4
- '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)':
- dependencies:
- big.js: 6.2.2
- dayjs: 1.11.13
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)
- transitivePeerDependencies:
- - bufferutil
- - typescript
- - utf-8-validate
- - zod
-
- '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- big.js: 6.2.2
- dayjs: 1.11.13
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- transitivePeerDependencies:
- - bufferutil
- - typescript
- - utf-8-validate
- - zod
-
- '@reown/appkit-controllers@1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)
- '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- valtio: 1.13.2(react@18.3.1)
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - encoding
- - ioredis
- - react
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@reown/appkit-pay@1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-controllers': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-ui': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-utils': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(react@18.3.1))(zod@3.25.76)
- lit: 3.3.0
- valtio: 1.13.2(react@18.3.1)
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - encoding
- - ioredis
- - react
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@reown/appkit-polyfills@1.7.8':
- dependencies:
- buffer: 6.0.3
-
- '@reown/appkit-scaffold-ui@1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(react@18.3.1))(zod@3.25.76)':
- dependencies:
- '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-controllers': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-ui': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-utils': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(react@18.3.1))(zod@3.25.76)
- '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)
- lit: 3.3.0
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - encoding
- - ioredis
- - react
- - typescript
- - uploadthing
- - utf-8-validate
- - valtio
- - zod
-
- '@reown/appkit-ui@1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-controllers': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)
- lit: 3.3.0
- qrcode: 1.5.3
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - encoding
- - ioredis
- - react
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@reown/appkit-utils@1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(react@18.3.1))(zod@3.25.76)':
- dependencies:
- '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-controllers': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-polyfills': 1.7.8
- '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)
- '@walletconnect/logger': 2.1.2
- '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- valtio: 1.13.2(react@18.3.1)
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - encoding
- - ioredis
- - react
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@reown/appkit-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)':
- dependencies:
- '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)
- '@reown/appkit-polyfills': 1.7.8
- '@walletconnect/logger': 2.1.2
- zod: 3.22.4
- transitivePeerDependencies:
- - bufferutil
- - typescript
- - utf-8-validate
-
- '@reown/appkit@1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-controllers': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-pay': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-polyfills': 1.7.8
- '@reown/appkit-scaffold-ui': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(react@18.3.1))(zod@3.25.76)
- '@reown/appkit-ui': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@reown/appkit-utils': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(react@18.3.1))(zod@3.25.76)
- '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)
- '@walletconnect/types': 2.21.0(ioredis@5.6.1)
- '@walletconnect/universal-provider': 2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- bs58: 6.0.0
- valtio: 1.13.2(react@18.3.1)
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - encoding
- - ioredis
- - react
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- events: 3.3.0
- transitivePeerDependencies:
- - bufferutil
- - typescript
- - utf-8-validate
- - zod
-
- '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@safe-global/safe-gateway-typescript-sdk': 3.23.1
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- transitivePeerDependencies:
- - bufferutil
- - typescript
- - utf-8-validate
- - zod
-
- '@safe-global/safe-gateway-typescript-sdk@3.23.1': {}
-
- '@scure/base@1.1.9': {}
-
'@scure/base@1.2.6': {}
- '@scure/bip32@1.4.0':
- dependencies:
- '@noble/curves': 1.4.2
- '@noble/hashes': 1.4.0
- '@scure/base': 1.1.9
-
- '@scure/bip32@1.6.2':
- dependencies:
- '@noble/curves': 1.8.1
- '@noble/hashes': 1.7.1
- '@scure/base': 1.2.6
-
'@scure/bip32@1.7.0':
dependencies:
'@noble/curves': 1.9.6
'@noble/hashes': 1.8.0
'@scure/base': 1.2.6
- '@scure/bip39@1.3.0':
- dependencies:
- '@noble/hashes': 1.4.0
- '@scure/base': 1.1.9
-
- '@scure/bip39@1.5.4':
- dependencies:
- '@noble/hashes': 1.7.1
- '@scure/base': 1.2.6
-
'@scure/bip39@1.6.0':
dependencies:
'@noble/hashes': 1.8.0
@@ -8914,7 +7508,7 @@ snapshots:
'@sentry/node-core': 10.27.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.38.0)
'@sentry/opentelemetry': 10.27.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.38.0)
import-in-the-middle: 2.0.0
- minimatch: 9.0.5
+ minimatch: 10.2.4
transitivePeerDependencies:
- supports-color
@@ -8937,21 +7531,6 @@ snapshots:
dependencies:
'@sinonjs/commons': 3.0.1
- '@socket.io/component-emitter@3.1.2': {}
-
- '@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))':
- dependencies:
- '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
-
- '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))':
- dependencies:
- '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
- '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)
-
- '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))':
- dependencies:
- '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
-
'@solana/accounts@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)':
dependencies:
'@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)
@@ -8984,7 +7563,7 @@ snapshots:
dependencies:
'@solana/buffer-layout': 4.0.1
'@solana/web3.js': 1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)
- bigint-buffer: 1.1.5
+ bigint-buffer: four-flap-bigint-buffer@1.1.6
bignumber.js: 9.2.0
transitivePeerDependencies:
- bufferutil
@@ -9407,13 +7986,13 @@ snapshots:
'@solana/web3.js@1.98.4(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)':
dependencies:
- '@babel/runtime': 7.28.2
+ '@babel/runtime': 7.28.4
'@noble/curves': 1.9.6
'@noble/hashes': 1.8.0
'@solana/buffer-layout': 4.0.1
'@solana/codecs-numbers': 2.3.0(typescript@5.8.3)
agentkeepalive: 4.5.0
- bn.js: 5.2.2
+ bn.js: 5.2.3
borsh: 0.7.0
bs58: 4.0.1
buffer: 6.0.3
@@ -9428,6 +8007,26 @@ snapshots:
- typescript
- utf-8-validate
+ '@spruceid/siwe-parser@2.1.2':
+ dependencies:
+ '@noble/hashes': 1.8.0
+ apg-js: 4.4.0
+ uri-js: 4.4.1
+ valid-url: 1.0.9
+
+ '@stablelib/binary@1.0.1':
+ dependencies:
+ '@stablelib/int': 1.0.1
+
+ '@stablelib/int@1.0.1': {}
+
+ '@stablelib/random@1.0.2':
+ dependencies:
+ '@stablelib/binary': 1.0.1
+ '@stablelib/wipe': 1.0.1
+
+ '@stablelib/wipe@1.0.1': {}
+
'@standard-schema/spec@1.0.0': {}
'@supabase/auth-js@2.71.1':
@@ -9477,24 +8076,21 @@ snapshots:
dependencies:
tslib: 2.8.1
- '@tanstack/query-core@5.83.1': {}
-
- '@tanstack/react-query@5.84.1(react@18.3.1)':
- dependencies:
- '@tanstack/query-core': 5.83.1
- react: 18.3.1
-
'@taplo/cli@0.7.0': {}
- '@tootallnate/once@2.0.0': {}
+ '@tootallnate/once@3.0.1': {}
- '@tsconfig/node10@1.0.11': {}
+ '@tsconfig/node10@1.0.12':
+ optional: true
- '@tsconfig/node12@1.0.11': {}
+ '@tsconfig/node12@1.0.11':
+ optional: true
- '@tsconfig/node14@1.0.3': {}
+ '@tsconfig/node14@1.0.3':
+ optional: true
- '@tsconfig/node16@1.0.4': {}
+ '@tsconfig/node16@1.0.4':
+ optional: true
'@tybys/wasm-util@0.10.0':
dependencies:
@@ -9550,16 +8146,12 @@ snapshots:
'@types/culori@4.0.1': {}
- '@types/debug@4.1.12':
- dependencies:
- '@types/ms': 2.1.0
-
'@types/escape-html@1.0.4': {}
'@types/express-serve-static-core@4.19.3':
dependencies:
'@types/node': 24.10.1
- '@types/qs': 6.9.15
+ '@types/qs': 6.14.0
'@types/range-parser': 1.2.7
'@types/send': 0.17.4
@@ -9573,7 +8165,7 @@ snapshots:
dependencies:
'@types/body-parser': 1.19.5
'@types/express-serve-static-core': 4.19.3
- '@types/qs': 6.9.15
+ '@types/qs': 6.14.0
'@types/serve-static': 1.15.7
'@types/http-errors@2.0.4': {}
@@ -9597,14 +8189,10 @@ snapshots:
'@types/lodash@4.17.14': {}
- '@types/lodash@4.17.20': {}
-
'@types/methods@1.1.4': {}
'@types/mime@1.3.5': {}
- '@types/ms@2.1.0': {}
-
'@types/mysql@2.15.27':
dependencies:
'@types/node': 22.19.1
@@ -9615,6 +8203,10 @@ snapshots:
dependencies:
undici-types: 6.21.0
+ '@types/node@22.7.5':
+ dependencies:
+ undici-types: 6.19.8
+
'@types/node@24.10.1':
dependencies:
undici-types: 7.16.0
@@ -9639,14 +8231,14 @@ snapshots:
'@types/phoenix@1.6.6': {}
- '@types/qs@6.9.15': {}
+ '@types/qs@6.14.0': {}
'@types/range-parser@1.2.7': {}
'@types/request@2.48.12':
dependencies:
'@types/caseless': 0.12.5
- '@types/node': 24.10.1
+ '@types/node': 22.19.1
'@types/tough-cookie': 4.0.5
form-data: 2.5.5
@@ -9683,8 +8275,6 @@ snapshots:
'@types/triple-beam@1.3.5': {}
- '@types/trusted-types@2.0.7': {}
-
'@types/uuid@8.3.4': {}
'@types/ws@7.4.7':
@@ -9768,591 +8358,55 @@ snapshots:
'@vercel/oidc@3.0.3': {}
- '@wagmi/connectors@5.11.2(@tanstack/react-query@5.84.1(react@18.3.1))(@wagmi/core@2.21.2(@tanstack/query-core@5.83.1)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.5(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)':
- dependencies:
- '@base-org/account': 1.1.1(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76)
- '@coinbase/wallet-sdk': 4.3.6(bufferutil@4.0.9)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.25.76)
- '@gemini-wallet/core': 0.2.0(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))
- '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)
- '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@wagmi/core': 2.21.2(@tanstack/query-core@5.83.1)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))
- '@walletconnect/ethereum-provider': 2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- cbw-sdk: '@coinbase/wallet-sdk@3.9.3'
- porto: 0.2.19(@tanstack/react-query@5.84.1(react@18.3.1))(@wagmi/core@2.21.2(@tanstack/query-core@5.83.1)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.5(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- optionalDependencies:
- typescript: 5.8.3
+ '@x402/core@2.4.0':
+ dependencies:
+ zod: 3.25.76
+
+ '@x402/evm@2.4.0(bufferutil@4.0.9)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.8.3)(utf-8-validate@5.0.10)':
+ dependencies:
+ '@x402/core': 2.4.0
+ '@x402/extensions': 2.4.0(bufferutil@4.0.9)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.8.3)(utf-8-validate@5.0.10)
+ viem: 2.45.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
+ zod: 3.25.76
transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@tanstack/react-query'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- bufferutil
- - db0
- - encoding
- - immer
- - ioredis
- - react
- - supports-color
- - uploadthing
- - use-sync-external-store
+ - ethers
+ - typescript
- utf-8-validate
- - wagmi
- - zod
- '@wagmi/core@2.21.2(@tanstack/query-core@5.83.1)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))':
+ '@x402/express@2.4.0(bufferutil@4.0.9)(encoding@0.1.13)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(express@4.22.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))':
dependencies:
- eventemitter3: 5.0.1
- mipd: 0.0.7(typescript@5.8.3)
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- zustand: 5.0.0(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1))
- optionalDependencies:
- '@tanstack/query-core': 5.83.1
- typescript: 5.8.3
- transitivePeerDependencies:
- - '@types/react'
- - immer
- - react
- - use-sync-external-store
-
- '@walletconnect/core@2.21.0(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@walletconnect/heartbeat': 1.2.2
- '@walletconnect/jsonrpc-provider': 1.0.14
- '@walletconnect/jsonrpc-types': 1.0.4
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1)
- '@walletconnect/logger': 2.1.2
- '@walletconnect/relay-api': 1.0.11
- '@walletconnect/relay-auth': 1.1.0
- '@walletconnect/safe-json': 1.0.2
- '@walletconnect/time': 1.0.2
- '@walletconnect/types': 2.21.0(ioredis@5.6.1)
- '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@walletconnect/window-getters': 1.0.1
- es-toolkit: 1.33.0
- events: 3.3.0
- uint8arrays: 3.1.0
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - ioredis
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@walletconnect/core@2.21.1(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@walletconnect/heartbeat': 1.2.2
- '@walletconnect/jsonrpc-provider': 1.0.14
- '@walletconnect/jsonrpc-types': 1.0.4
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1)
- '@walletconnect/logger': 2.1.2
- '@walletconnect/relay-api': 1.0.11
- '@walletconnect/relay-auth': 1.1.0
- '@walletconnect/safe-json': 1.0.2
- '@walletconnect/time': 1.0.2
- '@walletconnect/types': 2.21.1(ioredis@5.6.1)
- '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@walletconnect/window-getters': 1.0.1
- es-toolkit: 1.33.0
- events: 3.3.0
- uint8arrays: 3.1.0
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - ioredis
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@walletconnect/environment@1.0.1':
- dependencies:
- tslib: 1.14.1
-
- '@walletconnect/ethereum-provider@2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@reown/appkit': 1.7.8(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13)
- '@walletconnect/jsonrpc-provider': 1.0.14
- '@walletconnect/jsonrpc-types': 1.0.4
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1)
- '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@walletconnect/types': 2.21.1(ioredis@5.6.1)
- '@walletconnect/universal-provider': 2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- events: 3.3.0
+ '@coinbase/cdp-sdk': 1.33.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)
+ '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
+ '@x402/core': 2.4.0
+ '@x402/extensions': 2.4.0(bufferutil@4.0.9)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.8.3)(utf-8-validate@5.0.10)
+ express: 4.22.0
+ viem: 2.45.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
+ zod: 3.25.76
transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- bufferutil
- - db0
- - encoding
- - ioredis
- - react
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@walletconnect/events@1.0.1':
- dependencies:
- keyvaluestorage-interface: 1.0.0
- tslib: 1.14.1
-
- '@walletconnect/heartbeat@1.2.2':
- dependencies:
- '@walletconnect/events': 1.0.1
- '@walletconnect/time': 1.0.2
- events: 3.3.0
-
- '@walletconnect/jsonrpc-http-connection@1.0.8(encoding@0.1.13)':
- dependencies:
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/safe-json': 1.0.2
- cross-fetch: 3.1.8(encoding@0.1.13)
- events: 3.3.0
- transitivePeerDependencies:
+ - debug
- encoding
-
- '@walletconnect/jsonrpc-provider@1.0.14':
- dependencies:
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/safe-json': 1.0.2
- events: 3.3.0
-
- '@walletconnect/jsonrpc-types@1.0.4':
- dependencies:
- events: 3.3.0
- keyvaluestorage-interface: 1.0.0
-
- '@walletconnect/jsonrpc-utils@1.0.8':
- dependencies:
- '@walletconnect/environment': 1.0.1
- '@walletconnect/jsonrpc-types': 1.0.4
- tslib: 1.14.1
-
- '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)':
- dependencies:
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/safe-json': 1.0.2
- events: 3.3.0
- ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- transitivePeerDependencies:
- - bufferutil
- - utf-8-validate
-
- '@walletconnect/keyvaluestorage@1.1.1(ioredis@5.6.1)':
- dependencies:
- '@walletconnect/safe-json': 1.0.2
- idb-keyval: 6.2.2
- unstorage: 1.16.1(idb-keyval@6.2.2)(ioredis@5.6.1)
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - db0
- - ioredis
- - uploadthing
-
- '@walletconnect/logger@2.1.2':
- dependencies:
- '@walletconnect/safe-json': 1.0.2
- pino: 7.11.0
-
- '@walletconnect/relay-api@1.0.11':
- dependencies:
- '@walletconnect/jsonrpc-types': 1.0.4
-
- '@walletconnect/relay-auth@1.1.0':
- dependencies:
- '@noble/curves': 1.8.0
- '@noble/hashes': 1.7.0
- '@walletconnect/safe-json': 1.0.2
- '@walletconnect/time': 1.0.2
- uint8arrays: 3.1.0
-
- '@walletconnect/safe-json@1.0.2':
- dependencies:
- tslib: 1.14.1
-
- '@walletconnect/sign-client@2.21.0(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@walletconnect/core': 2.21.0(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@walletconnect/events': 1.0.1
- '@walletconnect/heartbeat': 1.2.2
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/logger': 2.1.2
- '@walletconnect/time': 1.0.2
- '@walletconnect/types': 2.21.0(ioredis@5.6.1)
- '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- events: 3.3.0
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - ioredis
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@walletconnect/sign-client@2.21.1(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@walletconnect/core': 2.21.1(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@walletconnect/events': 1.0.1
- '@walletconnect/heartbeat': 1.2.2
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/logger': 2.1.2
- '@walletconnect/time': 1.0.2
- '@walletconnect/types': 2.21.1(ioredis@5.6.1)
- '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- events: 3.3.0
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - ioredis
+ - ethers
+ - fastestsmallesttextencoderdecoder
- typescript
- - uploadthing
- utf-8-validate
- - zod
-
- '@walletconnect/time@1.0.2':
- dependencies:
- tslib: 1.14.1
+ - ws
- '@walletconnect/types@2.21.0(ioredis@5.6.1)':
+ '@x402/extensions@2.4.0(bufferutil@4.0.9)(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.8.3)(utf-8-validate@5.0.10)':
dependencies:
- '@walletconnect/events': 1.0.1
- '@walletconnect/heartbeat': 1.2.2
- '@walletconnect/jsonrpc-types': 1.0.4
- '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1)
- '@walletconnect/logger': 2.1.2
- events: 3.3.0
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - db0
- - ioredis
- - uploadthing
-
- '@walletconnect/types@2.21.1(ioredis@5.6.1)':
- dependencies:
- '@walletconnect/events': 1.0.1
- '@walletconnect/heartbeat': 1.2.2
- '@walletconnect/jsonrpc-types': 1.0.4
- '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1)
- '@walletconnect/logger': 2.1.2
- events: 3.3.0
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - db0
- - ioredis
- - uploadthing
-
- '@walletconnect/universal-provider@2.21.0(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@walletconnect/events': 1.0.1
- '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13)
- '@walletconnect/jsonrpc-provider': 1.0.14
- '@walletconnect/jsonrpc-types': 1.0.4
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1)
- '@walletconnect/logger': 2.1.2
- '@walletconnect/sign-client': 2.21.0(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@walletconnect/types': 2.21.0(ioredis@5.6.1)
- '@walletconnect/utils': 2.21.0(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- es-toolkit: 1.33.0
- events: 3.3.0
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - encoding
- - ioredis
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@walletconnect/universal-provider@2.21.1(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@walletconnect/events': 1.0.1
- '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13)
- '@walletconnect/jsonrpc-provider': 1.0.14
- '@walletconnect/jsonrpc-types': 1.0.4
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1)
- '@walletconnect/logger': 2.1.2
- '@walletconnect/sign-client': 2.21.1(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- '@walletconnect/types': 2.21.1(ioredis@5.6.1)
- '@walletconnect/utils': 2.21.1(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- es-toolkit: 1.33.0
- events: 3.3.0
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - encoding
- - ioredis
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@walletconnect/utils@2.21.0(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@noble/ciphers': 1.2.1
- '@noble/curves': 1.8.1
- '@noble/hashes': 1.7.1
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1)
- '@walletconnect/relay-api': 1.0.11
- '@walletconnect/relay-auth': 1.1.0
- '@walletconnect/safe-json': 1.0.2
- '@walletconnect/time': 1.0.2
- '@walletconnect/types': 2.21.0(ioredis@5.6.1)
- '@walletconnect/window-getters': 1.0.1
- '@walletconnect/window-metadata': 1.0.1
- bs58: 6.0.0
- detect-browser: 5.3.0
- query-string: 7.1.3
- uint8arrays: 3.1.0
- viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - ioredis
- - typescript
- - uploadthing
- - utf-8-validate
- - zod
-
- '@walletconnect/utils@2.21.1(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)':
- dependencies:
- '@noble/ciphers': 1.2.1
- '@noble/curves': 1.8.1
- '@noble/hashes': 1.7.1
- '@walletconnect/jsonrpc-utils': 1.0.8
- '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1)
- '@walletconnect/relay-api': 1.0.11
- '@walletconnect/relay-auth': 1.1.0
- '@walletconnect/safe-json': 1.0.2
- '@walletconnect/time': 1.0.2
- '@walletconnect/types': 2.21.1(ioredis@5.6.1)
- '@walletconnect/window-getters': 1.0.1
- '@walletconnect/window-metadata': 1.0.1
- bs58: 6.0.0
- detect-browser: 5.3.0
- query-string: 7.1.3
- uint8arrays: 3.1.0
- viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
+ '@scure/base': 1.2.6
+ '@x402/core': 2.4.0
+ ajv: 8.18.0
+ siwe: 2.3.2(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
+ tweetnacl: 1.0.3
+ viem: 2.45.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
+ zod: 3.25.76
transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- bufferutil
- - db0
- - ioredis
+ - ethers
- typescript
- - uploadthing
- utf-8-validate
- - zod
-
- '@walletconnect/window-getters@1.0.1':
- dependencies:
- tslib: 1.14.1
-
- '@walletconnect/window-metadata@1.0.1':
- dependencies:
- '@walletconnect/window-getters': 1.0.1
- tslib: 1.14.1
abbrev@2.0.0: {}
@@ -10361,36 +8415,11 @@ snapshots:
typescript: 5.8.3
zod: 3.25.76
- abitype@1.0.8(typescript@5.8.3)(zod@3.22.4):
- optionalDependencies:
- typescript: 5.8.3
- zod: 3.22.4
-
- abitype@1.0.8(typescript@5.8.3)(zod@3.25.76):
- optionalDependencies:
- typescript: 5.8.3
- zod: 3.25.76
-
- abitype@1.0.8(typescript@5.8.3)(zod@4.1.12):
- optionalDependencies:
- typescript: 5.8.3
- zod: 4.1.12
-
- abitype@1.1.1(typescript@5.8.3)(zod@3.22.4):
- optionalDependencies:
- typescript: 5.8.3
- zod: 3.22.4
-
- abitype@1.1.1(typescript@5.8.3)(zod@3.25.76):
+ abitype@1.2.3(typescript@5.8.3)(zod@3.25.76):
optionalDependencies:
typescript: 5.8.3
zod: 3.25.76
- abitype@1.1.1(typescript@5.8.3)(zod@4.1.12):
- optionalDependencies:
- typescript: 5.8.3
- zod: 4.1.12
-
abort-controller@3.0.0:
dependencies:
event-target-shim: 5.0.1
@@ -10404,12 +8433,15 @@ snapshots:
dependencies:
acorn: 8.15.0
- acorn-walk@8.3.2: {}
-
- acorn@8.11.3: {}
+ acorn-walk@8.3.4:
+ dependencies:
+ acorn: 8.15.0
+ optional: true
acorn@8.15.0: {}
+ aes-js@4.0.0-beta.5: {}
+
agent-base@6.0.2:
dependencies:
debug: 4.4.3
@@ -10430,16 +8462,16 @@ snapshots:
'@opentelemetry/api': 1.9.0
zod: 4.1.12
- ajv-formats@3.0.1(ajv@8.16.0):
+ ajv-formats@3.0.1(ajv@8.18.0):
optionalDependencies:
- ajv: 8.16.0
+ ajv: 8.18.0
- ajv@8.16.0:
+ ajv@8.18.0:
dependencies:
fast-deep-equal: 3.1.3
+ fast-uri: 3.1.0
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
- uri-js: 4.4.1
amqplib@0.10.9:
dependencies:
@@ -10475,11 +8507,10 @@ snapshots:
normalize-path: 3.0.0
picomatch: 2.3.1
- arg@4.1.3: {}
+ apg-js@4.4.0: {}
- argparse@1.0.10:
- dependencies:
- sprintf-js: 1.0.3
+ arg@4.1.3:
+ optional: true
argparse@2.0.1: {}
@@ -10489,10 +8520,6 @@ snapshots:
asap@2.0.6: {}
- async-mutex@0.2.6:
- dependencies:
- tslib: 2.8.1
-
async-mutex@0.5.0:
dependencies:
tslib: 2.8.1
@@ -10503,27 +8530,21 @@ snapshots:
async@2.6.4:
dependencies:
- lodash: 4.17.21
+ lodash: 4.17.23
async@3.2.5: {}
asynckit@0.4.0: {}
- atomic-sleep@1.0.0: {}
-
- available-typed-arrays@1.0.7:
+ axios-retry@4.5.0(axios@1.13.5):
dependencies:
- possible-typed-array-names: 1.1.0
-
- axios-retry@4.5.0(axios@1.12.2):
- dependencies:
- axios: 1.12.2
+ axios: 1.13.5
is-retry-allowed: 2.2.0
- axios@1.12.2:
+ axios@1.13.5:
dependencies:
- follow-redirects: 1.15.6
- form-data: 4.0.4
+ follow-redirects: 1.15.11
+ form-data: 4.0.5
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
@@ -10580,26 +8601,18 @@ snapshots:
babel-plugin-jest-hoist: 30.2.0
babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5)
- balanced-match@1.0.2: {}
+ balanced-match@4.0.3: {}
base-x@3.0.11:
dependencies:
safe-buffer: 5.2.1
- base-x@5.0.1: {}
-
base64-js@1.5.1: {}
baseline-browser-mapping@2.8.30: {}
before-after-hook@4.0.0: {}
- big.js@6.2.2: {}
-
- bigint-buffer@1.1.5:
- dependencies:
- bindings: 1.5.0
-
bignumber.js@9.2.0: {}
bindings@1.5.0:
@@ -10608,19 +8621,19 @@ snapshots:
bintrees@1.0.2: {}
- bn.js@5.2.2: {}
+ bn.js@5.2.3: {}
body-parser@1.20.3:
dependencies:
bytes: 3.1.2
content-type: 1.0.5
- debug: 4.4.3
+ debug: 2.6.9
depd: 2.0.0
destroy: 1.2.0
http-errors: 2.0.0
iconv-lite: 0.4.24
on-finished: 2.4.1
- qs: 6.14.1
+ qs: 6.15.0
raw-body: 2.5.2
type-is: 1.6.18
unpipe: 1.0.0
@@ -10631,22 +8644,13 @@ snapshots:
borsh@0.7.0:
dependencies:
- bn.js: 5.2.2
+ bn.js: 5.2.3
bs58: 4.0.1
text-encoding-utf-8: 1.0.2
- bowser@2.11.0: {}
-
- bowser@2.12.1: {}
-
- brace-expansion@1.1.12:
- dependencies:
- balanced-match: 1.0.2
- concat-map: 0.0.1
-
- brace-expansion@2.0.2:
+ brace-expansion@5.0.2:
dependencies:
- balanced-match: 1.0.2
+ balanced-match: 4.0.3
braces@3.0.3:
dependencies:
@@ -10668,10 +8672,6 @@ snapshots:
dependencies:
base-x: 3.0.11
- bs58@6.0.0:
- dependencies:
- base-x: 5.0.1
-
bser@2.1.1:
dependencies:
node-int64: 0.4.0
@@ -10692,6 +8692,7 @@ snapshots:
bufferutil@4.0.9:
dependencies:
node-gyp-build: 4.8.4
+ optional: true
bullmq@5.56.7:
dependencies:
@@ -10714,13 +8715,6 @@ snapshots:
es-errors: 1.3.0
function-bind: 1.1.2
- call-bind@1.0.8:
- dependencies:
- call-bind-apply-helpers: 1.0.2
- es-define-property: 1.0.1
- get-intrinsic: 1.3.0
- set-function-length: 1.2.2
-
call-bound@1.0.4:
dependencies:
call-bind-apply-helpers: 1.0.2
@@ -10772,10 +8766,6 @@ snapshots:
parse5: 7.1.2
parse5-htmlparser2-tree-adapter: 7.0.0
- chokidar@4.0.3:
- dependencies:
- readdirp: 4.1.2
-
ci-info@4.3.1: {}
cjs-module-lexer@1.4.3: {}
@@ -10797,20 +8787,12 @@ snapshots:
dependencies:
typanion: 3.14.0
- cliui@6.0.0:
- dependencies:
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wrap-ansi: 6.2.0
-
cliui@8.0.1:
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 7.0.0
- clsx@1.2.1: {}
-
cluster-key-slot@1.1.2: {}
co@4.6.0: {}
@@ -10860,8 +8842,6 @@ snapshots:
component-emitter@1.3.1: {}
- concat-map@0.0.1: {}
-
config-chain@1.1.13:
dependencies:
ini: 1.3.8
@@ -10875,16 +8855,12 @@ snapshots:
convert-source-map@2.0.0: {}
- cookie-es@1.2.2: {}
-
cookie-signature@1.0.6: {}
cookie@0.7.1: {}
cookiejar@2.1.4: {}
- core-util-is@1.0.3: {}
-
cors@2.8.5:
dependencies:
object-assign: 4.1.1
@@ -10892,36 +8868,19 @@ snapshots:
countries-list@3.1.1: {}
- crc-32@1.2.2: {}
-
- create-require@1.1.1: {}
+ create-require@1.1.1:
+ optional: true
cron-parser@4.9.0:
dependencies:
luxon: 3.4.4
- cross-fetch@3.1.8(encoding@0.1.13):
- dependencies:
- node-fetch: 2.7.0(encoding@0.1.13)
- transitivePeerDependencies:
- - encoding
-
- cross-fetch@4.1.0(encoding@0.1.13):
- dependencies:
- node-fetch: 2.7.0(encoding@0.1.13)
- transitivePeerDependencies:
- - encoding
-
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
- crossws@0.3.5:
- dependencies:
- uncrypto: 0.1.3
-
crypt@0.0.2: {}
css-select@5.1.0:
@@ -10948,34 +8907,24 @@ snapshots:
whatwg-mimetype: 4.0.0
whatwg-url: 14.1.1
- date-fns@2.30.0:
+ debug@2.6.9:
dependencies:
- '@babel/runtime': 7.28.2
+ ms: 2.0.0
- dayjs@1.11.13: {}
+ debug@3.2.7:
+ dependencies:
+ ms: 2.1.3
debug@4.4.3:
dependencies:
ms: 2.1.3
- decamelize@1.2.0: {}
-
decimal.js@10.5.0: {}
- decode-uri-component@0.2.2: {}
-
dedent@1.7.0: {}
deepmerge@4.3.1: {}
- define-data-property@1.1.4:
- dependencies:
- es-define-property: 1.0.0
- es-errors: 1.3.0
- gopd: 1.0.1
-
- defu@6.1.4: {}
-
delay@5.0.0: {}
delayed-stream@1.0.0: {}
@@ -10984,16 +8933,8 @@ snapshots:
depd@2.0.0: {}
- derive-valtio@0.1.0(valtio@1.13.2(react@18.3.1)):
- dependencies:
- valtio: 1.13.2(react@18.3.1)
-
- destr@2.0.5: {}
-
destroy@1.2.0: {}
- detect-browser@5.3.0: {}
-
detect-libc@2.1.2:
optional: true
@@ -11004,11 +8945,7 @@ snapshots:
asap: 2.0.6
wrappy: 1.0.2
- diff@3.5.0: {}
-
- diff@4.0.2: {}
-
- dijkstrajs@1.0.3: {}
+ diff@8.0.3: {}
dom-serializer@2.0.0:
dependencies:
@@ -11045,24 +8982,15 @@ snapshots:
readable-stream: 3.6.2
stream-shift: 1.0.3
- eastasianwidth@0.2.0: {}
-
ecdsa-sig-formatter@1.0.11:
dependencies:
safe-buffer: 5.2.1
- eciesjs@0.4.15:
- dependencies:
- '@ecies/ciphers': 0.2.4(@noble/ciphers@1.3.0)
- '@noble/ciphers': 1.3.0
- '@noble/curves': 1.9.6
- '@noble/hashes': 1.8.0
-
editorconfig@1.0.4:
dependencies:
'@one-ini/wasm': 0.1.1
commander: 10.0.1
- minimatch: 9.0.1
+ minimatch: 10.2.4
semver: 7.7.3
ee-first@1.1.1: {}
@@ -11081,12 +9009,8 @@ snapshots:
emoji-regex@8.0.0: {}
- emoji-regex@9.2.2: {}
-
enabled@2.0.0: {}
- encode-utf8@1.0.3: {}
-
encodeurl@1.0.2: {}
encodeurl@2.0.0: {}
@@ -11100,20 +9024,6 @@ snapshots:
dependencies:
once: 1.4.0
- engine.io-client@6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10):
- dependencies:
- '@socket.io/component-emitter': 3.1.2
- debug: 4.4.3
- engine.io-parser: 5.2.3
- ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- xmlhttprequest-ssl: 2.1.2
- transitivePeerDependencies:
- - bufferutil
- - supports-color
- - utf-8-validate
-
- engine.io-parser@5.2.3: {}
-
entities@4.5.0: {}
environment@1.1.0: {}
@@ -11122,10 +9032,6 @@ snapshots:
dependencies:
is-arrayish: 0.2.1
- es-define-property@1.0.0:
- dependencies:
- get-intrinsic: 1.3.0
-
es-define-property@1.0.1: {}
es-errors@1.3.0: {}
@@ -11141,8 +9047,6 @@ snapshots:
has-tostringtag: 1.0.2
hasown: 2.0.2
- es-toolkit@1.33.0: {}
-
es-toolkit@1.39.10: {}
es6-promise@4.2.8: {}
@@ -11180,6 +9084,35 @@ snapshots:
'@esbuild/win32-ia32': 0.25.8
'@esbuild/win32-x64': 0.25.8
+ esbuild@0.27.2:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.2
+ '@esbuild/android-arm': 0.27.2
+ '@esbuild/android-arm64': 0.27.2
+ '@esbuild/android-x64': 0.27.2
+ '@esbuild/darwin-arm64': 0.27.2
+ '@esbuild/darwin-x64': 0.27.2
+ '@esbuild/freebsd-arm64': 0.27.2
+ '@esbuild/freebsd-x64': 0.27.2
+ '@esbuild/linux-arm': 0.27.2
+ '@esbuild/linux-arm64': 0.27.2
+ '@esbuild/linux-ia32': 0.27.2
+ '@esbuild/linux-loong64': 0.27.2
+ '@esbuild/linux-mips64el': 0.27.2
+ '@esbuild/linux-ppc64': 0.27.2
+ '@esbuild/linux-riscv64': 0.27.2
+ '@esbuild/linux-s390x': 0.27.2
+ '@esbuild/linux-x64': 0.27.2
+ '@esbuild/netbsd-arm64': 0.27.2
+ '@esbuild/netbsd-x64': 0.27.2
+ '@esbuild/openbsd-arm64': 0.27.2
+ '@esbuild/openbsd-x64': 0.27.2
+ '@esbuild/openharmony-arm64': 0.27.2
+ '@esbuild/sunos-x64': 0.27.2
+ '@esbuild/win32-arm64': 0.27.2
+ '@esbuild/win32-ia32': 0.27.2
+ '@esbuild/win32-x64': 0.27.2
+
escalade@3.2.0: {}
escape-html@1.0.3: {}
@@ -11188,43 +9121,20 @@ snapshots:
escape-string-regexp@2.0.0: {}
- esprima@4.0.1: {}
-
etag@1.8.1: {}
- eth-block-tracker@7.1.0:
+ ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10):
dependencies:
- '@metamask/eth-json-rpc-provider': 1.0.1
- '@metamask/safe-event-emitter': 3.1.2
- '@metamask/utils': 5.0.2
- json-rpc-random-id: 1.0.1
- pify: 3.0.0
+ '@adraffy/ens-normalize': 1.10.1
+ '@noble/curves': 1.2.0
+ '@noble/hashes': 1.3.2
+ '@types/node': 22.7.5
+ aes-js: 4.0.0-beta.5
+ tslib: 2.7.0
+ ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)
transitivePeerDependencies:
- - supports-color
-
- eth-json-rpc-filters@6.0.1:
- dependencies:
- '@metamask/safe-event-emitter': 3.1.2
- async-mutex: 0.2.6
- eth-query: 2.1.2
- json-rpc-engine: 6.1.0
- pify: 5.0.0
-
- eth-query@2.1.2:
- dependencies:
- json-rpc-random-id: 1.0.1
- xtend: 4.0.2
-
- eth-rpc-errors@4.0.3:
- dependencies:
- fast-safe-stringify: 2.1.1
-
- ethereum-cryptography@2.2.1:
- dependencies:
- '@noble/curves': 1.4.2
- '@noble/hashes': 1.4.0
- '@scure/bip32': 1.4.0
- '@scure/bip39': 1.3.0
+ - bufferutil
+ - utf-8-validate
event-stream@3.3.4:
dependencies:
@@ -11238,8 +9148,6 @@ snapshots:
event-target-shim@5.0.1: {}
- eventemitter2@6.4.9: {}
-
eventemitter3@5.0.1: {}
events@3.3.0: {}
@@ -11288,7 +9196,7 @@ snapshots:
content-type: 1.0.5
cookie: 0.7.1
cookie-signature: 1.0.6
- debug: 4.4.3
+ debug: 2.6.9
depd: 2.0.0
encodeurl: 2.0.0
escape-html: 1.0.3
@@ -11302,7 +9210,7 @@ snapshots:
parseurl: 1.3.3
path-to-regexp: 0.1.12
proxy-addr: 2.0.7
- qs: 6.14.1
+ qs: 6.15.0
range-parser: 1.2.1
safe-buffer: 5.2.1
send: 0.19.0
@@ -11317,11 +9225,6 @@ snapshots:
extend@3.0.2: {}
- extension-port-stream@3.0.0:
- dependencies:
- readable-stream: 4.5.2
- webextension-polyfill: 0.10.0
-
eyes@0.1.8: {}
fast-content-type-parse@3.0.0: {}
@@ -11340,15 +9243,18 @@ snapshots:
fast-json-stable-stringify@2.1.0: {}
- fast-redact@3.5.0: {}
-
fast-safe-stringify@2.1.1: {}
fast-stable-stringify@1.0.0: {}
- fast-xml-parser@4.4.1:
+ fast-uri@3.1.0: {}
+
+ fast-xml-builder@1.0.0: {}
+
+ fast-xml-parser@5.4.1:
dependencies:
- strnum: 1.0.5
+ fast-xml-builder: 1.0.0
+ strnum: 2.1.2
fastestsmallesttextencoderdecoder@1.0.22: {}
@@ -11379,17 +9285,15 @@ snapshots:
filelist@1.0.4:
dependencies:
- minimatch: 5.1.6
+ minimatch: 10.2.4
fill-range@7.1.1:
dependencies:
to-regex-range: 5.0.1
- filter-obj@1.1.0: {}
-
finalhandler@1.3.1:
dependencies:
- debug: 4.4.3
+ debug: 2.6.9
encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
@@ -11406,16 +9310,7 @@ snapshots:
fn.name@1.1.0: {}
- follow-redirects@1.15.6: {}
-
- for-each@0.3.5:
- dependencies:
- is-callable: 1.2.7
-
- foreground-child@3.2.1:
- dependencies:
- cross-spawn: 7.0.6
- signal-exit: 4.1.0
+ follow-redirects@1.15.11: {}
form-data@2.5.5:
dependencies:
@@ -11434,6 +9329,14 @@ snapshots:
hasown: 2.0.2
mime-types: 2.1.35
+ 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
+
formatly@0.3.0:
dependencies:
fd-package-json: 2.0.0
@@ -11447,12 +9350,16 @@ snapshots:
'@paralleldrive/cuid2': 2.2.2
dezalgo: 1.0.4
once: 1.4.0
- qs: 6.14.1
+ qs: 6.15.0
forwarded-parse@2.1.2: {}
forwarded@0.2.0: {}
+ four-flap-bigint-buffer@1.1.6:
+ dependencies:
+ bindings: 1.5.0
+
fresh@0.5.2: {}
from@0.1.7: {}
@@ -11543,7 +9450,7 @@ snapshots:
git-diff@2.0.6:
dependencies:
chalk: 2.4.2
- diff: 3.5.0
+ diff: 8.0.3
loglevel: 1.9.1
shelljs: 0.8.5
shelljs.exec: 1.1.8
@@ -11552,21 +9459,18 @@ snapshots:
dependencies:
is-glob: 4.0.3
- glob@10.4.2:
+ glob@13.0.1:
dependencies:
- foreground-child: 3.2.1
- jackspeak: 3.4.0
- minimatch: 9.0.5
+ minimatch: 10.2.4
minipass: 7.1.2
- package-json-from-dist: 1.0.0
- path-scurry: 1.11.1
+ path-scurry: 2.0.1
glob@7.2.3:
dependencies:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
- minimatch: 3.1.2
+ minimatch: 10.2.4
once: 1.4.0
path-is-absolute: 1.0.1
@@ -11598,10 +9502,6 @@ snapshots:
google-logging-utils@1.1.3: {}
- gopd@1.0.1:
- dependencies:
- get-intrinsic: 1.3.0
-
gopd@1.2.0: {}
graceful-fs@4.2.11: {}
@@ -11621,18 +9521,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- h3@1.15.4:
- dependencies:
- cookie-es: 1.2.2
- crossws: 0.3.5
- defu: 6.1.4
- destr: 2.0.5
- iron-webcrypto: 1.2.1
- node-mock-http: 1.0.2
- radix3: 1.1.2
- ufo: 1.6.1
- uncrypto: 0.1.3
-
handlebars@4.7.8:
dependencies:
minimist: 1.2.8
@@ -11646,10 +9534,6 @@ snapshots:
has-flag@4.0.0: {}
- has-property-descriptors@1.0.2:
- dependencies:
- es-define-property: 1.0.0
-
has-symbols@1.1.0: {}
has-tostringtag@1.0.2:
@@ -11660,8 +9544,6 @@ snapshots:
dependencies:
function-bind: 1.1.2
- hono@4.9.10: {}
-
html-encoding-sniffer@4.0.0:
dependencies:
whatwg-encoding: 3.1.1
@@ -11685,12 +9567,12 @@ snapshots:
domutils: 3.1.0
entities: 4.5.0
- http-cookie-agent@7.0.1(tough-cookie@4.1.4)(undici@7.10.0):
+ http-cookie-agent@7.0.1(tough-cookie@4.1.4)(undici@7.18.2):
dependencies:
agent-base: 7.1.3
tough-cookie: 4.1.4
optionalDependencies:
- undici: 7.10.0
+ undici: 7.18.2
http-errors@2.0.0:
dependencies:
@@ -11702,7 +9584,7 @@ snapshots:
http-proxy-agent@5.0.0:
dependencies:
- '@tootallnate/once': 2.0.0
+ '@tootallnate/once': 3.0.1
agent-base: 6.0.2
debug: 4.4.3
transitivePeerDependencies:
@@ -11745,10 +9627,6 @@ snapshots:
dependencies:
safer-buffer: 2.1.2
- idb-keyval@6.2.1: {}
-
- idb-keyval@6.2.2: {}
-
ieee754@1.2.1: {}
import-in-the-middle@2.0.0:
@@ -11804,21 +9682,12 @@ snapshots:
ipaddr.js@2.2.0: {}
- iron-webcrypto@1.2.1: {}
-
- is-arguments@1.2.0:
- dependencies:
- call-bound: 1.0.4
- has-tostringtag: 1.0.2
-
is-arrayish@0.2.1: {}
is-arrayish@0.3.2: {}
is-buffer@1.1.6: {}
- is-callable@1.2.7: {}
-
is-core-module@2.13.1:
dependencies:
hasown: 2.0.2
@@ -11835,13 +9704,6 @@ snapshots:
is-generator-fn@2.1.0: {}
- is-generator-function@1.1.0:
- dependencies:
- call-bound: 1.0.4
- get-proto: 1.0.1
- has-tostringtag: 1.0.2
- safe-regex-test: 1.1.0
-
is-glob@4.0.3:
dependencies:
is-extglob: 2.1.1
@@ -11850,25 +9712,10 @@ snapshots:
is-potential-custom-element-name@1.0.1: {}
- is-regex@1.2.1:
- dependencies:
- call-bound: 1.0.4
- gopd: 1.2.0
- has-tostringtag: 1.0.2
- hasown: 2.0.2
-
is-retry-allowed@2.2.0: {}
is-stream@2.0.1: {}
- is-typed-array@1.1.15:
- dependencies:
- which-typed-array: 1.1.19
-
- isarray@1.0.0: {}
-
- isarray@2.0.5: {}
-
isexe@2.0.0: {}
isexe@3.1.1: {}
@@ -11877,14 +9724,6 @@ snapshots:
dependencies:
ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)):
- dependencies:
- ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
-
- isows@1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)):
- dependencies:
- ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)
-
isows@1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)):
dependencies:
ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)
@@ -11920,18 +9759,12 @@ snapshots:
html-escaper: 2.0.2
istanbul-lib-report: 3.0.1
- jackspeak@3.4.0:
- dependencies:
- '@isaacs/cliui': 8.0.2
- optionalDependencies:
- '@pkgjs/parseargs': 0.11.0
-
jake@10.9.1:
dependencies:
async: 3.2.5
chalk: 4.1.2
filelist: 1.0.4
- minimatch: 3.1.2
+ minimatch: 10.2.4
jayson@4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10):
dependencies:
@@ -12013,7 +9846,7 @@ snapshots:
chalk: 4.1.2
ci-info: 4.3.1
deepmerge: 4.3.1
- glob: 10.4.2
+ glob: 13.0.1
graceful-fs: 4.2.11
jest-circus: 30.2.0
jest-docblock: 30.2.0
@@ -12046,7 +9879,7 @@ snapshots:
chalk: 4.1.2
ci-info: 4.3.1
deepmerge: 4.3.1
- glob: 10.4.2
+ glob: 13.0.1
graceful-fs: 4.2.11
jest-circus: 30.2.0
jest-docblock: 30.2.0
@@ -12213,7 +10046,7 @@ snapshots:
chalk: 4.1.2
cjs-module-lexer: 2.1.1
collect-v8-coverage: 1.0.2
- glob: 10.4.2
+ glob: 13.0.1
graceful-fs: 4.2.11
jest-haste-map: 30.2.0
jest-message-util: 30.2.0
@@ -12313,7 +10146,7 @@ snapshots:
dependencies:
config-chain: 1.1.13
editorconfig: 1.0.4
- glob: 10.4.2
+ glob: 13.0.1
js-cookie: 3.0.5
nopt: 7.2.1
@@ -12321,11 +10154,6 @@ snapshots:
js-tokens@4.0.0: {}
- js-yaml@3.14.1:
- dependencies:
- argparse: 1.0.10
- esprima: 4.0.1
-
js-yaml@4.1.1:
dependencies:
argparse: 2.0.1
@@ -12370,13 +10198,6 @@ snapshots:
json-parse-even-better-errors@4.0.0: {}
- json-rpc-engine@6.1.0:
- dependencies:
- '@metamask/safe-event-emitter': 2.0.0
- eth-rpc-errors: 4.0.3
-
- json-rpc-random-id@1.0.1: {}
-
json-schema-traverse@1.0.0: {}
json-schema@0.4.0: {}
@@ -12396,14 +10217,6 @@ snapshots:
jwa: 2.0.1
safe-buffer: 5.2.1
- keccak@3.0.4:
- dependencies:
- node-addon-api: 2.0.2
- node-gyp-build: 4.8.4
- readable-stream: 3.6.2
-
- keyvaluestorage-interface@1.0.0: {}
-
knip@5.70.1(@types/node@22.19.1)(typescript@5.8.3):
dependencies:
'@nodelib/fs.walk': 1.2.8
@@ -12429,10 +10242,10 @@ snapshots:
leven@3.1.0: {}
- libpq@1.8.15:
+ libpq@1.9.0:
dependencies:
bindings: 1.5.0
- nan: 2.22.2
+ nan: 2.23.1
optional: true
lilconfig@3.1.3: {}
@@ -12463,22 +10276,6 @@ snapshots:
rfdc: 1.4.1
wrap-ansi: 9.0.0
- lit-element@4.2.1:
- dependencies:
- '@lit-labs/ssr-dom-shim': 1.4.0
- '@lit/reactive-element': 2.1.1
- lit-html: 3.3.1
-
- lit-html@3.3.1:
- dependencies:
- '@types/trusted-types': 2.0.7
-
- lit@3.3.0:
- dependencies:
- '@lit/reactive-element': 2.1.1
- lit-element: 4.2.1
- lit-html: 3.3.1
-
locate-path@5.0.0:
dependencies:
p-locate: 4.1.0
@@ -12499,7 +10296,7 @@ snapshots:
lodash.repeat@4.1.0: {}
- lodash@4.17.21: {}
+ lodash@4.17.23: {}
log-update@6.1.0:
dependencies:
@@ -12535,6 +10332,8 @@ snapshots:
lru-cache@10.4.3: {}
+ lru-cache@11.2.5: {}
+
lru-cache@5.1.1:
dependencies:
yallist: 3.1.1
@@ -12575,8 +10374,6 @@ snapshots:
methods@1.1.2: {}
- micro-ftch@0.3.1: {}
-
micromatch@4.0.8:
dependencies:
braces: 3.0.3
@@ -12598,34 +10395,20 @@ snapshots:
mimic-function@5.0.1: {}
- minimatch@3.1.2:
- dependencies:
- brace-expansion: 1.1.12
-
- minimatch@5.1.6:
+ minimatch@10.2.4:
dependencies:
- brace-expansion: 2.0.2
-
- minimatch@9.0.1:
- dependencies:
- brace-expansion: 2.0.2
-
- minimatch@9.0.5:
- dependencies:
- brace-expansion: 2.0.2
+ brace-expansion: 5.0.2
minimist@1.2.8: {}
minipass@7.1.2: {}
- mipd@0.0.7(typescript@5.8.3):
- optionalDependencies:
- typescript: 5.8.3
-
mkdirp@1.0.4: {}
module-details-from-path@1.0.4: {}
+ ms@2.0.0: {}
+
ms@2.1.3: {}
msgpackr-extract@3.0.3:
@@ -12644,11 +10427,9 @@ snapshots:
optionalDependencies:
msgpackr-extract: 3.0.3
- multiformats@9.9.0: {}
-
mute-stream@2.0.0: {}
- nan@2.22.2:
+ nan@2.23.1:
optional: true
nano-spawn@1.0.2: {}
@@ -12665,16 +10446,12 @@ snapshots:
node-abort-controller@3.1.1: {}
- node-addon-api@2.0.2: {}
-
node-cleanup@2.1.2: {}
node-domexception@1.0.0: {}
node-ensure@0.0.0: {}
- node-fetch-native@1.6.7: {}
-
node-fetch@2.7.0(encoding@0.1.13):
dependencies:
whatwg-url: 5.0.0
@@ -12692,12 +10469,11 @@ snapshots:
detect-libc: 2.1.2
optional: true
- node-gyp-build@4.8.4: {}
+ node-gyp-build@4.8.4:
+ optional: true
node-int64@0.4.0: {}
- node-mock-http@1.0.2: {}
-
node-releases@2.0.27: {}
nopt@7.2.1:
@@ -12729,22 +10505,10 @@ snapshots:
nwsapi@2.2.16: {}
- obj-multiplex@1.0.0:
- dependencies:
- end-of-stream: 1.4.4
- once: 1.4.0
- readable-stream: 2.3.8
-
object-assign@4.1.1: {}
object-inspect@1.13.4: {}
- ofetch@1.4.1:
- dependencies:
- destr: 2.0.5
- node-fetch-native: 1.6.7
- ufo: 1.6.1
-
ollama-ai-provider@1.2.0(zod@4.1.12):
dependencies:
'@ai-sdk/provider': 1.0.8
@@ -12753,8 +10517,6 @@ snapshots:
optionalDependencies:
zod: 4.1.12
- on-exit-leak-free@0.2.0: {}
-
on-finished@2.4.1:
dependencies:
ee-first: 1.1.1
@@ -12775,93 +10537,14 @@ snapshots:
onetime@7.0.0:
dependencies:
- mimic-function: 5.0.1
-
- openai@5.20.2(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.1.12):
- optionalDependencies:
- ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- zod: 4.1.12
-
- openapi-fetch@0.13.8:
- dependencies:
- openapi-typescript-helpers: 0.0.15
-
- openapi-typescript-helpers@0.0.15: {}
-
- ox@0.6.7(typescript@5.8.3)(zod@3.25.76):
- dependencies:
- '@adraffy/ens-normalize': 1.11.1
- '@noble/curves': 1.9.6
- '@noble/hashes': 1.8.0
- '@scure/bip32': 1.7.0
- '@scure/bip39': 1.6.0
- abitype: 1.1.1(typescript@5.8.3)(zod@3.25.76)
- eventemitter3: 5.0.1
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - zod
-
- ox@0.6.9(typescript@5.8.3)(zod@3.25.76):
- dependencies:
- '@adraffy/ens-normalize': 1.11.1
- '@noble/curves': 1.9.6
- '@noble/hashes': 1.8.0
- '@scure/bip32': 1.7.0
- '@scure/bip39': 1.6.0
- abitype: 1.1.1(typescript@5.8.3)(zod@3.25.76)
- eventemitter3: 5.0.1
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - zod
-
- ox@0.8.6(typescript@5.8.3)(zod@3.22.4):
- dependencies:
- '@adraffy/ens-normalize': 1.11.1
- '@noble/ciphers': 1.3.0
- '@noble/curves': 1.9.6
- '@noble/hashes': 1.8.0
- '@scure/bip32': 1.7.0
- '@scure/bip39': 1.6.0
- abitype: 1.1.1(typescript@5.8.3)(zod@3.22.4)
- eventemitter3: 5.0.1
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - zod
-
- ox@0.8.6(typescript@5.8.3)(zod@3.25.76):
- dependencies:
- '@adraffy/ens-normalize': 1.11.1
- '@noble/ciphers': 1.3.0
- '@noble/curves': 1.9.6
- '@noble/hashes': 1.8.0
- '@scure/bip32': 1.7.0
- '@scure/bip39': 1.6.0
- abitype: 1.1.1(typescript@5.8.3)(zod@3.25.76)
- eventemitter3: 5.0.1
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - zod
-
- ox@0.8.6(typescript@5.8.3)(zod@4.1.12):
- dependencies:
- '@adraffy/ens-normalize': 1.11.1
- '@noble/ciphers': 1.3.0
- '@noble/curves': 1.9.6
- '@noble/hashes': 1.8.0
- '@scure/bip32': 1.7.0
- '@scure/bip39': 1.6.0
- abitype: 1.1.1(typescript@5.8.3)(zod@4.1.12)
- eventemitter3: 5.0.1
+ mimic-function: 5.0.1
+
+ openai@5.20.2(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@4.1.12):
optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - zod
+ ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
+ zod: 4.1.12
- ox@0.9.8(typescript@5.8.3)(zod@4.1.12):
+ ox@0.11.3(typescript@5.8.3)(zod@3.25.76):
dependencies:
'@adraffy/ens-normalize': 1.11.1
'@noble/ciphers': 1.3.0
@@ -12869,7 +10552,7 @@ snapshots:
'@noble/hashes': 1.8.0
'@scure/bip32': 1.7.0
'@scure/bip39': 1.6.0
- abitype: 1.1.1(typescript@5.8.3)(zod@4.1.12)
+ abitype: 1.2.3(typescript@5.8.3)(zod@3.25.76)
eventemitter3: 5.0.1
optionalDependencies:
typescript: 5.8.3
@@ -12923,8 +10606,6 @@ snapshots:
p-try@2.2.0: {}
- package-json-from-dist@1.0.0: {}
-
parse-diff@0.11.1: {}
parse-json@5.2.0:
@@ -12964,9 +10645,9 @@ snapshots:
path-parse@1.0.7: {}
- path-scurry@1.11.1:
+ path-scurry@2.0.1:
dependencies:
- lru-cache: 10.4.3
+ lru-cache: 11.2.5
minipass: 7.1.2
path-to-regexp@0.1.12: {}
@@ -12977,7 +10658,7 @@ snapshots:
pdf-parse@1.1.1:
dependencies:
- debug: 4.4.3
+ debug: 3.2.7
node-ensure: 0.0.0
transitivePeerDependencies:
- supports-color
@@ -12995,7 +10676,7 @@ snapshots:
pg-native@3.5.2:
dependencies:
- libpq: 1.8.15
+ libpq: 1.9.0
pg-types: 2.2.0
optional: true
@@ -13036,63 +10717,12 @@ snapshots:
pidtree@0.6.0: {}
- pify@3.0.0: {}
-
- pify@5.0.0: {}
-
- pino-abstract-transport@0.5.0:
- dependencies:
- duplexify: 4.1.3
- split2: 4.2.0
-
- pino-std-serializers@4.0.0: {}
-
- pino@7.11.0:
- dependencies:
- atomic-sleep: 1.0.0
- fast-redact: 3.5.0
- on-exit-leak-free: 0.2.0
- pino-abstract-transport: 0.5.0
- pino-std-serializers: 4.0.0
- process-warning: 1.0.0
- quick-format-unescaped: 4.0.4
- real-require: 0.1.0
- safe-stable-stringify: 2.4.3
- sonic-boom: 2.8.0
- thread-stream: 0.15.2
-
pirates@4.0.7: {}
pkg-dir@4.2.0:
dependencies:
find-up: 4.1.0
- pngjs@5.0.0: {}
-
- pony-cause@2.1.11: {}
-
- porto@0.2.19(@tanstack/react-query@5.84.1(react@18.3.1))(@wagmi/core@2.21.2(@tanstack/query-core@5.83.1)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.5(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)):
- dependencies:
- '@wagmi/core': 2.21.2(@tanstack/query-core@5.83.1)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))
- hono: 4.9.10
- idb-keyval: 6.2.2
- mipd: 0.0.7(typescript@5.8.3)
- ox: 0.9.8(typescript@5.8.3)(zod@4.1.12)
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- zod: 4.1.12
- zustand: 5.0.8(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1))
- optionalDependencies:
- '@tanstack/react-query': 5.84.1(react@18.3.1)
- react: 18.3.1
- typescript: 5.8.3
- wagmi: 2.17.5(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@4.1.12)
- transitivePeerDependencies:
- - '@types/react'
- - immer
- - use-sync-external-store
-
- possible-typed-array-names@1.1.0: {}
-
postgres-array@2.0.0: {}
postgres-bytea@1.0.0: {}
@@ -13103,10 +10733,6 @@ snapshots:
dependencies:
xtend: 4.0.2
- preact@10.24.2: {}
-
- preact@10.27.2: {}
-
prettier@3.6.2: {}
pretty-format@30.2.0:
@@ -13115,10 +10741,6 @@ snapshots:
ansi-styles: 5.2.0
react-is: 18.3.1
- process-nextick-args@2.0.1: {}
-
- process-warning@1.0.0: {}
-
process@0.11.10: {}
progress@2.0.3: {}
@@ -13135,8 +10757,6 @@ snapshots:
forwarded: 0.2.0
ipaddr.js: 1.9.1
- proxy-compare@2.6.0: {}
-
proxy-from-env@1.1.0: {}
ps-tree@1.2.0:
@@ -13147,41 +10767,18 @@ snapshots:
dependencies:
punycode: 2.3.1
- pump@3.0.3:
- dependencies:
- end-of-stream: 1.4.4
- once: 1.4.0
-
punycode@2.3.1: {}
pure-rand@7.0.1: {}
- qrcode@1.5.3:
- dependencies:
- dijkstrajs: 1.0.3
- encode-utf8: 1.0.3
- pngjs: 5.0.0
- yargs: 15.4.1
-
- qs@6.14.1:
+ qs@6.15.0:
dependencies:
side-channel: 1.1.0
- query-string@7.1.3:
- dependencies:
- decode-uri-component: 0.2.2
- filter-obj: 1.1.0
- split-on-first: 1.1.0
- strict-uri-encode: 2.0.0
-
querystringify@2.2.0: {}
queue-microtask@1.2.3: {}
- quick-format-unescaped@4.0.4: {}
-
- radix3@1.1.2: {}
-
range-parser@1.2.1: {}
rate-limiter-flexible@2.4.2: {}
@@ -13214,16 +10811,6 @@ snapshots:
json-parse-even-better-errors: 4.0.0
npm-normalize-package-bin: 4.0.0
- readable-stream@2.3.8:
- dependencies:
- core-util-is: 1.0.3
- inherits: 2.0.4
- isarray: 1.0.0
- process-nextick-args: 2.0.1
- safe-buffer: 5.1.2
- string_decoder: 1.1.1
- util-deprecate: 1.0.2
-
readable-stream@3.6.2:
dependencies:
inherits: 2.0.4
@@ -13238,10 +10825,6 @@ snapshots:
process: 0.11.10
string_decoder: 1.3.0
- readdirp@4.1.2: {}
-
- real-require@0.1.0: {}
-
rechoir@0.6.2:
dependencies:
resolve: 1.22.8
@@ -13250,7 +10833,7 @@ snapshots:
redis-info@3.1.0:
dependencies:
- lodash: 4.17.21
+ lodash: 4.17.23
redis-parser@3.0.0:
dependencies:
@@ -13271,8 +10854,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- require-main-filename@2.0.0: {}
-
requires-port@1.0.0: {}
resend@3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
@@ -13323,7 +10904,7 @@ snapshots:
rimraf@5.0.10:
dependencies:
- glob: 10.4.2
+ glob: 13.0.1
robots-parser@3.0.1: {}
@@ -13346,16 +10927,8 @@ snapshots:
dependencies:
queue-microtask: 1.2.3
- safe-buffer@5.1.2: {}
-
safe-buffer@5.2.1: {}
- safe-regex-test@1.1.0:
- dependencies:
- call-bound: 1.0.4
- es-errors: 1.3.0
- is-regex: 1.2.1
-
safe-stable-stringify@2.4.3: {}
safer-buffer@2.1.2: {}
@@ -13384,7 +10957,7 @@ snapshots:
send@0.19.0:
dependencies:
- debug: 4.4.3
+ debug: 2.6.9
depd: 2.0.0
destroy: 1.2.0
encodeurl: 1.0.2
@@ -13409,25 +10982,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
- set-blocking@2.0.0: {}
-
- set-function-length@1.2.2:
- dependencies:
- define-data-property: 1.1.4
- es-errors: 1.3.0
- function-bind: 1.1.2
- get-intrinsic: 1.3.0
- gopd: 1.0.1
- has-property-descriptors: 1.0.2
-
setprototypeof@1.2.0: {}
- sha.js@2.4.12:
- dependencies:
- inherits: 2.0.4
- safe-buffer: 5.2.1
- to-buffer: 1.2.2
-
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
@@ -13480,6 +11036,14 @@ snapshots:
dependencies:
is-arrayish: 0.3.2
+ siwe@2.3.2(ethers@6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)):
+ dependencies:
+ '@spruceid/siwe-parser': 2.1.2
+ '@stablelib/random': 1.0.2
+ ethers: 6.16.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
+ uri-js: 4.4.1
+ valid-url: 1.0.9
+
slash@3.0.0: {}
slice-ansi@5.0.0:
@@ -13494,28 +11058,6 @@ snapshots:
smol-toml@1.5.2: {}
- socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10):
- dependencies:
- '@socket.io/component-emitter': 3.1.2
- debug: 4.4.3
- engine.io-client: 6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- socket.io-parser: 4.2.4
- transitivePeerDependencies:
- - bufferutil
- - supports-color
- - utf-8-validate
-
- socket.io-parser@4.2.4:
- dependencies:
- '@socket.io/component-emitter': 3.1.2
- debug: 4.4.3
- transitivePeerDependencies:
- - supports-color
-
- sonic-boom@2.8.0:
- dependencies:
- atomic-sleep: 1.0.0
-
source-map-support@0.5.13:
dependencies:
buffer-from: 1.1.2
@@ -13523,16 +11065,12 @@ snapshots:
source-map@0.6.1: {}
- split-on-first@1.1.0: {}
-
split2@4.2.0: {}
split@0.3.3:
dependencies:
through: 2.3.8
- sprintf-js@1.0.3: {}
-
sprintf-js@1.1.2: {}
stack-trace@0.0.10: {}
@@ -13561,8 +11099,6 @@ snapshots:
stream-shift@1.0.3: {}
- strict-uri-encode@2.0.0: {}
-
string-argv@0.3.2: {}
string-length@4.0.2:
@@ -13576,22 +11112,12 @@ snapshots:
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
- string-width@5.1.2:
- dependencies:
- eastasianwidth: 0.2.0
- emoji-regex: 9.2.2
- strip-ansi: 7.1.0
-
string-width@7.2.0:
dependencies:
emoji-regex: 10.5.0
get-east-asian-width: 1.3.1
strip-ansi: 7.1.0
- string_decoder@1.1.1:
- dependencies:
- safe-buffer: 5.1.2
-
string_decoder@1.3.0:
dependencies:
safe-buffer: 5.2.1
@@ -13615,9 +11141,9 @@ snapshots:
stripe@16.1.0:
dependencies:
'@types/node': 24.10.1
- qs: 6.14.1
+ qs: 6.15.0
- strnum@1.0.5: {}
+ strnum@2.1.2: {}
stubs@3.0.0: {}
@@ -13631,13 +11157,11 @@ snapshots:
formidable: 2.1.5
methods: 1.1.2
mime: 2.6.0
- qs: 6.14.1
+ qs: 6.15.0
semver: 7.6.2
transitivePeerDependencies:
- supports-color
- superstruct@1.0.4: {}
-
superstruct@2.0.2: {}
supertest@6.3.4:
@@ -13667,7 +11191,7 @@ snapshots:
dependencies:
'@pkgr/core': 0.2.9
- systeminformation@5.27.14: {}
+ systeminformation@5.31.1: {}
tdigest@0.1.2:
dependencies:
@@ -13688,16 +11212,12 @@ snapshots:
dependencies:
'@istanbuljs/schema': 0.1.3
glob: 7.2.3
- minimatch: 3.1.2
+ minimatch: 10.2.4
text-encoding-utf-8@1.0.2: {}
text-hex@1.0.0: {}
- thread-stream@0.15.2:
- dependencies:
- real-require: 0.1.0
-
through@2.3.8: {}
tldts-core@6.1.75: {}
@@ -13708,12 +11228,6 @@ snapshots:
tmpl@1.0.5: {}
- to-buffer@1.2.2:
- dependencies:
- isarray: 2.0.5
- safe-buffer: 5.2.1
- typed-array-buffer: 1.0.3
-
to-regex-range@5.0.1:
dependencies:
is-number: 7.0.0
@@ -13739,7 +11253,7 @@ snapshots:
triple-beam@1.4.1: {}
- ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(jest-util@30.2.0)(jest@30.2.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.8.3)))(typescript@5.8.3):
+ ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.28.5))(esbuild@0.27.2)(jest-util@30.2.0)(jest@30.2.0(@types/node@22.19.1)(ts-node@10.9.2(@types/node@22.19.1)(typescript@5.8.3)))(typescript@5.8.3):
dependencies:
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0
@@ -13757,25 +11271,27 @@ snapshots:
'@jest/transform': 30.2.0
'@jest/types': 30.2.0
babel-jest: 30.2.0(@babel/core@7.28.5)
+ esbuild: 0.27.2
jest-util: 30.2.0
ts-node@10.9.2(@types/node@22.19.1)(typescript@5.8.3):
dependencies:
'@cspotcode/source-map-support': 0.8.1
- '@tsconfig/node10': 1.0.11
+ '@tsconfig/node10': 1.0.12
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
'@types/node': 22.19.1
- acorn: 8.11.3
- acorn-walk: 8.3.2
+ acorn: 8.15.0
+ acorn-walk: 8.3.4
arg: 4.1.3
create-require: 1.1.1
- diff: 4.0.2
+ diff: 8.0.3
make-error: 1.3.6
typescript: 5.8.3
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
+ optional: true
tsc-watch@7.1.1(typescript@5.8.3):
dependencies:
@@ -13785,10 +11301,10 @@ snapshots:
string-argv: 0.3.2
typescript: 5.8.3
- tslib@1.14.1: {}
-
tslib@2.6.3: {}
+ tslib@2.7.0: {}
+
tslib@2.8.1: {}
tsx@4.20.3:
@@ -13802,6 +11318,8 @@ snapshots:
dependencies:
'@mixmark-io/domino': 2.2.0
+ tweetnacl@1.0.3: {}
+
typanion@3.14.0: {}
type-detect@4.0.8: {}
@@ -13815,32 +11333,22 @@ snapshots:
media-typer: 0.3.0
mime-types: 2.1.35
- typed-array-buffer@1.0.3:
- dependencies:
- call-bound: 1.0.4
- es-errors: 1.3.0
- is-typed-array: 1.1.15
-
typescript@5.8.3: {}
typescript@5.9.2: {}
- ufo@1.6.1: {}
-
uglify-js@3.19.3:
optional: true
- uint8arrays@3.1.0:
- dependencies:
- multiformats: 9.9.0
-
uncrypto@0.1.3: {}
+ undici-types@6.19.8: {}
+
undici-types@6.21.0: {}
undici-types@7.16.0: {}
- undici@7.10.0: {}
+ undici@7.18.2: {}
universal-user-agent@7.0.3: {}
@@ -13872,20 +11380,6 @@ snapshots:
'@unrs/resolver-binding-win32-ia32-msvc': 1.11.1
'@unrs/resolver-binding-win32-x64-msvc': 1.11.1
- unstorage@1.16.1(idb-keyval@6.2.2)(ioredis@5.6.1):
- dependencies:
- anymatch: 3.1.3
- chokidar: 4.0.3
- destr: 2.0.5
- h3: 1.15.4
- lru-cache: 10.4.3
- node-fetch-native: 1.6.7
- ofetch: 1.4.1
- ufo: 1.6.1
- optionalDependencies:
- idb-keyval: 6.2.2
- ioredis: 5.6.1
-
update-browserslist-db@1.1.4(browserslist@4.28.0):
dependencies:
browserslist: 4.28.0
@@ -13901,28 +11395,13 @@ snapshots:
querystringify: 2.2.0
requires-port: 1.0.0
- use-sync-external-store@1.2.0(react@18.3.1):
- dependencies:
- react: 18.3.1
-
- use-sync-external-store@1.4.0(react@18.3.1):
- dependencies:
- react: 18.3.1
-
utf-8-validate@5.0.10:
dependencies:
node-gyp-build: 4.8.4
+ optional: true
util-deprecate@1.0.2: {}
- util@0.12.5:
- dependencies:
- inherits: 2.0.4
- is-arguments: 1.2.0
- is-generator-function: 1.1.0
- is-typed-array: 1.1.15
- which-typed-array: 1.1.19
-
utils-merge@1.0.1: {}
uuid@13.0.0: {}
@@ -13931,7 +11410,8 @@ snapshots:
uuid@9.0.1: {}
- v8-compile-cache-lib@3.0.1: {}
+ v8-compile-cache-lib@3.0.1:
+ optional: true
v8-to-istanbul@9.2.0:
dependencies:
@@ -13939,77 +11419,20 @@ snapshots:
'@types/istanbul-lib-coverage': 2.0.6
convert-source-map: 2.0.0
- valtio@1.13.2(react@18.3.1):
- dependencies:
- derive-valtio: 0.1.0(valtio@1.13.2(react@18.3.1))
- proxy-compare: 2.6.0
- use-sync-external-store: 1.2.0(react@18.3.1)
- optionalDependencies:
- react: 18.3.1
+ valid-url@1.0.9: {}
vary@1.1.2: {}
- viem@2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76):
- dependencies:
- '@noble/curves': 1.8.1
- '@noble/hashes': 1.7.1
- '@scure/bip32': 1.6.2
- '@scure/bip39': 1.5.4
- abitype: 1.0.8(typescript@5.8.3)(zod@3.25.76)
- isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
- ox: 0.6.7(typescript@5.8.3)(zod@3.25.76)
- ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - bufferutil
- - utf-8-validate
- - zod
-
- viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4):
- dependencies:
- '@noble/curves': 1.9.2
- '@noble/hashes': 1.8.0
- '@scure/bip32': 1.7.0
- '@scure/bip39': 1.6.0
- abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4)
- isows: 1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))
- ox: 0.8.6(typescript@5.8.3)(zod@3.22.4)
- ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - bufferutil
- - utf-8-validate
- - zod
-
- viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76):
- dependencies:
- '@noble/curves': 1.9.2
- '@noble/hashes': 1.8.0
- '@scure/bip32': 1.7.0
- '@scure/bip39': 1.6.0
- abitype: 1.0.8(typescript@5.8.3)(zod@3.25.76)
- isows: 1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))
- ox: 0.8.6(typescript@5.8.3)(zod@3.25.76)
- ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - bufferutil
- - utf-8-validate
- - zod
-
- viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12):
+ viem@2.45.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76):
dependencies:
- '@noble/curves': 1.9.2
+ '@noble/curves': 1.9.1
'@noble/hashes': 1.8.0
'@scure/bip32': 1.7.0
'@scure/bip39': 1.6.0
- abitype: 1.0.8(typescript@5.8.3)(zod@4.1.12)
- isows: 1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))
- ox: 0.8.6(typescript@5.8.3)(zod@4.1.12)
- ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)
+ abitype: 1.2.3(typescript@5.8.3)(zod@3.25.76)
+ isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))
+ ox: 0.11.3(typescript@5.8.3)(zod@3.25.76)
+ ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)
optionalDependencies:
typescript: 5.8.3
transitivePeerDependencies:
@@ -14021,44 +11444,6 @@ snapshots:
dependencies:
xml-name-validator: 5.0.0
- wagmi@2.17.5(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@4.1.12):
- dependencies:
- '@tanstack/react-query': 5.84.1(react@18.3.1)
- '@wagmi/connectors': 5.11.2(@tanstack/react-query@5.84.1(react@18.3.1))(@wagmi/core@2.21.2(@tanstack/query-core@5.83.1)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(utf-8-validate@5.0.10)(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.17.5(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)
- '@wagmi/core': 2.21.2(@tanstack/query-core@5.83.1)(react@18.3.1)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@18.3.1))(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))
- react: 18.3.1
- use-sync-external-store: 1.4.0(react@18.3.1)
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- optionalDependencies:
- typescript: 5.8.3
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@tanstack/query-core'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - encoding
- - immer
- - ioredis
- - supports-color
- - uploadthing
- - utf-8-validate
- - zod
-
walk-up-path@4.0.0: {}
walker@1.0.8:
@@ -14067,8 +11452,6 @@ snapshots:
web-streams-polyfill@3.3.3: {}
- webextension-polyfill@0.10.0: {}
-
webidl-conversions@3.0.1: {}
webidl-conversions@7.0.0: {}
@@ -14089,18 +11472,6 @@ snapshots:
tr46: 0.0.3
webidl-conversions: 3.0.1
- which-module@2.0.1: {}
-
- which-typed-array@1.1.19:
- dependencies:
- available-typed-arrays: 1.0.7
- call-bind: 1.0.8
- call-bound: 1.0.4
- for-each: 0.3.5
- get-proto: 1.0.1
- gopd: 1.2.0
- has-tostringtag: 1.0.2
-
which@2.0.2:
dependencies:
isexe: 2.0.0
@@ -14143,12 +11514,6 @@ snapshots:
string-width: 4.2.3
strip-ansi: 6.0.1
- wrap-ansi@8.1.0:
- dependencies:
- ansi-styles: 6.2.1
- string-width: 5.1.2
- strip-ansi: 7.1.0
-
wrap-ansi@9.0.0:
dependencies:
ansi-styles: 6.2.1
@@ -14177,102 +11542,11 @@ snapshots:
bufferutil: 4.0.9
utf-8-validate: 5.0.10
- ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10):
- optionalDependencies:
- bufferutil: 4.0.9
- utf-8-validate: 5.0.10
-
ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10):
optionalDependencies:
bufferutil: 4.0.9
utf-8-validate: 5.0.10
- x402-express@0.6.5(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)):
- dependencies:
- '@coinbase/cdp-sdk': 1.33.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(utf-8-validate@5.0.10)
- '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
- express: 4.22.0
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76)
- x402: 0.6.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
- zod: 3.25.76
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@solana/sysvars'
- - '@tanstack/query-core'
- - '@tanstack/react-query'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - debug
- - encoding
- - fastestsmallesttextencoderdecoder
- - immer
- - ioredis
- - react
- - supports-color
- - typescript
- - uploadthing
- - utf-8-validate
- - ws
-
- x402@0.6.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)):
- dependencies:
- '@scure/base': 1.2.6
- '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))
- '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))
- '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3))
- '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
- '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.3)(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
- viem: 2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@4.1.12)
- wagmi: 2.17.5(@tanstack/query-core@5.83.1)(@tanstack/react-query@5.84.1(react@18.3.1))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@4.1.12)
- zod: 3.25.76
- transitivePeerDependencies:
- - '@azure/app-configuration'
- - '@azure/cosmos'
- - '@azure/data-tables'
- - '@azure/identity'
- - '@azure/keyvault-secrets'
- - '@azure/storage-blob'
- - '@capacitor/preferences'
- - '@deno/kv'
- - '@netlify/blobs'
- - '@planetscale/database'
- - '@react-native-async-storage/async-storage'
- - '@solana/sysvars'
- - '@tanstack/query-core'
- - '@tanstack/react-query'
- - '@types/react'
- - '@upstash/redis'
- - '@vercel/blob'
- - '@vercel/kv'
- - aws4fetch
- - bufferutil
- - db0
- - encoding
- - fastestsmallesttextencoderdecoder
- - immer
- - ioredis
- - react
- - supports-color
- - typescript
- - uploadthing
- - utf-8-validate
- - ws
-
xml-name-validator@5.0.0: {}
xml2js@0.6.2:
@@ -14286,39 +11560,16 @@ snapshots:
xmlchars@2.2.0: {}
- xmlhttprequest-ssl@2.1.2: {}
-
xtend@4.0.2: {}
- y18n@4.0.3: {}
-
y18n@5.0.8: {}
yallist@3.1.1: {}
yaml@2.8.1: {}
- yargs-parser@18.1.3:
- dependencies:
- camelcase: 5.3.1
- decamelize: 1.2.0
-
yargs-parser@21.1.1: {}
- yargs@15.4.1:
- dependencies:
- cliui: 6.0.0
- decamelize: 1.2.0
- find-up: 4.1.0
- get-caller-file: 2.0.5
- require-directory: 2.1.1
- require-main-filename: 2.0.0
- set-blocking: 2.0.0
- string-width: 4.2.3
- which-module: 2.0.1
- y18n: 4.0.3
- yargs-parser: 18.1.3
-
yargs@17.7.2:
dependencies:
cliui: 8.0.1
@@ -14334,29 +11585,13 @@ snapshots:
buffer-crc32: 0.2.13
fd-slicer: 1.1.0
- yn@3.1.1: {}
+ yn@3.1.1:
+ optional: true
yocto-queue@0.1.0: {}
yoctocolors-cjs@2.1.3: {}
- zod@3.22.4: {}
-
zod@3.25.76: {}
zod@4.1.12: {}
-
- zustand@5.0.0(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)):
- optionalDependencies:
- react: 18.3.1
- use-sync-external-store: 1.4.0(react@18.3.1)
-
- zustand@5.0.3(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)):
- optionalDependencies:
- react: 18.3.1
- use-sync-external-store: 1.4.0(react@18.3.1)
-
- zustand@5.0.8(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)):
- optionalDependencies:
- react: 18.3.1
- use-sync-external-store: 1.4.0(react@18.3.1)
diff --git a/apps/api/requests/v2/browser.requests.http b/apps/api/requests/v2/browser.requests.http
new file mode 100644
index 0000000000..fbceca1a65
--- /dev/null
+++ b/apps/api/requests/v2/browser.requests.http
@@ -0,0 +1,91 @@
+# Pick your baseUrl here:
+# @baseUrl = http://localhost:3002
+@baseUrl = https://api.firecrawl.dev
+
+### Create Browser Session (defaults)
+POST {{baseUrl}}/v2/browser HTTP/1.1
+Authorization: Bearer {{$dotenv TEST_API_KEY}}
+content-type: application/json
+
+{}
+
+### Create Browser Session (with options)
+POST {{baseUrl}}/v2/browser HTTP/1.1
+Authorization: Bearer {{$dotenv TEST_API_KEY}}
+content-type: application/json
+
+{
+ "ttlTotal": 600,
+ "ttlWithoutActivity": 120,
+ "streamWebView": false
+}
+
+### Create Browser Session (with webview streaming)
+POST {{baseUrl}}/v2/browser HTTP/1.1
+Authorization: Bearer {{$dotenv TEST_API_KEY}}
+content-type: application/json
+
+{
+ "ttlTotal": 300,
+ "streamWebView": true
+}
+
+### List Browser Sessions (all)
+GET {{baseUrl}}/v2/browser HTTP/1.1
+Authorization: Bearer {{$dotenv TEST_API_KEY}}
+
+### List Browser Sessions (active only)
+GET {{baseUrl}}/v2/browser?status=active HTTP/1.1
+Authorization: Bearer {{$dotenv TEST_API_KEY}}
+
+### Execute Code (Python) — replace sessionId with actual id from create response
+@sessionId = {{}}
+
+POST {{baseUrl}}/v2/browser/{{sessionId}}/execute HTTP/1.1
+Authorization: Bearer {{$dotenv TEST_API_KEY}}
+content-type: application/json
+
+{
+ "code": "await page.goto(\"https://example.com\")\nprint(await page.title())",
+ "language": "python"
+}
+
+
+### Execute Code (JS) — replace sessionId with actual id
+POST {{baseUrl}}/v2/browser/{{sessionId}}/execute HTTP/1.1
+Authorization: Bearer {{$dotenv TEST_API_KEY}}
+content-type: application/json
+
+{
+ "code": "await page.goto('https://example.com');\nconst title = await page.title();\nconsole.log(title);",
+ "language": "js"
+}
+
+### Execute Code — screenshot to base64
+POST {{baseUrl}}/v2/browser/{{sessionId}}/execute HTTP/1.1
+Authorization: Bearer {{$dotenv TEST_API_KEY}}
+content-type: application/json
+
+{
+ "code": "await page.goto(\"https://example.com\")\nscreenshot = await page.screenshot()\nimport base64\nprint(base64.b64encode(screenshot).decode()[:100])",
+ "language": "python"
+}
+
+### Execute Code — extract page content
+POST {{baseUrl}}/v2/browser/{{sessionId}}/execute HTTP/1.1
+Authorization: Bearer {{$dotenv TEST_API_KEY}}
+content-type: application/json
+
+{
+ "code": "await page.goto(\"https://news.ycombinator.com\")\ntitles = await page.query_selector_all(\".titleline > a\")\nfor t in titles[:5]:\n print(await t.inner_text())",
+ "language": "python"
+}
+
+### Delete Browser Session — replace sessionId with actual id
+DELETE {{baseUrl}}/v2/browser/{{sessionId}} HTTP/1.1
+Authorization: Bearer {{$dotenv TEST_API_KEY}}
+content-type: application/json
+
+
+### WebSocket — webview stream (use a WS client, e.g. wscat)
+# wscat -c "ws://localhost:3002/v2/browser/{{sessionId}}" -H "Authorization: Bearer YOUR_API_KEY"
diff --git a/apps/api/sharedLibs/go-html-to-md/go.mod b/apps/api/sharedLibs/go-html-to-md/go.mod
index c9bfa629db..24fbe0c656 100644
--- a/apps/api/sharedLibs/go-html-to-md/go.mod
+++ b/apps/api/sharedLibs/go-html-to-md/go.mod
@@ -4,17 +4,15 @@ go 1.23.0
toolchain go1.24.0
-require (
- github.com/PuerkitoBio/goquery v1.10.3
- github.com/firecrawl/html-to-markdown v0.0.0-20251230195842-d4db4da35d6b
- golang.org/x/net v0.41.0
-)
+require github.com/firecrawl/html-to-markdown v0.0.0-20260305014655-0ec744e89d3c
require (
+ github.com/PuerkitoBio/goquery v1.10.3 // indirect
github.com/andybalholm/cascadia v1.3.3 // indirect
github.com/kr/pretty v0.3.0 // indirect
+ golang.org/x/net v0.41.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
-replace github.com/JohannesKaufmann/html-to-markdown => github.com/firecrawl/html-to-markdown v0.0.0-20251230195842-d4db4da35d6b
+replace github.com/JohannesKaufmann/html-to-markdown => github.com/firecrawl/html-to-markdown v0.0.0-20260305014655-0ec744e89d3c
diff --git a/apps/api/sharedLibs/go-html-to-md/go.sum b/apps/api/sharedLibs/go-html-to-md/go.sum
index 56f967a450..79fc69187b 100644
--- a/apps/api/sharedLibs/go-html-to-md/go.sum
+++ b/apps/api/sharedLibs/go-html-to-md/go.sum
@@ -3,8 +3,8 @@ github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/firecrawl/html-to-markdown v0.0.0-20251230195842-d4db4da35d6b h1:SitKYwFT7vUXqzatv258cf02yD5HFlH5P+bjM7ZVkTo=
-github.com/firecrawl/html-to-markdown v0.0.0-20251230195842-d4db4da35d6b/go.mod h1:jngam+MdNp7FZkhSTlFsuA5hXY21X0+vuiGlpgo2n5o=
+github.com/firecrawl/html-to-markdown v0.0.0-20260305014655-0ec744e89d3c h1:EadFGDVcmkhrWfld8MVrnWFIoimCpRd9eUX/AwCiMRs=
+github.com/firecrawl/html-to-markdown v0.0.0-20260305014655-0ec744e89d3c/go.mod h1:jngam+MdNp7FZkhSTlFsuA5hXY21X0+vuiGlpgo2n5o=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
diff --git a/apps/api/sharedLibs/go-html-to-md/html-to-markdown.go b/apps/api/sharedLibs/go-html-to-md/html-to-markdown.go
index 88dccfe394..3b7b2c4960 100644
--- a/apps/api/sharedLibs/go-html-to-md/html-to-markdown.go
+++ b/apps/api/sharedLibs/go-html-to-md/html-to-markdown.go
@@ -5,25 +5,17 @@ package main
*/
import "C"
import (
- "strings"
"unsafe"
- // "log"
-
- "unicode/utf8"
-
- "github.com/PuerkitoBio/goquery"
md "github.com/firecrawl/html-to-markdown"
"github.com/firecrawl/html-to-markdown/plugin"
- "golang.org/x/net/html"
)
//export ConvertHTMLToMarkdown
func ConvertHTMLToMarkdown(html *C.char) *C.char {
converter := md.NewConverter("", true, nil)
converter.Use(plugin.GitHubFlavored())
-
- addGenericPreRule(converter)
+ converter.Use(plugin.RobustCodeBlock())
markdown, err := converter.ConvertString(C.GoString(html))
if err != nil {
@@ -40,115 +32,3 @@ func FreeCString(s *C.char) {
func main() {
// This function is required for the main package
}
-
-// addGenericPreRule adds a robust PRE handler that extracts nested code text
-// (e.g., tables/rows/gutters) and outputs fenced blocks with detected language.
-func addGenericPreRule(conv *md.Converter) {
- isGutter := func(class string) bool {
- c := strings.ToLower(class)
- return strings.Contains(c, "gutter") || strings.Contains(c, "line-numbers")
- }
-
- detectLang := func(sel *goquery.Selection) string {
- classes := sel.AttrOr("class", "")
- lower := strings.ToLower(classes)
- for _, part := range strings.Fields(lower) {
- if strings.HasPrefix(part, "language-") {
- return strings.TrimPrefix(part, "language-")
- }
- if strings.HasPrefix(part, "lang-") {
- return strings.TrimPrefix(part, "lang-")
- }
- }
- return ""
- }
-
- // Collect text recursively; insert newlines after block elements and br
- var collect func(n *html.Node, b *strings.Builder)
- collect = func(n *html.Node, b *strings.Builder) {
- if n == nil {
- return
- }
- switch n.Type {
- case html.TextNode:
- b.WriteString(n.Data)
- case html.ElementNode:
- name := strings.ToLower(n.Data)
- // Skip gutters
- if name != "" {
- // check class attr for gutters
- for _, a := range n.Attr {
- if a.Key == "class" && isGutter(a.Val) {
- return
- }
- }
- }
-
- if name == "br" {
- b.WriteString("\n")
- }
-
- for c := n.FirstChild; c != nil; c = c.NextSibling {
- collect(c, b)
- }
-
- // Newline after block-ish wrappers to preserve lines
- switch name {
- case "p", "div", "li", "tr", "table", "thead", "tbody", "tfoot", "section", "article", "blockquote", "pre", "h1", "h2", "h3", "h4", "h5", "h6":
- b.WriteString("\n")
- }
- }
- }
-
- conv.AddRules(md.Rule{
- Filter: []string{"pre"},
- Replacement: func(_ string, selec *goquery.Selection, opt *md.Options) *string {
- // find inner if present for language
- codeSel := selec.Find("code").First()
- lang := detectLang(codeSel)
- if lang == "" {
- lang = detectLang(selec)
- }
-
- var b strings.Builder
- for _, n := range selec.Nodes {
- collect(n, &b)
- }
- content := strings.TrimRight(b.String(), "\n")
-
- fenceChar, _ := utf8.DecodeRuneInString(opt.Fence)
- fence := md.CalculateCodeFence(fenceChar, content)
- text := "\n\n" + fence + lang + "\n" + content + "\n" + fence + "\n\n"
- return md.String(text)
- },
- })
-
- // Inline code: robustly extract text and fence with backticks
- conv.AddRules(md.Rule{
- Filter: []string{"code"},
- Replacement: func(_ string, selec *goquery.Selection, opt *md.Options) *string {
- // If inside pre, let the PRE rule handle it
- if selec.ParentsFiltered("pre").Length() > 0 {
- return nil
- }
- var b strings.Builder
- for _, n := range selec.Nodes {
- collect(n, &b)
- }
- code := b.String()
- // collapse multiple newlines for inline code
- code = md.TrimTrailingSpaces(strings.ReplaceAll(code, "\r\n", "\n"))
-
- // Choose fence length safely
- fence := "`"
- if strings.Contains(code, "`") {
- fence = "``"
- if strings.Contains(code, "``") {
- fence = "```"
- }
- }
- out := fence + code + fence
- return md.String(out)
- },
- })
-}
diff --git a/apps/api/src/__tests__/e2e_full_withAuth/index.test.ts b/apps/api/src/__tests__/e2e_full_withAuth/index.test.ts
index 3b9bd51511..d33507eeef 100644
--- a/apps/api/src/__tests__/e2e_full_withAuth/index.test.ts
+++ b/apps/api/src/__tests__/e2e_full_withAuth/index.test.ts
@@ -1,7 +1,7 @@
import request from "supertest";
import { config } from "../../config";
import { v7 as uuidv7 } from "uuid";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../lib/strings";
// const TEST_URL = 'http://localhost:3002'
const TEST_URL = "http://127.0.0.1:3002";
@@ -44,15 +44,15 @@ describe("E2E Tests for API Routes", () => {
},
);
- it.concurrent("should return an error for a blocklisted URL", async () => {
- const blocklistedUrl = "https://facebook.com/fake-test";
+ it.concurrent("should return an error for a unsupported URL", async () => {
+ const unsupportedUrl = "https://facebook.com/fake-test";
const response = await request(TEST_URL)
.post("/v0/scrape")
.set("Authorization", `Bearer ${config.TEST_API_KEY}`)
.set("Content-Type", "application/json")
- .send({ url: blocklistedUrl });
+ .send({ url: unsupportedUrl });
expect(response.statusCode).toBe(403);
- expect(response.body.error).toContain(BLOCKLISTED_URL_MESSAGE);
+ expect(response.body.error).toContain(UNSUPPORTED_SITE_MESSAGE);
});
it.concurrent(
@@ -454,15 +454,15 @@ describe("E2E Tests for API Routes", () => {
},
);
- it.concurrent("should return an error for a blocklisted URL", async () => {
- const blocklistedUrl = "https://twitter.com/fake-test";
+ it.concurrent("should return an error for a unsupported URL", async () => {
+ const unsupportedUrl = "https://twitter.com/fake-test";
const response = await request(TEST_URL)
.post("/v0/crawl")
.set("Authorization", `Bearer ${config.TEST_API_KEY}`)
.set("Content-Type", "application/json")
- .send({ url: blocklistedUrl });
+ .send({ url: unsupportedUrl });
expect(response.statusCode).toBe(403);
- expect(response.body.error).toContain(BLOCKLISTED_URL_MESSAGE);
+ expect(response.body.error).toContain(UNSUPPORTED_SITE_MESSAGE);
});
it.concurrent(
@@ -1045,13 +1045,13 @@ describe("E2E Tests for API Routes", () => {
},
);
- // it.concurrent("should return an error for a blocklisted URL", async () => {
- // const blocklistedUrl = "https://instagram.com/fake-test";
+ // it.concurrent("should return an error for a unsupported URL", async () => {
+ // const unsupportedUrl = "https://instagram.com/fake-test";
// const response = await request(TEST_URL)
// .post("/v0/crawlWebsitePreview")
// .set("Authorization", `Bearer ${config.TEST_API_KEY}`)
// .set("Content-Type", "application/json")
- // .send({ url: blocklistedUrl });
+ // .send({ url: unsupportedUrl });
// // is returning 429 instead of 403
// expect(response.statusCode).toBe(403);
// expect(response.body.error).toContain("Firecrawl currently does not support social media scraping due to policy restrictions. We're actively working on building support for it.");
diff --git a/apps/api/src/__tests__/e2e_noAuth/index.test.ts b/apps/api/src/__tests__/e2e_noAuth/index.test.ts
index 428202a855..65bf979f07 100644
--- a/apps/api/src/__tests__/e2e_noAuth/index.test.ts
+++ b/apps/api/src/__tests__/e2e_noAuth/index.test.ts
@@ -1,6 +1,6 @@
import request from "supertest";
import { config } from "../../config";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../lib/strings";
const fs = require("fs");
const path = require("path");
@@ -52,14 +52,14 @@ describe("E2E Tests for API Routes with No Authentication", () => {
expect(response.statusCode).not.toBe(401);
});
- it("should return an error for a blocklisted URL without requiring authorization", async () => {
- const blocklistedUrl = "https://facebook.com/fake-test";
+ it("should return an error for a unsupported URL without requiring authorization", async () => {
+ const unsupportedUrl = "https://facebook.com/fake-test";
const response = await request(TEST_URL)
.post("/v0/scrape")
.set("Content-Type", "application/json")
- .send({ url: blocklistedUrl });
+ .send({ url: unsupportedUrl });
expect(response.statusCode).toBe(403);
- expect(response.body.error).toContain(BLOCKLISTED_URL_MESSAGE);
+ expect(response.body.error).toContain(UNSUPPORTED_SITE_MESSAGE);
});
it("should return a successful response", async () => {
@@ -77,14 +77,14 @@ describe("E2E Tests for API Routes with No Authentication", () => {
expect(response.statusCode).not.toBe(401);
});
- it("should return an error for a blocklisted URL", async () => {
- const blocklistedUrl = "https://twitter.com/fake-test";
+ it("should return an error for a unsupported URL", async () => {
+ const unsupportedUrl = "https://twitter.com/fake-test";
const response = await request(TEST_URL)
.post("/v0/crawl")
.set("Content-Type", "application/json")
- .send({ url: blocklistedUrl });
+ .send({ url: unsupportedUrl });
expect(response.statusCode).toBe(403);
- expect(response.body.error).toContain(BLOCKLISTED_URL_MESSAGE);
+ expect(response.body.error).toContain(UNSUPPORTED_SITE_MESSAGE);
});
it("should return a successful response", async () => {
@@ -106,14 +106,14 @@ describe("E2E Tests for API Routes with No Authentication", () => {
expect(response.statusCode).not.toBe(401);
});
- it("should return an error for a blocklisted URL", async () => {
- const blocklistedUrl = "https://instagram.com/fake-test";
+ it("should return an error for a unsupported URL", async () => {
+ const unsupportedUrl = "https://instagram.com/fake-test";
const response = await request(TEST_URL)
.post("/v0/crawlWebsitePreview")
.set("Content-Type", "application/json")
- .send({ url: blocklistedUrl });
+ .send({ url: unsupportedUrl });
expect(response.statusCode).toBe(403);
- expect(response.body.error).toContain(BLOCKLISTED_URL_MESSAGE);
+ expect(response.body.error).toContain(UNSUPPORTED_SITE_MESSAGE);
});
it("should return a successful response", async () => {
diff --git a/apps/api/src/__tests__/e2e_v1_withAuth/index.test.ts b/apps/api/src/__tests__/e2e_v1_withAuth/index.test.ts
index ffb3eab492..4d1011434e 100644
--- a/apps/api/src/__tests__/e2e_v1_withAuth/index.test.ts
+++ b/apps/api/src/__tests__/e2e_v1_withAuth/index.test.ts
@@ -2,7 +2,7 @@ import request from "supertest";
import { config } from "../../config";
import { configDotenv } from "dotenv";
import { ScrapeRequestInput } from "../../controllers/v1/types";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../lib/strings";
configDotenv();
const TEST_URL = "http://127.0.0.1:3002";
@@ -40,7 +40,7 @@ describe("E2E Tests for v1 API Routes", () => {
expect(response.statusCode).toBe(401);
});
- it.concurrent("should throw error for blocklisted URL", async () => {
+ it.concurrent("should throw error for unsupported URL", async () => {
const scrapeRequest: ScrapeRequestInput = {
url: "https://facebook.com/fake-test",
};
@@ -52,7 +52,7 @@ describe("E2E Tests for v1 API Routes", () => {
.send(scrapeRequest);
expect(response.statusCode).toBe(403);
- expect(response.body.error).toBe(BLOCKLISTED_URL_MESSAGE);
+ expect(response.body.error).toBe(UNSUPPORTED_SITE_MESSAGE);
});
it.concurrent(
@@ -736,7 +736,7 @@ describe("E2E Tests for v1 API Routes", () => {
expect(response.statusCode).toBe(401);
});
- it.concurrent("should throw error for blocklisted URL", async () => {
+ it.concurrent("should throw error for unsupported URL", async () => {
const scrapeRequest: ScrapeRequestInput = {
url: "https://facebook.com/fake-test",
};
@@ -748,7 +748,7 @@ describe("E2E Tests for v1 API Routes", () => {
.send(scrapeRequest);
expect(response.statusCode).toBe(403);
- expect(response.body.error).toBe(BLOCKLISTED_URL_MESSAGE);
+ expect(response.body.error).toBe(UNSUPPORTED_SITE_MESSAGE);
});
it.concurrent(
diff --git a/apps/api/src/__tests__/snips/lib.ts b/apps/api/src/__tests__/snips/lib.ts
index a802fd8f25..4e2306633d 100644
--- a/apps/api/src/__tests__/snips/lib.ts
+++ b/apps/api/src/__tests__/snips/lib.ts
@@ -23,6 +23,7 @@ export const TEST_PRODUCTION = !TEST_SELF_HOST;
// TODO: do we want to run AI tests when users run this command locally? It may lead to increased spending for them, depending on configuration
export const HAS_AI = !!(config.OPENAI_API_KEY || config.OLLAMA_BASE_URL);
+export const HAS_FIRE_ENGINE = !!config.FIRE_ENGINE_BETA_URL;
export const HAS_PLAYWRIGHT = !!config.PLAYWRIGHT_MICROSERVICE_URL;
export const HAS_PROXY = !!config.PROXY_SERVER;
diff --git a/apps/api/src/__tests__/snips/v1/lib.ts b/apps/api/src/__tests__/snips/v1/lib.ts
index 9c905c466b..d531348d55 100644
--- a/apps/api/src/__tests__/snips/v1/lib.ts
+++ b/apps/api/src/__tests__/snips/v1/lib.ts
@@ -63,7 +63,7 @@ export async function scrape(
): Promise {
const raw = await scrapeRaw(body, identity);
expectScrapeToSucceed(raw);
- if (body.proxy === "stealth") {
+ if (body.proxy === "stealth" || body.proxy === "enhanced") {
expect(raw.body.data.metadata.proxyUsed).toBe("stealth");
} else if (!body.proxy || body.proxy === "basic") {
expect(raw.body.data.metadata.proxyUsed).toBe("basic");
@@ -410,7 +410,7 @@ export async function extract(
// Search API
// =========================================
-async function searchRaw(body: SearchRequestInput, identity: Identity) {
+export async function searchRaw(body: SearchRequestInput, identity: Identity) {
return await request(TEST_API_URL)
.post("/v1/search")
.set("Authorization", `Bearer ${identity.apiKey}`)
diff --git a/apps/api/src/__tests__/snips/v1/map.test.ts b/apps/api/src/__tests__/snips/v1/map.test.ts
index 38aa54ae48..33ee0a6f5d 100644
--- a/apps/api/src/__tests__/snips/v1/map.test.ts
+++ b/apps/api/src/__tests__/snips/v1/map.test.ts
@@ -47,7 +47,7 @@ describe("Map tests", () => {
expect(response.statusCode).toBe(408);
expect(response.body.success).toBe(false);
- expect(response.body.error).toBe("Map timed out");
+ expect(response.body.error).toContain("The map operation timed out");
},
10000,
);
diff --git a/apps/api/src/__tests__/snips/v1/scrape.test.ts b/apps/api/src/__tests__/snips/v1/scrape.test.ts
index 31ded4a570..2e851b0d4f 100644
--- a/apps/api/src/__tests__/snips/v1/scrape.test.ts
+++ b/apps/api/src/__tests__/snips/v1/scrape.test.ts
@@ -7,6 +7,7 @@ import {
TEST_PRODUCTION,
TEST_SELF_HOST,
TEST_SUITE_WEBSITE,
+ HAS_FIRE_ENGINE,
HAS_PLAYWRIGHT,
HAS_PROXY,
HAS_AI,
@@ -232,6 +233,31 @@ describe("Scrape tests", () => {
scrapeTimeout,
);
+ itIf(TEST_SELF_HOST && !HAS_FIRE_ENGINE)(
+ "rejects actions when fire-engine is not configured",
+ async () => {
+ const raw = await scrapeRaw(
+ {
+ url: "https://example.com",
+ timeout: scrapeTimeout,
+ actions: [
+ {
+ type: "wait",
+ milliseconds: 1000,
+ },
+ ],
+ },
+ identity,
+ );
+
+ expect(raw.statusCode).toBe(400);
+ expect(raw.body.success).toBe(false);
+ expect(raw.body.code).toBe("SCRAPE_ACTIONS_NOT_SUPPORTED");
+ expect(raw.body.error).toContain("Actions are not supported");
+ },
+ scrapeTimeout,
+ );
+
describe("JSON scrape support", () => {
concurrentIf(ALLOW_TEST_SUITE_WEBSITE)(
"returns parseable JSON",
diff --git a/apps/api/src/__tests__/snips/v1/search.test.ts b/apps/api/src/__tests__/snips/v1/search.test.ts
index ff8e073556..a7956292e2 100644
--- a/apps/api/src/__tests__/snips/v1/search.test.ts
+++ b/apps/api/src/__tests__/snips/v1/search.test.ts
@@ -1,5 +1,5 @@
import { describeIf, HAS_PROXY, HAS_SEARCH, TEST_PRODUCTION } from "../lib";
-import { search, idmux, Identity } from "./lib";
+import { search, searchRaw, idmux, Identity } from "./lib";
let identity: Identity;
@@ -81,6 +81,23 @@ describeIf(TEST_PRODUCTION || HAS_SEARCH || HAS_PROXY)("Search tests", () => {
60000,
);
+ it.concurrent(
+ "returns 400 for limit over 100",
+ async () => {
+ const raw = await searchRaw(
+ {
+ query: "firecrawl",
+ limit: 200,
+ } as any,
+ identity,
+ );
+
+ expect(raw.statusCode).toBe(400);
+ expect(raw.body.success).toBe(false);
+ },
+ 60000,
+ );
+
it.concurrent(
"country defaults to undefined when location is set",
async () => {
diff --git a/apps/api/src/__tests__/snips/v1/types-validation.test.ts b/apps/api/src/__tests__/snips/v1/types-validation.test.ts
index 11c62c39b4..5211361607 100644
--- a/apps/api/src/__tests__/snips/v1/types-validation.test.ts
+++ b/apps/api/src/__tests__/snips/v1/types-validation.test.ts
@@ -267,6 +267,7 @@ describe("V1 Types Validation", () => {
expect(result.timeout).toBe(30000);
expect(result.formats).toEqual(["markdown"]);
expect(result.onlyMainContent).toBe(true);
+ expect(result.onlyCleanContent).toBe(false);
expect(result.waitFor).toBe(0);
expect(result.mobile).toBe(false);
expect(result.parsePDF).toBe(true);
@@ -277,6 +278,16 @@ describe("V1 Types Validation", () => {
expect(result.storeInCache).toBe(true);
});
+ it("should accept scrape request with onlyCleanContent=true", () => {
+ const input: ScrapeRequestInput = {
+ url: "https://example.com",
+ onlyCleanContent: true,
+ };
+
+ const result = scrapeRequestSchema.parse(input);
+ expect(result.onlyCleanContent).toBe(true);
+ });
+
it("should accept valid integration value", () => {
const input: ScrapeRequestInput = {
url: "https://example.com",
diff --git a/apps/api/src/__tests__/snips/v2/crawl.test.ts b/apps/api/src/__tests__/snips/v2/crawl.test.ts
index 82111f9e56..2d4e439dae 100644
--- a/apps/api/src/__tests__/snips/v2/crawl.test.ts
+++ b/apps/api/src/__tests__/snips/v2/crawl.test.ts
@@ -13,6 +13,7 @@ import {
crawl,
crawlOngoing,
crawlStart,
+ map,
Identity,
idmux,
scrapeTimeout,
@@ -23,6 +24,13 @@ import { describe, it, expect } from "@jest/globals";
let identity: Identity;
+const normalizeUrlForCompare = (value: string) => {
+ const url = new URL(value);
+ url.hash = "";
+ const href = url.href;
+ return href.endsWith("/") ? href.slice(0, -1) : href;
+};
+
beforeAll(async () => {
identity = await idmux({
name: "crawl",
@@ -69,6 +77,97 @@ describe("Crawl tests", () => {
10 * scrapeTimeout,
);
+ concurrentIf(ALLOW_TEST_SUITE_WEBSITE)(
+ "works with sitemap: only",
+ async () => {
+ const results = await crawl(
+ {
+ url: base,
+ limit: 10,
+ sitemap: "only",
+ },
+ identity,
+ );
+
+ expect(results.completed).toBeGreaterThan(0);
+ },
+ 10 * scrapeTimeout,
+ );
+
+ concurrentIf(ALLOW_TEST_SUITE_WEBSITE)(
+ "sitemap-only results are subset of map-only + start URL",
+ async () => {
+ const mapResponse = await map(
+ {
+ url: base,
+ sitemap: "only",
+ includeSubdomains: false,
+ ignoreQueryParameters: false,
+ limit: 500,
+ },
+ identity,
+ );
+
+ expect(mapResponse.statusCode).toBe(200);
+ expect(mapResponse.body.success).toBe(true);
+
+ const sitemapUrls = new Set(
+ mapResponse.body.links.map(link => normalizeUrlForCompare(link.url)),
+ );
+ const baseNormalized = normalizeUrlForCompare(base);
+
+ const results = await crawl(
+ {
+ url: base,
+ limit: 50,
+ sitemap: "only",
+ },
+ identity,
+ );
+
+ expect(results.success).toBe(true);
+ if (results.success) {
+ for (const page of results.data) {
+ const pageUrl =
+ page.metadata.url ?? page.metadata.sourceURL ?? base;
+ const normalized = normalizeUrlForCompare(pageUrl);
+ expect(
+ normalized === baseNormalized || sitemapUrls.has(normalized),
+ ).toBe(true);
+ }
+ }
+ },
+ 10 * scrapeTimeout,
+ );
+
+ concurrentIf(TEST_PRODUCTION)(
+ "no sitemap found -> start URL only",
+ async () => {
+ const noSitemapUrl = "https://example.com";
+ const results = await crawl(
+ {
+ url: noSitemapUrl,
+ limit: 10,
+ sitemap: "only",
+ },
+ identity,
+ );
+
+ expect(results.success).toBe(true);
+ if (results.success) {
+ expect(results.data.length).toBe(1);
+ const pageUrl =
+ results.data[0].metadata.url ??
+ results.data[0].metadata.sourceURL ??
+ noSitemapUrl;
+ expect(normalizeUrlForCompare(pageUrl)).toBe(
+ normalizeUrlForCompare(noSitemapUrl),
+ );
+ }
+ },
+ 10 * scrapeTimeout,
+ );
+
concurrentIf(ALLOW_TEST_SUITE_WEBSITE)(
"filters URLs properly",
async () => {
diff --git a/apps/api/src/__tests__/snips/v2/map.test.ts b/apps/api/src/__tests__/snips/v2/map.test.ts
index 475d45c3f1..09df04aad1 100644
--- a/apps/api/src/__tests__/snips/v2/map.test.ts
+++ b/apps/api/src/__tests__/snips/v2/map.test.ts
@@ -47,7 +47,7 @@ describe("Map tests", () => {
expect(response.statusCode).toBe(408);
expect(response.body.success).toBe(false);
- expect(response.body.error).toBe("Map timed out");
+ expect(response.body.error).toContain("The map operation timed out");
},
10000,
);
@@ -139,6 +139,17 @@ describe("Map tests", () => {
expect(response.statusCode).toBe(200);
expect(response.body.success).toBe(true);
expect(response.body.links.length).toBeGreaterThan(0);
+
+ const nonFirecrawlLinks = response.body.links.filter(
+ link => !link.url.includes("firecrawl.dev"),
+ );
+ if (nonFirecrawlLinks.length > 0) {
+ console.log(
+ "Links not containing 'firecrawl.dev':",
+ JSON.stringify(nonFirecrawlLinks, null, 2),
+ );
+ }
+
expect(
response.body.links.every(link => link.url.includes("firecrawl.dev")),
).toBe(true);
diff --git a/apps/api/src/__tests__/snips/v2/parsers.test.ts b/apps/api/src/__tests__/snips/v2/parsers.test.ts
index a9c908f0df..bedc30d95e 100644
--- a/apps/api/src/__tests__/snips/v2/parsers.test.ts
+++ b/apps/api/src/__tests__/snips/v2/parsers.test.ts
@@ -147,6 +147,80 @@ describeIf(ALLOW_TEST_SUITE_WEBSITE)("Parsers parameter tests", () => {
);
});
+ describe("Mode - object format", () => {
+ it.concurrent(
+ "accepts mode: 'fast' and parses PDF with Rust parser",
+ async () => {
+ const response = await scrape(
+ {
+ url: pdfUrl,
+ parsers: [{ type: "pdf", mode: "fast" }],
+ },
+ identity,
+ );
+
+ expect(response.markdown).toBeDefined();
+ expect(response.markdown).toContain("PDF Test File");
+ expect(response.metadata.numPages).toBeGreaterThan(0);
+ },
+ scrapeTimeout * 2,
+ );
+
+ it.concurrent(
+ "accepts mode: 'auto' and parses PDF",
+ async () => {
+ const response = await scrape(
+ {
+ url: pdfUrl,
+ parsers: [{ type: "pdf", mode: "auto" }],
+ },
+ identity,
+ );
+
+ expect(response.markdown).toBeDefined();
+ expect(response.markdown).toContain("PDF Test File");
+ expect(response.metadata.numPages).toBeGreaterThan(0);
+ },
+ scrapeTimeout * 2,
+ );
+
+ it.concurrent(
+ "accepts mode: 'ocr' and parses PDF via OCR",
+ async () => {
+ const response = await scrape(
+ {
+ url: pdfUrl,
+ parsers: [{ type: "pdf", mode: "ocr" }],
+ },
+ identity,
+ );
+
+ expect(response.markdown).toBeDefined();
+ expect(response.markdown).toContain("PDF Test File");
+ expect(response.metadata.numPages).toBeGreaterThan(0);
+ },
+ scrapeTimeout * 2,
+ );
+
+ it.concurrent(
+ "accepts mode with maxPages combined",
+ async () => {
+ const response = await scrape(
+ {
+ url: pdfUrl,
+ parsers: [{ type: "pdf", mode: "fast", maxPages: 1 }],
+ },
+ identity,
+ );
+
+ expect(response.markdown).toBeDefined();
+ expect(response.markdown).toContain("PDF Test File");
+ expect(response.metadata.numPages).toBe(1);
+ },
+ scrapeTimeout * 2,
+ );
+ });
+
describe("Default behavior", () => {
it.concurrent(
"parses PDF by default when parsers not specified",
@@ -256,6 +330,42 @@ describeIf(ALLOW_TEST_SUITE_WEBSITE)("Parsers parameter tests", () => {
},
scrapeTimeout,
);
+
+ it.concurrent(
+ "rejects invalid mode in object format",
+ async () => {
+ const raw = await scrapeRaw(
+ {
+ url: pdfUrl,
+ parsers: [{ type: "pdf", mode: "invalid" } as any],
+ },
+ identity,
+ );
+
+ expect(raw.statusCode).toBe(400);
+ expect(raw.body.success).toBe(false);
+ expect(raw.body.error).toBe("Bad Request");
+ },
+ scrapeTimeout,
+ );
+
+ it.concurrent(
+ "rejects colon-separated shorthand strings",
+ async () => {
+ const raw = await scrapeRaw(
+ {
+ url: pdfUrl,
+ parsers: ["pdf:fast" as any],
+ },
+ identity,
+ );
+
+ expect(raw.statusCode).toBe(400);
+ expect(raw.body.success).toBe(false);
+ expect(raw.body.error).toBe("Bad Request");
+ },
+ scrapeTimeout,
+ );
});
describe("Billing implications", () => {
diff --git a/apps/api/src/__tests__/snips/v2/scrape.test.ts b/apps/api/src/__tests__/snips/v2/scrape.test.ts
index 9719c92bf4..d3c2c96014 100644
--- a/apps/api/src/__tests__/snips/v2/scrape.test.ts
+++ b/apps/api/src/__tests__/snips/v2/scrape.test.ts
@@ -7,6 +7,7 @@ import {
TEST_PRODUCTION,
TEST_SELF_HOST,
TEST_SUITE_WEBSITE,
+ HAS_FIRE_ENGINE,
HAS_PLAYWRIGHT,
HAS_PROXY,
HAS_AI,
@@ -138,6 +139,22 @@ describe("Scrape tests", () => {
);
});
+ it.concurrent(
+ "returns 400 for invalid URL",
+ async () => {
+ const raw = await scrapeRaw(
+ {
+ url: "not-a-valid-url",
+ } as any,
+ identity,
+ );
+
+ expect(raw.statusCode).toBe(400);
+ expect(raw.body.success).toBe(false);
+ },
+ scrapeTimeout,
+ );
+
// TEMP: domain broken
// it.concurrent("works with Punycode domains", async () => {
// await scrape({
@@ -278,6 +295,30 @@ describe("Scrape tests", () => {
scrapeTimeout,
);
+ itIf(TEST_SELF_HOST && !HAS_FIRE_ENGINE)(
+ "rejects actions when fire-engine is not configured",
+ async () => {
+ const raw = await scrapeRaw(
+ {
+ url: "https://example.com",
+ actions: [
+ {
+ type: "wait",
+ milliseconds: 1000,
+ },
+ ],
+ },
+ identity,
+ );
+
+ expect(raw.statusCode).toBe(400);
+ expect(raw.body.success).toBe(false);
+ expect(raw.body.code).toBe("SCRAPE_ACTIONS_NOT_SUPPORTED");
+ expect(raw.body.error).toContain("Actions are not supported");
+ },
+ scrapeTimeout,
+ );
+
describeIf(ALLOW_TEST_SUITE_WEBSITE)("JSON scrape support", () => {
it.concurrent(
"returns parseable JSON",
diff --git a/apps/api/src/__tests__/snips/v2/search.test.ts b/apps/api/src/__tests__/snips/v2/search.test.ts
index e2f089f03e..cbdfa67f44 100644
--- a/apps/api/src/__tests__/snips/v2/search.test.ts
+++ b/apps/api/src/__tests__/snips/v2/search.test.ts
@@ -6,6 +6,7 @@ import {
TEST_PRODUCTION,
} from "../lib";
import { search, idmux, Identity } from "./lib";
+import { config } from "../../../config";
let identity: Identity;
@@ -214,4 +215,39 @@ describeIf(TEST_PRODUCTION || HAS_SEARCH || HAS_PROXY)("Search tests", () => {
},
60000,
);
+
+ // SEARXNG-specific pagination tests
+ concurrentIf(!!config.SEARXNG_ENDPOINT)(
+ "searxng respects limit of 2 results",
+ async () => {
+ const res = await search(
+ {
+ query: "firecrawl",
+ limit: 2,
+ },
+ identity,
+ );
+ expect(res.web).toBeDefined();
+ expect(res.web?.length).toBeGreaterThan(0);
+ expect(res.web?.length).toBeLessThanOrEqual(2);
+ },
+ 60000,
+ );
+
+ concurrentIf(!!config.SEARXNG_ENDPOINT)(
+ "searxng fetches multiple pages for 21 results",
+ async () => {
+ const res = await search(
+ {
+ query: "firecrawl",
+ limit: 21,
+ },
+ identity,
+ );
+ expect(res.web).toBeDefined();
+ expect(res.web?.length).toBeGreaterThan(0);
+ expect(res.web?.length).toBeLessThanOrEqual(21);
+ },
+ 60000,
+ );
});
diff --git a/apps/api/src/__tests__/snips/v2/types-validation.test.ts b/apps/api/src/__tests__/snips/v2/types-validation.test.ts
index cb1e98b8ed..71a192660b 100644
--- a/apps/api/src/__tests__/snips/v2/types-validation.test.ts
+++ b/apps/api/src/__tests__/snips/v2/types-validation.test.ts
@@ -19,6 +19,7 @@ import {
BatchScrapeRequestInput,
SearchRequest,
SearchRequestInput,
+ toV2CrawlerOptions,
} from "../../../controllers/v2/types";
describe("V2 Types Validation", () => {
@@ -224,6 +225,7 @@ describe("V2 Types Validation", () => {
expect(result.origin).toBe("api");
expect(result.formats).toEqual([{ type: "markdown" }]);
expect(result.onlyMainContent).toBe(true);
+ expect(result.onlyCleanContent).toBe(false);
expect(result.waitFor).toBe(0);
expect(result.mobile).toBe(false);
expect(result.removeBase64Images).toBe(true);
@@ -233,6 +235,16 @@ describe("V2 Types Validation", () => {
expect(result.storeInCache).toBe(true);
});
+ it("should accept scrape request with onlyCleanContent=true", () => {
+ const input: ScrapeRequestInput = {
+ url: "https://example.com",
+ onlyCleanContent: true,
+ };
+
+ const result = scrapeRequestSchema.parse(input);
+ expect(result.onlyCleanContent).toBe(true);
+ });
+
it("should accept valid integration value", () => {
const input: ScrapeRequestInput = {
url: "https://example.com",
@@ -606,11 +618,11 @@ describe("V2 Types Validation", () => {
it("should handle sitemap enum values", () => {
const input: CrawlRequestInput = {
url: "https://example.com",
- sitemap: "include",
+ sitemap: "only",
};
const result = crawlRequestSchema.parse(input);
- expect(result.sitemap).toBe("include");
+ expect(result.sitemap).toBe("only");
});
it("should reject invalid sitemap value", () => {
@@ -621,6 +633,15 @@ describe("V2 Types Validation", () => {
expect(() => crawlRequestSchema.parse(input)).toThrow();
});
+
+ it("should map sitemapOnly to sitemap=only", () => {
+ const result = toV2CrawlerOptions({
+ sitemapOnly: true,
+ ignoreSitemap: false,
+ });
+
+ expect(result.sitemap).toBe("only");
+ });
});
describe("mapRequestSchema", () => {
diff --git a/apps/api/src/config.ts b/apps/api/src/config.ts
index 13f084dc0b..e82b167895 100644
--- a/apps/api/src/config.ts
+++ b/apps/api/src/config.ts
@@ -9,6 +9,21 @@ const delimitedList = (separator = ",") => {
});
};
+// Ethereum address schema: validates 0x followed by 40 hex characters
+const ethereumAddress = z
+ .string()
+ .transform(s => s.trim())
+ .pipe(
+ z.union([
+ z.literal(""), // Allow empty string (treated as undefined below)
+ z
+ .string()
+ .regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address format"),
+ ]),
+ )
+ .transform(s => (s === "" ? undefined : (s as `0x${string}`)))
+ .optional();
+
/* Schema */
const configSchema = z.object({
// Application
@@ -55,8 +70,6 @@ const configSchema = z.object({
SUPABASE_ANON_TOKEN: z.string().optional(),
SUPABASE_SERVICE_TOKEN: z.string().optional(),
SUPABASE_REPLICA_URL: z.string().optional(),
- SUPABASE_ACUC_URL: z.string().optional(),
- SUPABASE_ACUC_SERVICE_TOKEN: z.string().optional(),
INDEX_SUPABASE_URL: z.string().optional(),
INDEX_SUPABASE_SERVICE_TOKEN: z.string().optional(),
SEARCH_INDEX_SUPABASE_URL: z.string().optional(),
@@ -71,8 +84,13 @@ const configSchema = z.object({
// Fire Engine
FIRE_ENGINE_BETA_URL: z.string().optional(),
FIRE_ENGINE_STAGING_URL: z.string().optional(),
- FIRE_ENGINE_AB_HOST: z.string().optional(),
+ FIRE_ENGINE_AB_URL: z.string().optional(),
FIRE_ENGINE_AB_RATE: z.coerce.number().optional(),
+ FIRE_ENGINE_AB_MODE: z.enum(["mirror", "split"]).default("mirror"),
+
+ // Indexer
+ INDEXER_RABBITMQ_URL: z.string().optional(),
+ INDEXER_TRAFFIC_SHARE: z.coerce.number().default(0.0),
// ScrapeURL
SCRAPEURL_AB_HOST: z.string().optional(),
@@ -80,6 +98,13 @@ const configSchema = z.object({
SCRAPEURL_AB_EXTEND_MAXAGE: z.stringbool().optional(),
SCRAPEURL_ENGINE_WATERFALL_DELAY_MS: z.coerce.number().default(0),
+ // Scrape Retry Limits
+ SCRAPE_MAX_ATTEMPTS: z.coerce.number().int().positive().default(6),
+ SCRAPE_MAX_FEATURE_TOGGLES: z.coerce.number().int().positive().default(3),
+ SCRAPE_MAX_FEATURE_REMOVALS: z.coerce.number().int().positive().default(3),
+ SCRAPE_MAX_PDF_PREFETCHES: z.coerce.number().int().positive().default(2),
+ SCRAPE_MAX_DOCUMENT_PREFETCHES: z.coerce.number().int().positive().default(2),
+
// Search Services
SEARXNG_ENDPOINT: z.string().optional(),
SEARXNG_ENGINES: z.string().optional(),
@@ -94,6 +119,7 @@ const configSchema = z.object({
NUQ_WORKER_START_PORT: z.coerce.number().default(3006),
NUQ_WORKER_COUNT: z.coerce.number().default(5),
NUQ_PREFETCH_WORKER_PORT: z.coerce.number().default(3011).catch(3011), // todo: investigate why .catch is needed
+ NUQ_RECONCILER_WORKER_PORT: z.coerce.number().default(3012).catch(3012),
EXTRACT_WORKER_PORT: z.coerce.number().default(3004),
NUQ_WAIT_MODE: z.string().optional(),
@@ -128,6 +154,10 @@ const configSchema = z.object({
RUNPOD_MU_API_KEY: z.string().optional(),
RUNPOD_MU_POD_ID: z.string().optional(),
+ // PDF Rust Extraction (pdf-inspector)
+ PDF_RUST_EXTRACT_ENABLE: z.stringbool().optional(),
+ PDF_SHADOW_COMPARISON_ENABLE: z.stringbool().optional(),
+
// Webhooks
SELF_HOSTED_WEBHOOK_URL: z.string().optional(),
SELF_HOSTED_WEBHOOK_HMAC_SECRET: z.string().optional(),
@@ -171,7 +201,8 @@ const configSchema = z.object({
// Payment (x402)
X402_ENDPOINT_PRICE_USD: z.string().optional(),
X402_NETWORK: z.string().optional(),
- X402_PAY_TO_ADDRESS: z.string().optional(),
+ X402_PAY_TO_ADDRESS: ethereumAddress,
+ X402_FACILITATOR_URL: z.string().url().optional(),
// System
MAX_CPU: z.coerce.number().default(0.8),
@@ -195,6 +226,13 @@ const configSchema = z.object({
EXTRACT_V3_BETA_URL: z.string().optional(),
AGENT_INTEROP_SECRET: z.string().optional(),
+
+ // Browser Service
+ BROWSER_SERVICE_URL: z.string().optional(),
+ BROWSER_SERVICE_API_KEY: z.string().optional(),
+ BROWSER_SERVICE_WEBHOOK_SECRET: z.string().optional(),
+
+ NUQ_PREFETCH_WORKER_HEARTBEAT_URL: z.string().optional(),
});
export const config = configSchema.parse(process.env);
diff --git a/apps/api/src/controllers/auth.ts b/apps/api/src/controllers/auth.ts
index 0c30470d72..b212893e80 100644
--- a/apps/api/src/controllers/auth.ts
+++ b/apps/api/src/controllers/auth.ts
@@ -1,22 +1,19 @@
-import { parseApi } from "../lib/parseApi";
+import { RateLimiterRedis } from "rate-limiter-flexible";
+import { validate } from "uuid";
import { config } from "../config";
+import { logger } from "../lib/logger";
+import { parseApi } from "../lib/parseApi";
+import { withAuth } from "../lib/withAuth";
+import { getAgentSponsorStatus } from "../services/agent-sponsor";
+import { getRedisConnection } from "../services/queue-service";
import { getRateLimiter } from "../services/rate-limiter";
-import { AuthResponse, NotificationType, RateLimiterMode } from "../types";
+import { deleteKey, getValue, setValue } from "../services/redis";
+import { redlock } from "../services/redlock";
import {
- supabase_acuc_only_service,
supabase_rr_service,
supabase_service,
} from "../services/supabase";
-import { withAuth } from "../lib/withAuth";
-import { RateLimiterRedis } from "rate-limiter-flexible";
-import { sendNotification } from "../services/notification/email_notification";
-import { logger } from "../lib/logger";
-import { redlock } from "../services/redlock";
-import { deleteKey, getValue } from "../services/redis";
-import { setValue } from "../services/redis";
-import { getRedisConnection } from "../services/queue-service";
-import { validate } from "uuid";
-import * as Sentry from "@sentry/node";
+import { AuthResponse, RateLimiterMode } from "../types";
import { AuthCreditUsageChunk, AuthCreditUsageChunkFromTeam } from "./v1/types";
function normalizedApiIsUuid(potentialUuid: string): boolean {
@@ -159,7 +156,7 @@ export async function getACUC(
return acuc;
}
- if (config.USE_DB_AUTHENTICATION !== true && !config.SUPABASE_ACUC_URL) {
+ if (config.USE_DB_AUTHENTICATION !== true) {
const acuc = mockACUC();
acuc.is_extract = isExtract;
return acuc;
@@ -180,13 +177,11 @@ export async function getACUC(
let retries = 0;
const maxRetries = 5;
while (retries < maxRetries) {
- const client = !!config.SUPABASE_ACUC_URL
- ? supabase_acuc_only_service
- : Math.random() > 2 / 3
- ? supabase_rr_service
- : supabase_service;
+ const client = Math.random() > 2 / 3
+ ? supabase_rr_service
+ : supabase_service;
({ data, error } = await client.rpc(
- "auth_credit_usage_chunk_38",
+ "auth_credit_usage_chunk_45",
{
input_key: api_key,
i_is_extract: isExtract,
@@ -207,7 +202,7 @@ export async function getACUC(
if (retries === maxRetries) {
throw new Error(
"Failed to retrieve authentication and credit usage data after 3 attempts: " +
- JSON.stringify(error),
+ JSON.stringify(error),
);
}
@@ -240,8 +235,8 @@ export async function setCachedACUCTeam(
| AuthCreditUsageChunkFromTeam
| null
| ((
- acuc: AuthCreditUsageChunkFromTeam,
- ) => AuthCreditUsageChunkFromTeam | null),
+ acuc: AuthCreditUsageChunkFromTeam,
+ ) => AuthCreditUsageChunkFromTeam | null),
) {
const cacheKeyACUC = `acuc_team_${team_id}_${is_extract ? "extract" : "scrape"}`;
const redLockKey = `lock_${cacheKeyACUC}`;
@@ -288,7 +283,7 @@ export async function getACUCTeam(
return acuc;
}
- if (config.USE_DB_AUTHENTICATION !== true && !config.SUPABASE_ACUC_URL) {
+ if (config.USE_DB_AUTHENTICATION !== true) {
const acuc = mockACUC();
acuc.is_extract = isExtract;
return acuc;
@@ -310,13 +305,11 @@ export async function getACUCTeam(
const maxRetries = 5;
while (retries < maxRetries) {
- const client = !!config.SUPABASE_ACUC_URL
- ? supabase_acuc_only_service
- : Math.random() > 2 / 3
- ? supabase_rr_service
- : supabase_service;
+ const client = Math.random() > 2 / 3
+ ? supabase_rr_service
+ : supabase_service;
({ data, error } = await client.rpc(
- "auth_credit_usage_chunk_38_from_team",
+ "auth_credit_usage_chunk_45_from_team",
{
input_team: team_id,
i_is_extract: isExtract,
@@ -337,7 +330,7 @@ export async function getACUCTeam(
if (retries === maxRetries) {
throw new Error(
"Failed to retrieve authentication and credit usage data after 3 attempts: " +
- JSON.stringify(error),
+ JSON.stringify(error),
);
}
@@ -395,10 +388,6 @@ export async function authenticateUser(
res,
mode?: RateLimiterMode,
): Promise {
- if (!!config.SUPABASE_ACUC_URL) {
- return supaAuthenticateUser(req, res, mode);
- }
-
return withAuth(supaAuthenticateUser, {
success: true,
chunk: null,
@@ -491,20 +480,21 @@ async function supaAuthenticateUser(
try {
await rateLimiter.consume(team_endpoint_token);
} catch (rateLimiterRes) {
- logger.error(`Rate limit exceeded: ${rateLimiterRes}`, {
- teamId,
- priceId,
- mode,
- rateLimits: chunk?.rate_limits,
- rateLimiterRes,
- });
+ // logger.error(`Rate limit exceeded: ${rateLimiterRes}`, {
+ // teamId,
+ // priceId,
+ // mode,
+ // rateLimits: chunk?.rate_limits,
+ // rateLimiterRes,
+ // });
+
const secs = Math.round(rateLimiterRes.msBeforeNext / 1000) || 1;
const retryDate = new Date(Date.now() + rateLimiterRes.msBeforeNext);
// We can only send a rate limit email every 7 days, send notification already has the date in between checking
- const startDate = new Date();
- const endDate = new Date();
- endDate.setDate(endDate.getDate() + 7);
+ // const startDate = new Date();
+ // const endDate = new Date();
+ // endDate.setDate(endDate.getDate() + 7);
// await sendNotification(team_id, NotificationType.RATE_LIMIT_REACHED, startDate.toISOString(), endDate.toISOString());
@@ -542,6 +532,27 @@ async function supaAuthenticateUser(
// return { success: false, error: "Unauthorized: Invalid token", status: 401 };
}
+ // Check if this is an agent-provisioned key and attach sponsor status
+ if (chunk && chunk.api_key_id) {
+ try {
+ const sponsorStatus = await getAgentSponsorStatus({
+ apiKeyId: chunk.api_key_id,
+ });
+ if (sponsorStatus) {
+ chunk._agentSponsor = {
+ status: sponsorStatus.status,
+ verification_deadline: sponsorStatus.verification_deadline,
+ email: sponsorStatus.email,
+ };
+ }
+ } catch (err) {
+ logger.warn("Failed to check agent sponsor status", {
+ error: err,
+ api_key_id: chunk.api_key_id,
+ });
+ }
+ }
+
return {
success: true,
team_id: teamId ?? undefined,
diff --git a/apps/api/src/controllers/v0/admin/concurrency-queue-backfill.ts b/apps/api/src/controllers/v0/admin/concurrency-queue-backfill.ts
index a508f8d718..ee810a7b0d 100644
--- a/apps/api/src/controllers/v0/admin/concurrency-queue-backfill.ts
+++ b/apps/api/src/controllers/v0/admin/concurrency-queue-backfill.ts
@@ -1,8 +1,6 @@
import { logger as _logger } from "../../../lib/logger";
import { Request, Response } from "express";
-import { getRedisConnection } from "../../../services/queue-service";
-import { scrapeQueue } from "../../../services/worker/nuq";
-import { pushConcurrencyLimitedJob } from "../../../lib/concurrency-limit";
+import { reconcileConcurrencyQueue } from "../../../lib/concurrency-queue-reconciler";
export async function concurrencyQueueBackfillController(
req: Request,
@@ -14,72 +12,16 @@ export async function concurrencyQueueBackfillController(
logger.info("Starting concurrency queue backfill");
- const backloggedOwnerIDs = req.query.teamId
- ? [req.query.teamId as string]
- : await scrapeQueue.getBackloggedOwnerIDs(logger);
-
- for (const ownerId of backloggedOwnerIDs) {
- logger.info("Backfilling concurrency queue for team", { teamId: ownerId });
-
- const backloggedJobIDs = new Set(
- await scrapeQueue.getBackloggedJobIDsOfOnwer(ownerId, logger),
- );
- const queuedJobIDs = new Set();
-
- let cursor = "0";
-
- do {
- const result = await getRedisConnection().zscan(
- `concurrency-limit-queue:${ownerId}`,
- cursor,
- "COUNT",
- 20,
- );
- cursor = result[0];
- const results = result[1];
-
- // zscan returns [member1, score1, member2, score2, ...]
- // Only parse members (even indices), skip scores (odd indices)
- for (let i = 0; i < results.length; i += 2) {
- queuedJobIDs.add(JSON.parse(results[i]).id);
- }
- } while (cursor !== "0");
-
- const jobIDsToAdd = new Set(
- [...backloggedJobIDs].filter(x => !queuedJobIDs.has(x)),
- );
-
- logger.info("Team statistics", {
- teamId: ownerId,
- backloggedJobIDs: backloggedJobIDs.size,
- queuedJobIDs: queuedJobIDs.size,
- jobIDsToAdd: jobIDsToAdd.size,
- });
-
- const jobsToAdd = await scrapeQueue.getJobsFromBacklog(
- Array.from(jobIDsToAdd),
- logger,
- );
-
- for (const job of jobsToAdd) {
- await pushConcurrencyLimitedJob(
- ownerId,
- {
- id: job.id,
- data: job.data,
- priority: job.priority,
- listenable: job.listenChannelId !== undefined,
- },
- Infinity,
- );
- }
-
- logger.info("Finished backfilling concurrency queue for team", {
- teamId: ownerId,
- });
- }
+ const teamId =
+ typeof req.query.teamId === "string"
+ ? (req.query.teamId as string)
+ : undefined;
+ const summary = await reconcileConcurrencyQueue({
+ teamId,
+ logger,
+ });
- logger.info("Finished backfilling all teams");
+ logger.info("Finished backfilling all teams", summary);
- res.json({ ok: true });
+ res.json({ ok: true, ...summary });
}
diff --git a/apps/api/src/controllers/v0/admin/create-user.ts b/apps/api/src/controllers/v0/admin/create-user.ts
index 3fcba7b4c0..07d0b89da1 100644
--- a/apps/api/src/controllers/v0/admin/create-user.ts
+++ b/apps/api/src/controllers/v0/admin/create-user.ts
@@ -10,6 +10,10 @@ async function addCoupon(teamId: string, integration: any) {
return;
}
+ const expiresAt = integration.coupon_expiry_ms
+ ? new Date(Date.now() + integration.coupon_expiry_ms).toISOString()
+ : null;
+
const { error } = await supabase_service.from("coupons").insert({
team_id: teamId,
credits: integration.coupon_credits,
@@ -18,16 +22,51 @@ async function addCoupon(teamId: string, integration: any) {
initial_credits: integration.coupon_credits,
code: integration.coupon_code,
is_extract: false,
- expires_at: integration.coupon_expiry_ms
- ? new Date(Date.now() + integration.coupon_expiry_ms).toISOString()
- : null,
- override_rate_limits: integration.coupon_rate_limits,
- override_concurrency: integration.coupon_concurrency,
+ expires_at: expiresAt,
});
if (error) {
throw error;
}
+
+ if (integration.coupon_rate_limits) {
+ const { error: overrideError } = await (supabase_service as any)
+ .from("team_overrides")
+ .insert({
+ team_id: teamId,
+ rate_limits: integration.coupon_rate_limits,
+ expires_at: expiresAt,
+ internal_comment: `Integration coupon (${integration.display_name || integration.slug || "unknown"})`,
+ });
+
+ if (overrideError) {
+ throw overrideError;
+ }
+ }
+
+ if (integration.coupon_concurrency) {
+ // Look up the org for this team (created by handle_new_user trigger)
+ const { data: teamWithOrg } = await supabase_service
+ .from("teams")
+ .select("org_id")
+ .eq("id", teamId)
+ .single();
+
+ if (teamWithOrg?.org_id) {
+ const { error: orgOverrideError } = await (supabase_service as any)
+ .from("organization_overrides")
+ .insert({
+ org_id: teamWithOrg.org_id,
+ concurrent_browsers: integration.coupon_concurrency,
+ expires_at: expiresAt,
+ internal_comment: `Integration coupon (${integration.display_name || integration.slug || "unknown"})`,
+ });
+
+ if (orgOverrideError) {
+ throw orgOverrideError;
+ }
+ }
+ }
}
/**
@@ -182,13 +221,25 @@ export async function integCreateUserController(req: Request, res: Response) {
teamId,
});
} else {
- // create a new team with this referrer
+ // Create an org first (mirrors handle_new_user trigger)
+ const { data: newOrg, error: newOrgError } = await supabase_service
+ .from("organizations")
+ .insert({ name: "pending" })
+ .select()
+ .single();
+ if (newOrgError) {
+ logger.error("Failed to create organization", { error: newOrgError });
+ return res.status(500).json({ error: "Failed to create organization" });
+ }
+
+ // create a new team with this referrer, linked to the org
const { data: newTeam, error: newTeamError } = await supabase_service
.from("teams")
.insert({
name: "via " + (integration.display_name ?? integration.slug),
referrer_integration: integration.slug,
- })
+ org_id: newOrg.id,
+ } as any)
.select()
.single();
if (newTeamError) {
@@ -197,6 +248,27 @@ export async function integCreateUserController(req: Request, res: Response) {
}
teamId = newTeam.id;
+ // Update org name to match team ID (convention)
+ const { error: orgNameError } = await supabase_service
+ .from("organizations")
+ .update({ name: teamId })
+ .eq("id", newOrg.id);
+ if (orgNameError) {
+ logger.warn("Failed to update org name to team ID", { error: orgNameError, orgId: newOrg.id, teamId });
+ }
+
+ // Link team to org in join table
+ const { error: orgLinkError } = await supabase_service
+ .from("organization_teams")
+ .insert({
+ org_id: newOrg.id,
+ team_id: teamId,
+ });
+ if (orgLinkError) {
+ logger.error("Failed to link team to organization", { error: orgLinkError });
+ return res.status(500).json({ error: "Failed to link team to organization" });
+ }
+
const { error: newUserTeamError } = await supabase_service
.from("user_teams")
.insert({
diff --git a/apps/api/src/controllers/v0/admin/index-queue-prometheus.ts b/apps/api/src/controllers/v0/admin/index-queue-prometheus.ts
index 890d177de3..fccaa12b33 100644
--- a/apps/api/src/controllers/v0/admin/index-queue-prometheus.ts
+++ b/apps/api/src/controllers/v0/admin/index-queue-prometheus.ts
@@ -1,7 +1,6 @@
import type { Request, Response } from "express";
import {
getIndexInsertQueueLength,
- getIndexRFInsertQueueLength,
getOMCEQueueLength,
} from "../../../services";
import { getWebhookInsertQueueLength } from "../../../services/webhook";
@@ -9,7 +8,6 @@ import { getWebhookInsertQueueLength } from "../../../services/webhook";
export async function indexQueuePrometheus(req: Request, res: Response) {
const queueLength = await getIndexInsertQueueLength();
const webhookQueueLength = await getWebhookInsertQueueLength();
- const indexRFQueueLength = await getIndexRFInsertQueueLength();
const omceQueueLength = await getOMCEQueueLength();
res.setHeader("Content-Type", "text/plain");
res.send(`\
@@ -17,7 +15,6 @@ export async function indexQueuePrometheus(req: Request, res: Response) {
# TYPE firecrawl_index_queue_length gauge
firecrawl_index_queue_length ${queueLength}
firecrawl_webhook_queue_length ${webhookQueueLength}
-firecrawl_index_rf_queue_length ${indexRFQueueLength}
firecrawl_omce_queue_length ${omceQueueLength}
`);
}
diff --git a/apps/api/src/controllers/v0/admin/metrics.ts b/apps/api/src/controllers/v0/admin/metrics.ts
index 69d2217f03..b64a839f00 100644
--- a/apps/api/src/controllers/v0/admin/metrics.ts
+++ b/apps/api/src/controllers/v0/admin/metrics.ts
@@ -5,7 +5,8 @@ import { teamConcurrencySemaphore } from "../../../services/worker/team-semaphor
export async function metricsController(_: Request, res: Response) {
let cursor: string = "0";
- const metrics: Record = {};
+ let totalJobCount = 0;
+ let teamCount = 0;
do {
const res = await getRedisConnection().sscan(
"concurrency-limit-queues",
@@ -21,8 +22,8 @@ export async function metricsController(_: Request, res: Response) {
if (jobCount === 0) {
await getRedisConnection().srem("concurrency-limit-queues", key);
} else {
- const teamId = key.split(":")[1];
- metrics[teamId] = jobCount;
+ totalJobCount += jobCount;
+ teamCount++;
}
}
} while (cursor !== "0");
@@ -30,14 +31,13 @@ export async function metricsController(_: Request, res: Response) {
const semaphoreMetrics = await teamConcurrencySemaphore.getMetrics();
res.contentType("text/plain").send(`\
-# HELP concurrency_limit_queue_job_count The number of jobs in the concurrency limit queue per team
-# TYPE concurrency_limit_queue_job_count gauge
-${Object.entries(metrics)
- .map(
- ([key, value]) =>
- `concurrency_limit_queue_job_count{team_id="${key}"} ${value}`,
- )
- .join("\n")}
+# HELP concurrency_limit_queue_job_count_total The total number of jobs across all concurrency limit queues
+# TYPE concurrency_limit_queue_job_count_total gauge
+concurrency_limit_queue_job_count_total ${totalJobCount}
+
+# HELP concurrency_limit_queue_team_count The number of teams with jobs in the concurrency limit queue
+# TYPE concurrency_limit_queue_team_count gauge
+concurrency_limit_queue_team_count ${teamCount}
# HELP billed_teams_count The number of teams that have been billed but not yet tallied
# TYPE billed_teams_count gauge
diff --git a/apps/api/src/controllers/v0/admin/zdrcleaner.ts b/apps/api/src/controllers/v0/admin/zdrcleaner.ts
index 7e1ad206dd..5040945018 100644
--- a/apps/api/src/controllers/v0/admin/zdrcleaner.ts
+++ b/apps/api/src/controllers/v0/admin/zdrcleaner.ts
@@ -9,97 +9,6 @@ async function cleanUpJob(jobId: string) {
await removeJobFromGCS(jobId);
}
-async function cleanUpFirecrawlJobs(
- specificTeamId: string | null,
- _logger: Logger,
-) {
- const logger = _logger.child({
- ...(specificTeamId ? { teamId: specificTeamId } : {}),
- method: "cleanUpFirecrawlJobs",
- });
-
- const cleanedUp: number[] = [];
-
- try {
- for (let i = 0; ; i++) {
- let selector = supabase_service
- .from("firecrawl_jobs")
- .select("id, job_id");
-
- if (specificTeamId) {
- selector = selector
- .eq("team_id", specificTeamId)
- .not("dr_clean_by", "is", null);
- } else {
- selector = selector
- .lte("dr_clean_by", new Date().toISOString())
- .gte(
- "dr_clean_by",
- new Date(Date.now() - 1000 * 60 * 60 * 24 * 7).toISOString(),
- );
- // Explanation for the gte: since the cleaner should run every 5 minutes, it is very unlikely that
- // the cleaner will be down for 7 days without anyone noticing.
- // Since the firecrawl_jobs table is incredibly large, even with the index on dr_clean_by,
- // not giving the select a lower bound guarantees that the select will not run with an empty result
- // in reasonable time.
- // Therefore, we give it a lower bound which should never cause problems.
- }
-
- const { data: jobs } = await selector
- .range(i * 1000, (i + 1) * 1000)
- .throwOnError();
-
- if (jobs?.length === 0) {
- break;
- }
-
- for (let i = 0; i < Math.ceil((jobs?.length ?? 0) / 50); i++) {
- const theseJobs = (jobs ?? []).slice(i * 50, (i + 1) * 50);
- await Promise.allSettled(
- theseJobs.map(async job => {
- try {
- await cleanUpJob(job.job_id);
- cleanedUp.push(job.id);
- } catch (error) {
- logger.error(`Error cleaning up job`, {
- method: "cleanUpJob",
- jobId: job.job_id,
- scrapeId: job.job_id,
- error,
- });
- throw error;
- }
- }) ?? [],
- );
- }
-
- if ((jobs ?? []).length < 1000) {
- break;
- }
- }
- } catch (error) {
- logger.error(`Error looping through jobs`, {
- error,
- });
- }
-
- if (cleanedUp.length > 0) {
- try {
- await supabase_service
- .from("firecrawl_jobs")
- .update({
- dr_clean_by: null,
- })
- .in("id", cleanedUp)
- .throwOnError();
- } catch (error) {
- logger.error(`Error setting cleanup value on team`, {
- error,
- });
- }
- }
-}
-
async function cleanUpRequests(specificTeamId: string | null, _logger: Logger) {
const logger = _logger.child({
...(specificTeamId ? { teamId: specificTeamId } : {}),
@@ -212,10 +121,7 @@ export async function zdrcleanerController(req: Request, res: Response) {
const teamId = (req.query.teamId as string | undefined) ?? null;
- // Clean up old firecrawl_jobs table (legacy)
- await cleanUpFirecrawlJobs(teamId, logger);
-
- // Clean up new requests/scrapes tables
+ // Clean up requests/scrapes tables
await cleanUpRequests(teamId, logger);
logger.info("ZDR Cleaner finished!");
diff --git a/apps/api/src/controllers/v0/crawl.ts b/apps/api/src/controllers/v0/crawl.ts
index 1caa079a0d..865c83cfc1 100644
--- a/apps/api/src/controllers/v0/crawl.ts
+++ b/apps/api/src/controllers/v0/crawl.ts
@@ -30,7 +30,7 @@ import * as Sentry from "@sentry/node";
import { getJobPriority } from "../../lib/job-priority";
import { url as urlSchema } from "../v1/types";
import { ZodError } from "zod";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../lib/strings";
import { fromV0ScrapeOptions } from "../v2/types";
import { isSelfHosted } from "../../lib/deployment";
import { crawlGroup } from "../../services/worker/nuq";
@@ -156,7 +156,7 @@ export async function crawlController(req: Request, res: Response) {
if (isUrlBlocked(url, auth.chunk?.flags ?? null)) {
return res.status(403).json({
- error: BLOCKLISTED_URL_MESSAGE,
+ error: UNSUPPORTED_SITE_MESSAGE,
});
}
diff --git a/apps/api/src/controllers/v0/scrape.ts b/apps/api/src/controllers/v0/scrape.ts
index ca39577201..1e7d420d11 100644
--- a/apps/api/src/controllers/v0/scrape.ts
+++ b/apps/api/src/controllers/v0/scrape.ts
@@ -19,7 +19,7 @@ import * as Sentry from "@sentry/node";
import { getJobPriority } from "../../lib/job-priority";
import { ZodError } from "zod";
import { Document as V0Document } from "./../../lib/entities";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../lib/strings";
import { fromV0Combo } from "../v2/types";
import { ScrapeJobTimeoutError } from "../../lib/error";
import { scrapeQueue } from "../../services/worker/nuq";
@@ -64,7 +64,7 @@ async function scrapeHelper(
if (isUrlBlocked(url, flags)) {
return {
success: false,
- error: BLOCKLISTED_URL_MESSAGE,
+ error: UNSUPPORTED_SITE_MESSAGE,
returnCode: 403,
};
}
diff --git a/apps/api/src/controllers/v1/__tests__/urlValidation.test.ts b/apps/api/src/controllers/v1/__tests__/urlValidation.test.ts
index 6fe982007e..df7ff30803 100644
--- a/apps/api/src/controllers/v1/__tests__/urlValidation.test.ts
+++ b/apps/api/src/controllers/v1/__tests__/urlValidation.test.ts
@@ -1,5 +1,5 @@
import { url } from "../types";
-import { BLOCKLISTED_URL_MESSAGE } from "../../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../../lib/strings";
describe("URL Schema Validation", () => {
beforeEach(() => {
diff --git a/apps/api/src/controllers/v1/batch-scrape.ts b/apps/api/src/controllers/v1/batch-scrape.ts
index 57b36d595d..fbeb0425b8 100644
--- a/apps/api/src/controllers/v1/batch-scrape.ts
+++ b/apps/api/src/controllers/v1/batch-scrape.ts
@@ -22,7 +22,7 @@ import { getJobPriority } from "../../lib/job-priority";
import { addScrapeJobs } from "../../services/queue-jobs";
import { createWebhookSender, WebhookEvent } from "../../services/webhook";
import { logger as _logger } from "../../lib/logger";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../lib/strings";
import { isUrlBlocked } from "../../scraper/WebScraper/utils/blocklist";
import { fromV1ScrapeOptions } from "../v2/types";
import { checkPermissions } from "../../lib/permissions";
@@ -93,7 +93,7 @@ export async function batchScrapeController(
if (!res.headersSent) {
return res.status(403).json({
success: false,
- error: BLOCKLISTED_URL_MESSAGE,
+ error: UNSUPPORTED_SITE_MESSAGE,
});
}
}
diff --git a/apps/api/src/controllers/v1/extract.ts b/apps/api/src/controllers/v1/extract.ts
index 9662c64c09..1d0e947caf 100644
--- a/apps/api/src/controllers/v1/extract.ts
+++ b/apps/api/src/controllers/v1/extract.ts
@@ -11,7 +11,7 @@ import { saveExtract } from "../../lib/extract/extract-redis";
import { getTeamIdSyncB } from "../../lib/extract/team-id-sync";
import { ExtractResult } from "../../lib/extract/extraction-service";
import { performExtraction_F0 } from "../../lib/extract/fire-0/extraction-service-f0";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../lib/strings";
import { isUrlBlocked } from "../../scraper/WebScraper/utils/blocklist";
import { logger as _logger } from "../../lib/logger";
import {
@@ -124,7 +124,7 @@ export async function extractController(
if (!res.headersSent) {
return res.status(403).json({
success: false,
- error: BLOCKLISTED_URL_MESSAGE,
+ error: UNSUPPORTED_SITE_MESSAGE,
});
}
}
diff --git a/apps/api/src/controllers/v1/map.ts b/apps/api/src/controllers/v1/map.ts
index 2d385385db..d24b08ca69 100644
--- a/apps/api/src/controllers/v1/map.ts
+++ b/apps/api/src/controllers/v1/map.ts
@@ -95,6 +95,7 @@ export async function getMapResults({
filterByPath = true,
flags,
useIndex = true,
+ ignoreCache = false,
timeout,
location,
headers,
@@ -115,6 +116,7 @@ export async function getMapResults({
filterByPath?: boolean;
flags: TeamFlags;
useIndex?: boolean;
+ ignoreCache?: boolean;
timeout?: number;
location?: ScrapeOptions["location"];
headers?: Record;
@@ -162,6 +164,7 @@ export async function getMapResults({
timeout ?? 30000,
abort,
mock,
+ ignoreCache ? 0 : undefined,
);
if (sitemap > 0) {
links = links
@@ -192,7 +195,7 @@ export async function getMapResults({
);
const cacheKey = `fireEngineMap:${mapUrl}`;
- const cachedResult = await redis.get(cacheKey);
+ const cachedResult = ignoreCache ? null : await redis.get(cacheKey);
let allResults: any[] = [];
let pagePromises: Promise[] = [];
@@ -248,6 +251,8 @@ export async function getMapResults({
false,
timeout ?? 30000,
abort,
+ undefined,
+ ignoreCache ? 0 : undefined,
);
} catch (e) {
logger.warn("tryGetSitemap threw an error", { error: e });
@@ -423,6 +428,7 @@ export async function mapController(
filterByPath: req.body.filterByPath !== false,
flags: req.acuc?.flags ?? null,
useIndex: req.body.useIndex,
+ ignoreCache: req.body.ignoreCache,
timeout: req.body.timeout,
location: req.body.location,
headers: req.body.headers,
diff --git a/apps/api/src/controllers/v1/scrape.ts b/apps/api/src/controllers/v1/scrape.ts
index 6e9e57c283..b5e81eea19 100644
--- a/apps/api/src/controllers/v1/scrape.ts
+++ b/apps/api/src/controllers/v1/scrape.ts
@@ -20,6 +20,8 @@ import { processJobInternal } from "../../services/worker/scrape-worker";
import { ScrapeJobData } from "../../types";
import { AbortManagerThrownError } from "../../scraper/scrapeURL/lib/abortManager";
import { logRequest } from "../../services/logging/log_job";
+import { getErrorContactMessage } from "../../lib/deployment";
+import { captureExceptionWithZdrCheck } from "../../services/sentry";
export async function scrapeController(
req: RequestWithAuth<{}, ScrapeResponse, ScrapeRequest>,
@@ -65,7 +67,7 @@ export async function scrapeController(
account: req.account,
});
- await logRequest({
+ logRequest({
id: jobId,
kind: "scrape",
api_version: "v1",
@@ -75,7 +77,9 @@ export async function scrapeController(
target_hint: req.body.url,
zeroDataRetention: zeroDataRetention || false,
api_key_id: req.acuc?.api_key_id ?? null,
- });
+ }).catch(err =>
+ logger.warn("Background request log failed", { error: err, jobId }),
+ );
const origin = req.body.origin;
const timeout = req.body.timeout;
@@ -175,14 +179,13 @@ export async function scrapeController(
const timeoutErr =
e instanceof TransportableError && e.code === "SCRAPE_TIMEOUT";
- if (!timeoutErr) {
- logger.error(`Error in scrapeController`, {
- version: "v1",
- error: e,
- });
- }
-
if (e instanceof TransportableError) {
+ if (!timeoutErr) {
+ logger.error(`Error in scrapeController`, {
+ version: "v1",
+ error: e,
+ });
+ }
// DNS resolution errors should return 200 with success: false
if (e.code === "SCRAPE_DNS_RESOLUTION_ERROR") {
return res.status(200).json({
@@ -192,16 +195,44 @@ export async function scrapeController(
});
}
+ if (e.code === "SCRAPE_ACTIONS_NOT_SUPPORTED") {
+ return res.status(400).json({
+ success: false,
+ code: e.code,
+ error: e.message,
+ });
+ }
+
return res.status(e.code === "SCRAPE_TIMEOUT" ? 408 : 500).json({
success: false,
code: e.code,
error: e.message,
});
} else {
+ const id = uuidv7();
+ logger.error(`Error in scrapeController`, {
+ version: "v1",
+ error: e,
+ errorId: id,
+ path: req.path,
+ teamId: req.auth.team_id,
+ });
+ captureExceptionWithZdrCheck(e, {
+ tags: {
+ errorId: id,
+ version: "v1",
+ teamId: req.auth.team_id,
+ },
+ extra: {
+ path: req.path,
+ url: req.body.url,
+ },
+ zeroDataRetention,
+ });
return res.status(500).json({
success: false,
code: "UNKNOWN_ERROR",
- error: `(Internal server error) - ${e && e.message ? e.message : e}`,
+ error: getErrorContactMessage(id),
});
}
} finally {
diff --git a/apps/api/src/controllers/v1/search.ts b/apps/api/src/controllers/v1/search.ts
index 4f684acb3f..f96ffaedd2 100644
--- a/apps/api/src/controllers/v1/search.ts
+++ b/apps/api/src/controllers/v1/search.ts
@@ -6,33 +6,26 @@ import {
SearchRequest,
SearchResponse,
searchRequestSchema,
- ScrapeOptions,
- TeamFlags,
} from "./types";
import { billTeam } from "../../services/billing/credit_billing";
import { v7 as uuidv7 } from "uuid";
-import { addScrapeJob, waitForJob } from "../../services/queue-jobs";
import { logSearch, logRequest } from "../../services/logging/log_job";
import { search } from "../../search";
-import { isUrlBlocked } from "../../scraper/WebScraper/utils/blocklist";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
import { logger as _logger } from "../../lib/logger";
import type { Logger } from "winston";
-import { getJobPriority } from "../../lib/job-priority";
-import { CostTracking } from "../../lib/cost-tracking";
-import { supabase_service } from "../../services/supabase";
-import { fromV1ScrapeOptions } from "../v2/types";
import { ScrapeJobTimeoutError } from "../../lib/error";
-import { scrapeQueue } from "../../services/worker/nuq";
+import { captureExceptionWithZdrCheck } from "../../services/sentry";
+import { z } from "zod";
+import { executeSearch } from "../../search/execute";
import {
- applyZdrScope,
- captureExceptionWithZdrCheck,
-} from "../../services/sentry";
-
-interface DocumentWithCostTracking {
- document: Document;
- costTracking: ReturnType;
-}
+ DocumentWithCostTracking,
+ scrapeSearchResults,
+} from "../../search/scrape";
+import {
+ transformToV1Response,
+ filterDocumentsWithContent,
+} from "../../search/transform";
+import { fromV1ScrapeOptions } from "../v2/types";
// Used for deep research
export async function searchAndScrapeSearchResult(
@@ -41,12 +34,12 @@ export async function searchAndScrapeSearchResult(
teamId: string;
origin: string;
timeout: number;
- scrapeOptions: ScrapeOptions;
+ scrapeOptions: any;
apiKeyId: number | null;
requestId?: string;
},
logger: Logger,
- flags: TeamFlags,
+ flags: any,
): Promise {
try {
const searchResults = await search({
@@ -55,174 +48,31 @@ export async function searchAndScrapeSearchResult(
num_results: 5,
});
- const documentsWithCostTracking = await Promise.all(
- searchResults.map(result =>
- scrapeSearchResult(
- {
- url: result.url,
- title: result.title,
- description: result.description,
- },
- options,
- logger,
- flags,
- ),
- ),
- );
-
- return documentsWithCostTracking;
- } catch (error) {
- return [];
- }
-}
-
-async function scrapeSearchResult(
- searchResult: { url: string; title: string; description: string },
- options: {
- teamId: string;
- origin: string;
- timeout: number;
- scrapeOptions: ScrapeOptions;
- apiKeyId: number | null;
- requestId?: string;
- },
- logger: Logger,
- flags: TeamFlags,
- directToBullMQ: boolean = false,
- isSearchPreview: boolean = false,
-): Promise {
- const jobId = uuidv7();
-
- const costTracking = new CostTracking();
-
- const zeroDataRetention = flags?.forceZDR ?? false;
- applyZdrScope(zeroDataRetention);
-
- try {
- if (isUrlBlocked(searchResult.url, flags)) {
- throw new Error("Could not scrape url: " + BLOCKLISTED_URL_MESSAGE);
- }
- logger.info("Adding scrape job", {
- scrapeId: jobId,
- url: searchResult.url,
- teamId: options.teamId,
- origin: options.origin,
- zeroDataRetention,
- });
-
- const { scrapeOptions, internalOptions } = fromV1ScrapeOptions(
+ const { scrapeOptions } = fromV1ScrapeOptions(
options.scrapeOptions,
options.timeout,
options.teamId,
);
- const jobPriority = await getJobPriority({
- team_id: options.teamId,
- basePriority: 10,
- });
-
- await addScrapeJob(
+ return await scrapeSearchResults(
+ searchResults.map(r => ({
+ url: r.url,
+ title: r.title,
+ description: r.description,
+ })),
{
- url: searchResult.url,
- mode: "single_urls",
- team_id: options.teamId,
- scrapeOptions: {
- ...scrapeOptions,
- maxAge:
- scrapeOptions.maxAge === 0
- ? 3 * 24 * 60 * 60 * 1000
- : scrapeOptions.maxAge,
- },
- internalOptions: {
- ...internalOptions,
- teamId: options.teamId,
- bypassBilling: false, // Scrape jobs always bill themselves
- zeroDataRetention,
- },
+ teamId: options.teamId,
origin: options.origin,
- startTime: Date.now(),
- zeroDataRetention,
+ timeout: options.timeout,
+ scrapeOptions,
apiKeyId: options.apiKeyId,
requestId: options.requestId,
},
- jobId,
- jobPriority,
- directToBullMQ,
- true,
- );
-
- const doc: Document = await waitForJob(
- jobId,
- options.timeout,
- zeroDataRetention,
+ logger,
+ flags,
);
-
- logger.info("Scrape job completed", {
- scrapeId: jobId,
- url: searchResult.url,
- teamId: options.teamId,
- origin: options.origin,
- });
- await scrapeQueue.removeJob(jobId, logger);
-
- const document = {
- title: searchResult.title,
- description: searchResult.description,
- url: searchResult.url,
- ...doc,
- };
-
- let costTracking: ReturnType;
- if (config.USE_DB_AUTHENTICATION) {
- const { data: costTrackingResponse, error: costTrackingError } =
- await supabase_service
- .from("scrapes")
- .select("cost_tracking")
- .eq("id", jobId);
-
- if (costTrackingError) {
- logger.error("Error getting cost tracking", {
- error: costTrackingError,
- });
- throw costTrackingError;
- }
-
- costTracking = costTrackingResponse?.[0]?.cost_tracking;
- } else {
- costTracking = new CostTracking().toJSON();
- }
-
- return {
- document,
- costTracking,
- };
} catch (error) {
- logger.error(`Error in scrapeSearchResult: ${error}`, {
- scrapeId: jobId,
- url: searchResult.url,
- teamId: options.teamId,
- });
-
- let statusCode = 0;
- if (error?.message?.includes("Could not scrape url")) {
- statusCode = 403;
- }
-
- const document: Document = {
- title: searchResult.title,
- description: searchResult.description,
- url: searchResult.url,
- metadata: {
- statusCode,
- error: error.message,
- proxyUsed: "basic",
- },
- };
-
- return {
- document,
- costTracking: new CostTracking().toJSON(),
- };
+ return [];
}
}
@@ -230,7 +80,6 @@ export async function searchController(
req: RequestWithAuth<{}, SearchResponse, SearchRequest>,
res: Response,
) {
- // Get timing data from middleware (includes all middleware processing time)
const middlewareStartTime =
(req as any).requestTiming?.startTime || new Date().getTime();
const controllerStartTime = new Date().getTime();
@@ -263,9 +112,6 @@ export async function searchController(
config.SEARCH_PREVIEW_TOKEN !== undefined &&
config.SEARCH_PREVIEW_TOKEN === req.body.__searchPreviewToken;
- let credits_billed = 0;
- let allDocsWithCostTracking: DocumentWithCostTracking[] = [];
-
try {
req.body = searchRequestSchema.parse(req.body);
@@ -283,91 +129,57 @@ export async function searchController(
origin: req.body.origin ?? "api",
integration: req.body.integration,
target_hint: req.body.query,
- zeroDataRetention: false, // not supported for search
+ zeroDataRetention: false,
api_key_id: req.acuc?.api_key_id ?? null,
});
- let limit = req.body.limit;
-
- // Buffer results by 50% to account for filtered URLs
- const num_results_buffer = Math.floor(limit * 2);
+ // Convert v1 scrape options to v2 format
+ const { scrapeOptions } = fromV1ScrapeOptions(
+ req.body.scrapeOptions,
+ req.body.timeout,
+ req.auth.team_id,
+ );
- logger.info("Searching for results");
+ // Check if scraping is requested
+ const shouldScrape =
+ req.body.scrapeOptions.formats &&
+ req.body.scrapeOptions.formats.length > 0;
- let searchResults = await search({
- query: req.body.query,
+ // Execute search using v2 logic
+ const result = await executeSearch(
+ {
+ query: req.body.query,
+ limit: req.body.limit,
+ tbs: req.body.tbs,
+ filter: req.body.filter,
+ lang: req.body.lang,
+ country: req.body.country,
+ location: req.body.location,
+ sources: [{ type: "web" }], // v1 only supports web
+ scrapeOptions: shouldScrape ? scrapeOptions : undefined,
+ timeout: req.body.timeout,
+ },
+ {
+ teamId: req.auth.team_id,
+ origin: req.body.origin,
+ apiKeyId: req.acuc?.api_key_id ?? null,
+ flags: req.acuc?.flags ?? null,
+ requestId: jobId,
+ bypassBilling: false,
+ zeroDataRetention: false,
+ },
logger,
- advanced: false,
- num_results: num_results_buffer,
- tbs: req.body.tbs,
- filter: req.body.filter,
- lang: req.body.lang,
- country: req.body.country,
- location: req.body.location,
- });
-
- if (req.body.ignoreInvalidURLs) {
- searchResults = searchResults.filter(
- result => !isUrlBlocked(result.url, req.acuc?.flags ?? null),
- );
- }
+ );
- logger.info("Searching completed", {
- num_results: searchResults.length,
- });
+ // Transform v2 response to v1 format (flat array)
+ const docs = transformToV1Response(result.response);
- // Filter blocked URLs early to avoid unnecessary billing
- if (searchResults.length > limit) {
- searchResults = searchResults.slice(0, limit);
- }
-
- if (searchResults.length === 0) {
+ if (docs.length === 0) {
logger.info("No search results found");
responseData.warning = "No search results found";
- } else if (
- !req.body.scrapeOptions.formats ||
- req.body.scrapeOptions.formats.length === 0
- ) {
- responseData.data = searchResults.map(r => ({
- url: r.url,
- title: r.title,
- description: r.description,
- })) as Document[];
- credits_billed = Math.ceil(responseData.data.length / 10) * 2;
- } else {
- logger.info("Scraping search results");
- const scrapePromises = searchResults.map(result =>
- scrapeSearchResult(
- result,
- {
- teamId: req.auth.team_id,
- origin: req.body.origin,
- timeout: req.body.timeout,
- scrapeOptions: req.body.scrapeOptions,
- apiKeyId: req.acuc?.api_key_id ?? null,
- requestId: jobId,
- },
- logger,
- req.acuc?.flags ?? null,
- (req.acuc?.price_credits ?? 0) <= 3000,
- isSearchPreview,
- ),
- );
-
- const docsWithCostTracking = await Promise.all(scrapePromises);
- logger.info("Scraping completed", {
- num_docs: docsWithCostTracking.length,
- });
-
- const docs = docsWithCostTracking.map(item => item.document);
- const filteredDocs = docs.filter(
- doc =>
- doc.serpResults || (doc.markdown && doc.markdown.trim().length > 0),
- );
-
- logger.info("Filtering completed", {
- num_docs: filteredDocs.length,
- });
+ } else if (shouldScrape) {
+ // Filter documents that have content
+ const filteredDocs = filterDocumentsWithContent(docs);
if (filteredDocs.length === 0) {
responseData.data = docs;
@@ -375,23 +187,25 @@ export async function searchController(
} else {
responseData.data = filteredDocs;
}
-
- // Calculate search credits only - scrape jobs bill themselves
- credits_billed = Math.ceil(responseData.data.length / 10) * 2;
-
- allDocsWithCostTracking = docsWithCostTracking;
+ } else {
+ // No scraping - just return basic info
+ responseData.data = docs.map(d => ({
+ url: d.url,
+ title: d.title,
+ description: d.description,
+ })) as Document[];
}
- // Bill team for search credits only - scrape jobs handle their own billing
+ // Bill team for search credits only
if (!isSearchPreview) {
billTeam(
req.auth.team_id,
req.acuc?.sub_id ?? undefined,
- credits_billed,
+ result.searchCredits,
req.acuc?.api_key_id ?? null,
).catch(error => {
logger.error(
- `Failed to bill team ${req.auth.team_id} for ${responseData.data.length} credits: ${error}`,
+ `Failed to bill team ${req.auth.team_id} for ${result.searchCredits} credits: ${error}`,
);
});
}
@@ -399,11 +213,6 @@ export async function searchController(
const endTime = new Date().getTime();
const timeTakenInSeconds = (endTime - middlewareStartTime) / 1000;
- logger.info("Logging job", {
- num_docs: responseData.data.length,
- time_taken: timeTakenInSeconds,
- });
-
logSearch(
{
id: jobId,
@@ -420,19 +229,15 @@ export async function searchController(
query: undefined,
scrapeOptions: undefined,
},
- credits_cost: credits_billed,
- zeroDataRetention: false, // not supported
+ credits_cost: result.searchCredits,
+ zeroDataRetention: false,
},
false,
);
- // Log final timing information
const totalRequestTime = new Date().getTime() - middlewareStartTime;
const controllerTime = new Date().getTime() - controllerStartTime;
- const scrapeful = !!(
- req.body.scrapeOptions.formats &&
- req.body.scrapeOptions.formats.length > 0
- );
+
logger.info("Request metrics", {
version: "v1",
mode: "search",
@@ -442,12 +247,21 @@ export async function searchController(
middlewareTime,
controllerTime,
totalRequestTime,
- creditsUsed: credits_billed,
- scrapeful,
+ creditsUsed: result.searchCredits,
+ scrapeful: shouldScrape,
});
return res.status(200).json(responseData);
} catch (error) {
+ if (error instanceof z.ZodError) {
+ logger.warn("Invalid request body", { error: error.issues });
+ return res.status(400).json({
+ success: false,
+ error: "Invalid request body",
+ details: error.issues,
+ });
+ }
+
if (error instanceof ScrapeJobTimeoutError) {
return res.status(408).json({
success: false,
diff --git a/apps/api/src/controllers/v1/types.ts b/apps/api/src/controllers/v1/types.ts
index 72c9679ad8..9eb9b77a29 100644
--- a/apps/api/src/controllers/v1/types.ts
+++ b/apps/api/src/controllers/v1/types.ts
@@ -74,7 +74,7 @@ export const url = z.preprocess(
return false;
}
}, "Invalid URL"),
- // .refine((x) => !isUrlBlocked(x as string), BLOCKLISTED_URL_MESSAGE),
+ // .refine((x) => !isUrlBlocked(x as string), UNSUPPORTED_SITE_MESSAGE),
);
const agentExtractModelValue = "fire-1";
@@ -368,6 +368,12 @@ const actionSchema = z.union([
export type Action = z.infer;
+export type InternalAction = Action & {
+ metadata?: {
+ [key: string]: unknown;
+ };
+};
+
const actionsSchema = z
.array(actionSchema)
.refine(actions => actions.length <= MAX_ACTIONS, {
@@ -447,7 +453,8 @@ const baseScrapeOptions = z.strictObject({
.transform(tags => tags.map(transformIframeSelector))
.optional(),
onlyMainContent: z.boolean().prefault(true),
- timeout: z.int().positive().finite().optional(),
+ onlyCleanContent: z.boolean().prefault(false),
+ timeout: z.int().positive().min(1000).optional(),
waitFor: z.int().nonnegative().finite().max(60000).prefault(0),
// Deprecate this to jsonOptions
extract: extractOptions.optional(),
@@ -509,7 +516,7 @@ const baseScrapeOptions = z.strictObject({
fastMode: z.boolean().prefault(false),
useMock: z.string().optional(),
blockAds: z.boolean().prefault(true),
- proxy: z.enum(["basic", "stealth", "auto"]).prefault("basic"),
+ proxy: z.enum(["basic", "stealth", "enhanced", "auto"]).prefault("basic"),
maxAge: z
.int()
.gte(0)
@@ -569,7 +576,9 @@ const extractTransform = (obj: ScrapeOptions) => {
}
if (
- (obj.proxy === "stealth" || obj.proxy === "auto") &&
+ (obj.proxy === "stealth" ||
+ obj.proxy === "enhanced" ||
+ obj.proxy === "auto") &&
obj.timeout === 30000
) {
obj = { ...obj, timeout: 120000 };
@@ -713,11 +722,12 @@ const extractV1Options = z
origin: z.string().optional().prefault("api"),
integration: integrationSchema.optional().transform(val => val || null),
urlTrace: z.boolean().prefault(false),
- timeout: z.int().positive().finite().prefault(60000),
+ timeout: z.int().positive().min(1000).prefault(60000),
__experimental_streamSteps: z.boolean().prefault(false),
__experimental_llmUsage: z.boolean().prefault(false),
__experimental_showSources: z.boolean().prefault(false),
showSources: z.boolean().prefault(false),
+ // These two below don't do anything anymore
__experimental_cacheKey: z.string().optional(),
__experimental_cacheMode: z
.enum(["direct", "save", "load"])
@@ -774,7 +784,7 @@ const scrapeRequestSchemaBase = baseScrapeOptions
jsonOptions: extractOptionsWithAgent.optional(),
origin: z.string().optional().prefault("api"),
integration: integrationSchema.optional().transform(val => val || null),
- timeout: z.int().positive().finite().prefault(30000),
+ timeout: z.int().positive().min(1000).prefault(30000),
zeroDataRetention: z.boolean().optional(),
})
.strict();
@@ -945,6 +955,7 @@ const mapRequestSchemaBase = crawlerOptions
useMock: z.string().optional(),
filterByPath: z.boolean().prefault(true),
useIndex: z.boolean().prefault(true),
+ ignoreCache: z.boolean().prefault(false),
location: locationSchema,
headers: z.record(z.string(), z.string()).optional(),
});
@@ -1236,12 +1247,21 @@ export type AuthCreditUsageChunk = {
extractStatus: number;
extractAgentPreview?: number;
scrapeAgentPreview?: number;
+ browser?: number;
+ browserExecute?: number;
};
concurrency: number;
flags: TeamFlags;
// appended on JS-side
is_extract?: boolean;
+
+ // Agent signup: populated when the key is agent-provisioned
+ _agentSponsor?: {
+ status: "pending" | "verified" | "blocked";
+ verification_deadline: string;
+ email: string;
+ } | null;
};
export type TeamFlags = {
@@ -1251,13 +1271,12 @@ export type TeamFlags = {
allowZDR?: boolean;
zdrCost?: number;
checkRobotsOnScrape?: boolean;
- allowTeammateInvites?: boolean;
crawlTtlHours?: number;
ipWhitelist?: boolean;
skipCountryCheck?: boolean;
- extractV3Beta?: boolean;
- agentBeta?: boolean;
+ browserBeta?: boolean;
bypassCreditChecks?: boolean;
+ debugBranding?: boolean;
} | null;
export type AuthCreditUsageChunkFromTeam = Omit<
diff --git a/apps/api/src/controllers/v1/x402-search.ts b/apps/api/src/controllers/v1/x402-search.ts
index d53948fada..805b2519a4 100644
--- a/apps/api/src/controllers/v1/x402-search.ts
+++ b/apps/api/src/controllers/v1/x402-search.ts
@@ -14,7 +14,7 @@ import { addScrapeJob, waitForJob } from "../../services/queue-jobs";
import { logSearch, logRequest } from "../../services/logging/log_job";
import { search } from "../../search";
import { isUrlBlocked } from "../../scraper/WebScraper/utils/blocklist";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../lib/strings";
import { logger as _logger } from "../../lib/logger";
import type { Logger } from "winston";
import { CostTracking } from "../../lib/cost-tracking";
@@ -56,7 +56,7 @@ async function scrapeX402SearchResult(
try {
if (isUrlBlocked(searchResult.url, flags)) {
- throw new Error("Could not scrape url: " + BLOCKLISTED_URL_MESSAGE);
+ throw new Error("Could not scrape url: " + UNSUPPORTED_SITE_MESSAGE);
}
logger.info("Adding scrape job [x402]", {
scrapeId: jobId,
diff --git a/apps/api/src/controllers/v2/__tests__/agent-status.test.ts b/apps/api/src/controllers/v2/__tests__/agent-status.test.ts
new file mode 100644
index 0000000000..d2bfe77adf
--- /dev/null
+++ b/apps/api/src/controllers/v2/__tests__/agent-status.test.ts
@@ -0,0 +1,77 @@
+import type { Response } from "express";
+import { agentStatusController } from "../agent-status";
+import type { RequestWithAuth } from "../types";
+import {
+ supabaseGetAgentByIdDirect,
+ supabaseGetAgentRequestByIdDirect,
+} from "../../../lib/supabase-jobs";
+import { getJobFromGCS } from "../../../lib/gcs-jobs";
+
+jest.mock("../../../lib/supabase-jobs", () => ({
+ supabaseGetAgentByIdDirect: jest.fn(),
+ supabaseGetAgentRequestByIdDirect: jest.fn(),
+}));
+
+jest.mock("../../../lib/gcs-jobs", () => ({
+ getJobFromGCS: jest.fn(),
+}));
+
+describe("agentStatusController", () => {
+ const baseReq = {
+ params: { jobId: "job-123" },
+ auth: { team_id: "team-123" },
+ } as RequestWithAuth<{ jobId: string }, any, any>;
+
+ const buildRes = () =>
+ ({
+ status: jest.fn().mockReturnThis(),
+ json: jest.fn(),
+ }) as unknown as Response;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it("returns model from agent options", async () => {
+ (supabaseGetAgentRequestByIdDirect as jest.Mock).mockResolvedValue({
+ team_id: "team-123",
+ created_at: "2025-01-01T00:00:00Z",
+ });
+ (supabaseGetAgentByIdDirect as jest.Mock).mockResolvedValue({
+ id: "job-123",
+ is_successful: true,
+ options: { model: "spark-1-mini" },
+ created_at: "2025-01-01T00:00:00Z",
+ });
+ (getJobFromGCS as jest.Mock).mockResolvedValue({ result: "ok" });
+
+ const res = buildRes();
+ await agentStatusController(baseReq, res);
+
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ model: "spark-1-mini" }),
+ );
+ });
+
+ it("defaults model to spark-1-pro when missing", async () => {
+ (supabaseGetAgentRequestByIdDirect as jest.Mock).mockResolvedValue({
+ team_id: "team-123",
+ created_at: "2025-01-01T00:00:00Z",
+ });
+ (supabaseGetAgentByIdDirect as jest.Mock).mockResolvedValue({
+ id: "job-123",
+ is_successful: false,
+ options: null,
+ created_at: "2025-01-01T00:00:00Z",
+ });
+
+ const res = buildRes();
+ await agentStatusController(baseReq, res);
+
+ expect(res.status).toHaveBeenCalledWith(200);
+ expect(res.json).toHaveBeenCalledWith(
+ expect.objectContaining({ model: "spark-1-pro" }),
+ );
+ });
+});
diff --git a/apps/api/src/controllers/v2/agent-signup-confirm.ts b/apps/api/src/controllers/v2/agent-signup-confirm.ts
new file mode 100644
index 0000000000..cebe3079e9
--- /dev/null
+++ b/apps/api/src/controllers/v2/agent-signup-confirm.ts
@@ -0,0 +1,287 @@
+import { Request, Response } from "express";
+import { z } from "zod";
+import { logger as _logger } from "../../lib/logger";
+import {
+ clearAgentSponsorCache,
+ getAgentSponsorByToken,
+ markSponsorBlocked,
+ markSponsorVerified,
+} from "../../services/agent-sponsor";
+import { supabase_rr_service, supabase_service } from "../../services/supabase";
+import { clearACUC } from "../auth";
+
+const agentSignupTokenSchema = z.object({
+ agent_signup_token: z.string().min(1),
+});
+
+/**
+ * POST /v2/agent-signup/confirm
+ * Confirms a pending agent sponsor, merging the sandboxed key into the sponsor's real account.
+ */
+export async function agentSignupConfirmController(
+ req: Request,
+ res: Response,
+) {
+ const logger = _logger.child({
+ module: "v2/agent-signup-confirm",
+ method: "agentSignupConfirmController",
+ });
+
+ try {
+ const { agent_signup_token } = agentSignupTokenSchema.parse(req.body);
+
+ const sponsor = await getAgentSponsorByToken({ agent_signup_token });
+ if (!sponsor) {
+ return res.status(404).json({
+ success: false,
+ error: "Invalid or expired verification token.",
+ });
+ }
+
+ if (sponsor.status === "verified") {
+ return res.status(200).json({
+ success: true,
+ message: "This agent key has already been confirmed.",
+ });
+ }
+
+ if (sponsor.status === "blocked") {
+ return res.status(403).json({
+ success: false,
+ error: "This agent signup has been blocked.",
+ });
+ }
+
+ // Check deadline
+ const deadline = new Date(sponsor.verification_deadline);
+ if (deadline < new Date()) {
+ return res.status(403).json({
+ success: false,
+ error:
+ "Verification deadline has passed. Please log in to manage your account.",
+ login_url: "https://firecrawl.dev/signin",
+ });
+ }
+
+ // Look up existing user by sponsor email
+ const { data: existingUser } = await supabase_rr_service
+ .from("users")
+ .select("id, team_id")
+ .eq("email", sponsor.email)
+ .limit(1);
+
+ if (existingUser && existingUser.length > 0) {
+ // Merge: move the agent API key from the sandboxed team to the existing user's team
+ const realTeamId = existingUser[0].team_id;
+ const realUserId = existingUser[0].id;
+
+ // Move the API key to the real team
+ const { error: moveKeyError } = await supabase_service
+ .from("api_keys")
+ .update({ team_id: realTeamId, owner_id: realUserId } as any)
+ .eq("id", sponsor.api_key_id);
+
+ if (moveKeyError) {
+ logger.error("Failed to move API key to real team", {
+ error: moveKeyError,
+ });
+ return res
+ .status(500)
+ .json({ success: false, error: "Failed to confirm agent key." });
+ }
+
+ // Carry over credit_usage from sandboxed team to real team
+ const { error: creditMoveError } = await supabase_service
+ .from("credit_usage")
+ .update({ team_id: realTeamId } as any)
+ .eq("team_id", sponsor.sandboxed_team_id);
+
+ if (creditMoveError) {
+ logger.warn("Failed to carry over credit usage from sandboxed team", {
+ error: creditMoveError,
+ sandboxedTeamId: sponsor.sandboxed_team_id,
+ realTeamId,
+ });
+ // Non-fatal: continue with merge
+ }
+
+ // Ban the sandboxed team to deactivate it
+ const { error: banError } = await supabase_service
+ .from("teams")
+ .update({ banned: true })
+ .eq("id", sponsor.sandboxed_team_id);
+
+ if (banError) {
+ logger.warn("Failed to ban sandboxed team", { error: banError });
+ }
+
+ logger.info("Agent key merged into existing account", {
+ email: sponsor.email,
+ realTeamId,
+ sandboxedTeamId: sponsor.sandboxed_team_id,
+ apiKeyId: sponsor.api_key_id,
+ });
+ } else {
+ // No existing user: the sandboxed account becomes the real account
+ // Update the auth.users email from synthetic to the real sponsor email
+ const { data: sandboxedTeamUsers } = await supabase_service
+ .from("users")
+ .select("id")
+ .eq("team_id", sponsor.sandboxed_team_id)
+ .limit(1);
+
+ if (sandboxedTeamUsers && sandboxedTeamUsers.length > 0) {
+ const userId = sandboxedTeamUsers[0].id;
+
+ // Update auth.users email via admin API
+ const { error: updateAuthError } =
+ await supabase_service.auth.admin.updateUserById(userId, {
+ email: sponsor.email,
+ });
+
+ if (updateAuthError) {
+ logger.error("Failed to update auth user email", {
+ error: updateAuthError,
+ });
+ return res
+ .status(500)
+ .json({ success: false, error: "Failed to confirm agent key." });
+ }
+
+ // Update public.users email
+ const { error: updateUserError } = await supabase_service
+ .from("users")
+ .update({ email: sponsor.email })
+ .eq("id", userId);
+
+ if (updateUserError) {
+ logger.warn("Failed to update public.users email", {
+ error: updateUserError,
+ });
+ }
+ }
+
+ logger.info("Sandboxed account promoted to real account", {
+ email: sponsor.email,
+ sandboxedTeamId: sponsor.sandboxed_team_id,
+ apiKeyId: sponsor.api_key_id,
+ });
+ }
+
+ // Mark sponsor as verified and clear sponsor cache before clearing ACUC,
+ // so that when ACUC is rebuilt it sees verified status (no sandbox cap).
+ await markSponsorVerified({ sponsorId: sponsor.id });
+ await clearAgentSponsorCache({ apiKeyId: sponsor.api_key_id });
+
+ // Clear ACUC so the key picks up the new plan / verified status
+ const { data: apiKeyData } = await supabase_service
+ .from("api_keys")
+ .select("key")
+ .eq("id", sponsor.api_key_id)
+ .single();
+
+ if (apiKeyData) {
+ await clearACUC(apiKeyData.key);
+ }
+
+ return res.status(200).json({
+ success: true,
+ message: "Agent key confirmed and linked to your account.",
+ });
+ } catch (error) {
+ if (error instanceof z.ZodError) {
+ return res.status(400).json({
+ success: false,
+ error: "Invalid request: agent_signup_token is required.",
+ });
+ }
+ logger.error("Unexpected error in agent signup confirm", { error });
+ return res
+ .status(500)
+ .json({ success: false, error: "Internal server error" });
+ }
+}
+
+/**
+ * POST /v2/agent-signup/block
+ * Blocks an agent sponsor, disabling the sandboxed key.
+ */
+export async function agentSignupBlockController(req: Request, res: Response) {
+ const logger = _logger.child({
+ module: "v2/agent-signup-block",
+ method: "agentSignupBlockController",
+ });
+
+ try {
+ const { agent_signup_token } = agentSignupTokenSchema.parse(req.body);
+
+ const sponsor = await getAgentSponsorByToken({ agent_signup_token });
+ if (!sponsor) {
+ return res.status(404).json({
+ success: false,
+ error: "Invalid verification token.",
+ });
+ }
+
+ if (sponsor.status === "blocked") {
+ return res.status(200).json({
+ success: true,
+ message: "This agent signup has already been blocked.",
+ });
+ }
+
+ if (sponsor.status === "verified") {
+ return res.status(409).json({
+ success: false,
+ error:
+ "This agent key has already been confirmed and cannot be blocked.",
+ });
+ }
+
+ // Disable the API key
+ const { error: deleteKeyError } = await supabase_service
+ .from("api_keys")
+ .delete()
+ .eq("id", sponsor.api_key_id);
+
+ if (deleteKeyError) {
+ logger.warn("Failed to delete agent API key", { error: deleteKeyError });
+ }
+
+ // Ban the sandboxed team
+ const { error: banError } = await supabase_service
+ .from("teams")
+ .update({ banned: true })
+ .eq("id", sponsor.sandboxed_team_id);
+
+ if (banError) {
+ logger.warn("Failed to ban sandboxed team", { error: banError });
+ }
+
+ // Mark sponsor as blocked
+ await markSponsorBlocked({ sponsorId: sponsor.id });
+ await clearAgentSponsorCache({ apiKeyId: sponsor.api_key_id });
+
+ logger.info("Agent signup blocked", {
+ email: sponsor.email,
+ sandboxedTeamId: sponsor.sandboxed_team_id,
+ apiKeyId: sponsor.api_key_id,
+ });
+
+ return res.status(200).json({
+ success: true,
+ message: "Agent key has been blocked and disabled.",
+ });
+ } catch (error) {
+ if (error instanceof z.ZodError) {
+ return res.status(400).json({
+ success: false,
+ error: "Invalid request: agent_signup_token is required.",
+ });
+ }
+ logger.error("Unexpected error in agent signup block", { error });
+ return res
+ .status(500)
+ .json({ success: false, error: "Internal server error" });
+ }
+}
diff --git a/apps/api/src/controllers/v2/agent-signup.ts b/apps/api/src/controllers/v2/agent-signup.ts
new file mode 100644
index 0000000000..87049278ae
--- /dev/null
+++ b/apps/api/src/controllers/v2/agent-signup.ts
@@ -0,0 +1,444 @@
+import crypto from "crypto";
+import { Request, Response } from "express";
+import qs from "qs";
+import { RateLimiterRedis } from "rate-limiter-flexible";
+import { Resend } from "resend";
+import { z } from "zod";
+import { config } from "../../config";
+import { logger as _logger } from "../../lib/logger";
+import { apiKeyToFcApiKey } from "../../lib/parseApi";
+import { redisRateLimitClient } from "../../services/rate-limiter";
+import { supabase_rr_service, supabase_service } from "../../services/supabase";
+
+const PUBLIC_EMAIL_DOMAINS = new Set([
+ "gmail.com",
+ "googlemail.com",
+ "outlook.com",
+ "hotmail.com",
+ "live.com",
+ "yahoo.com",
+ "yahoo.co.uk",
+ "icloud.com",
+ "me.com",
+ "mac.com",
+ "aol.com",
+ "protonmail.com",
+ "proton.me",
+ "mail.com",
+ "zoho.com",
+ "yandex.com",
+ "gmx.com",
+ "gmx.net",
+ "tutanota.com",
+ "fastmail.com",
+]);
+
+// Rate limit values — used by limiters and error copy so they stay in sync
+const AGENT_SIGNUP_IP_LIMIT = 5;
+const AGENT_SIGNUP_DOMAIN_LIMIT = 20;
+const AGENT_SIGNUP_IP_LIMIT_SIDEGUIDE = 15; // 3x default
+const AGENT_SIGNUP_DOMAIN_LIMIT_SIDEGUIDE = 60; // 3x default
+
+// Rate limiters
+const ipRateLimiter = new RateLimiterRedis({
+ storeClient: redisRateLimitClient,
+ keyPrefix: "agent_signup_ip",
+ points: AGENT_SIGNUP_IP_LIMIT,
+ duration: 3600, // 1 hour
+});
+
+// Per-domain (or per-email for public providers) limit to curb abuse while allowing
+// legitimate multi-agent signups. Tune points if product requirements change.
+const domainRateLimiter = new RateLimiterRedis({
+ storeClient: redisRateLimitClient,
+ keyPrefix: "agent_signup_domain",
+ points: AGENT_SIGNUP_DOMAIN_LIMIT,
+ duration: 86400, // 24 hours
+});
+
+// Higher limits for *+test*@sideguide.dev only. sideguide.dev is internal-only; external users
+// cannot receive mail or hold accounts there, so this path is not abusable.
+const ipRateLimiterSideguide = new RateLimiterRedis({
+ storeClient: redisRateLimitClient,
+ keyPrefix: "agent_signup_ip_sideguide",
+ points: AGENT_SIGNUP_IP_LIMIT_SIDEGUIDE,
+ duration: 3600, // 1 hour
+});
+
+const domainRateLimiterSideguide = new RateLimiterRedis({
+ storeClient: redisRateLimitClient,
+ keyPrefix: "agent_signup_domain_sideguide",
+ points: AGENT_SIGNUP_DOMAIN_LIMIT_SIDEGUIDE,
+ duration: 86400, // 24 hours
+});
+
+const agentSignupSchema = z.object({
+ email: z.string().email(),
+ agent_name: z.string().min(1).max(100),
+ accept_terms: z.literal(true),
+});
+
+/** Insert payload for agent_sponsors (nullable cols in DB are optional here). */
+type AgentSponsorInsert = {
+ email: string;
+ status: "pending" | "blocked" | "verified";
+ verification_deadline: string;
+ agent_name: string;
+ sandboxed_team_id: string;
+ api_key_id: number;
+ verification_token: string;
+
+ requesting_ip?: string;
+ tos_version?: string;
+ tos_hash?: string;
+};
+
+export async function agentSignupController(req: Request, res: Response) {
+ const logger = _logger.child({
+ module: "v2/agent-signup",
+ method: "agentSignupController",
+ });
+
+ try {
+ // Parse and validate input
+ const body = agentSignupSchema.parse(req.body);
+ const email = body.email.toLowerCase();
+ const { agent_name } = body;
+
+ const incomingIP = req.ip || req.socket.remoteAddress || "unknown";
+ const [emailPrefix, emailDomain] = email.split("@");
+ // sideguide.dev is an internal domain: only Sideguide team have mailboxes there. Even if
+ // someone used this pattern to get the higher limits, each signup still gets only 50 credits
+ // and keys stay sandboxed (no confirm/merge); limits are 3x default, not unbounded.
+ const isSideguideEmail =
+ emailDomain === "sideguide.dev" && emailPrefix.includes("+test");
+
+ // Always rate limit; use higher limits only for internal sideguide.dev +test addresses
+ const ipLimiter = isSideguideEmail ? ipRateLimiterSideguide : ipRateLimiter;
+ const domainLimiter = isSideguideEmail
+ ? domainRateLimiterSideguide
+ : domainRateLimiter;
+ const ipLimitMsg = isSideguideEmail
+ ? `Rate limit exceeded. Maximum ${AGENT_SIGNUP_IP_LIMIT_SIDEGUIDE} agent signup requests per hour per IP for sideguide test emails.`
+ : `Rate limit exceeded. Maximum ${AGENT_SIGNUP_IP_LIMIT} agent signup requests per hour per IP.`;
+ const domainLimitMsg = isSideguideEmail
+ ? "Too many agent signups for this email. Please try again later."
+ : "Too many agent signups for this email domain. Please try again later.";
+
+ try {
+ await ipLimiter.consume(incomingIP);
+ } catch {
+ return res.status(429).json({
+ success: false,
+ error: ipLimitMsg,
+ });
+ }
+
+ const domainKey = PUBLIC_EMAIL_DOMAINS.has(emailDomain)
+ ? email
+ : emailDomain;
+ try {
+ await domainLimiter.consume(domainKey);
+ } catch {
+ return res.status(429).json({
+ success: false,
+ error: domainLimitMsg,
+ });
+ }
+
+ // Check for existing blocked sponsor record (use primary for strong consistency)
+ const { data: blockedSponsor } = await supabase_service
+ .from("agent_sponsors")
+ .select("id")
+ .eq("email", email)
+ .eq("status", "blocked")
+ .limit(1);
+
+ if (blockedSponsor && blockedSponsor.length > 0) {
+ return res.status(403).json({
+ success: false,
+ error: "This email has blocked agent signups.",
+ });
+ }
+
+ // Check for existing pending sponsor record (use primary for strong consistency)
+ const { data: pendingSponsor } = await supabase_service
+ .from("agent_sponsors")
+ .select("id, verification_deadline")
+ .eq("email", email)
+ .eq("status", "pending")
+ .limit(1);
+
+ if (pendingSponsor && pendingSponsor.length > 0) {
+ const deadline = new Date(pendingSponsor[0].verification_deadline);
+ if (deadline > new Date()) {
+ return res.status(409).json({
+ success: false,
+ error:
+ "A pending agent signup confirmation has already been sent to this email.",
+ login_url: "https://firecrawl.dev/signin",
+ });
+ } else {
+ return res.status(403).json({
+ success: false,
+ error:
+ "Previous agent signup verification has expired. Please log in to manage your account.",
+ login_url: "https://firecrawl.dev/signin",
+ });
+ }
+ }
+
+ // Create sandboxed account via Supabase auth
+ const sandboxId = crypto.randomUUID();
+ const syntheticEmail = `agent-${sandboxId}@agent.sandbox.firecrawl.dev`;
+
+ const { data: newUser, error: newUserError } =
+ await supabase_service.auth.admin.createUser({
+ email: syntheticEmail,
+ email_confirm: true,
+ user_metadata: {
+ referrer_integration: "agent_signup",
+ agent_name: agent_name,
+ },
+ });
+
+ if (newUserError) {
+ logger.error("Failed to create sandboxed user", { error: newUserError });
+ return res
+ .status(500)
+ .json({ success: false, error: "Failed to create agent account." });
+ }
+
+ // Wait briefly for the trigger to complete, then fetch the created records
+ // The handle_new_user_6 trigger creates user, team, org, api_key
+ let teamId: string | null = null;
+ let apiKeyRecord: { id: number; key: string } | null = null;
+
+ // Poll for trigger completion (the trigger runs synchronously in the same transaction)
+ const { data: fcUser, error: fcUserError } = await supabase_service
+ .from("users")
+ .select("team_id")
+ .eq("id", newUser.user.id)
+ .single();
+
+ if (fcUserError || !fcUser) {
+ logger.error("Failed to look up sandboxed user after creation", {
+ error: fcUserError,
+ });
+ return res
+ .status(500)
+ .json({ success: false, error: "Failed to create agent account." });
+ }
+
+ teamId = fcUser.team_id;
+
+ const { data: apiKeyData, error: apiKeyError } = await supabase_service
+ .from("api_keys")
+ .select("id, key")
+ .eq("team_id", teamId)
+ .limit(1)
+ .single();
+
+ if (apiKeyError || !apiKeyData) {
+ logger.error("Failed to look up API key for sandboxed team", {
+ error: apiKeyError,
+ });
+ return res
+ .status(500)
+ .json({ success: false, error: "Failed to create agent account." });
+ }
+
+ apiKeyRecord = apiKeyData;
+
+ if (!teamId) {
+ return res
+ .status(500)
+ .json({ success: false, error: "Failed to create agent account." });
+ }
+
+ // Mark the API key as agent_provisioned
+ const { error: updateKeyError } = await supabase_service
+ .from("api_keys")
+ .update({ agent_provisioned: true } as any)
+ .eq("id", apiKeyRecord.id);
+
+ if (updateKeyError) {
+ logger.error("Failed to mark API key as agent_provisioned", {
+ error: updateKeyError,
+ });
+ return res
+ .status(500)
+ .json({ success: false, error: "Failed to create agent account." });
+ }
+
+ // Generate verification token
+ const verificationToken = crypto.randomBytes(32).toString("hex");
+
+ // Compute deadline (5 days from now)
+ const deadline = new Date();
+ deadline.setDate(deadline.getDate() + 5);
+
+ // Create sponsor record
+ const sponsorRow: AgentSponsorInsert = {
+ email,
+ status: "pending",
+ verification_deadline: deadline.toISOString(),
+ agent_name,
+ sandboxed_team_id: teamId,
+ api_key_id: apiKeyRecord.id,
+ requesting_ip: incomingIP,
+ tos_version: "2024-11-05", // Date of last revision in ToS at https://firecrawl.dev/terms-of-service
+ tos_hash: crypto
+ .createHash("sha256")
+ .update("accept_terms:true")
+ .digest("hex"),
+ verification_token: verificationToken,
+ };
+ const { error: sponsorError } = await supabase_service
+ .from("agent_sponsors")
+ .insert(sponsorRow);
+
+ if (sponsorError) {
+ logger.error("Failed to create sponsor record", { error: sponsorError });
+ return res
+ .status(500)
+ .json({ success: false, error: "Failed to create agent signup." });
+ }
+
+ // Send confirmation email
+ const confirmUrl = `https://firecrawl.dev/agent-confirm?${qs.stringify({
+ agent_signup_token: verificationToken,
+ agent_signup_action: "confirm",
+ })}`;
+ const blockUrl = `https://firecrawl.dev/agent-confirm?${qs.stringify({
+ agent_signup_token: verificationToken,
+ agent_signup_action: "block",
+ })}`;
+
+ if (config.RESEND_API_KEY) {
+ logger.info("Sending agent sponsor confirmation email", {
+ to: email,
+ agent_name,
+ });
+ try {
+ const resend = new Resend(config.RESEND_API_KEY);
+ const sendResult = await resend.emails.send({
+ from: "Firecrawl ",
+ to: [email],
+ reply_to: "help@firecrawl.com",
+ subject: `An AI agent "${agent_name}" created an API key under your email — Firecrawl`,
+ html: `
+ Hey there,
+ An AI agent called ${escapeHtml(agent_name)} just created a Firecrawl API key and listed your email as the account holder.
+ The key is currently sandboxed with a 50-credit limit. To link it to your account and unlock your full plan, please confirm:
+ Confirm & Link Key
+ If you did not authorize this, you can block the key:
+ Block this key
+ This confirmation link expires on ${deadline.toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric" })}.
+ If you have questions, reach out to us at help@firecrawl.com.
+
+ Thanks,
Firecrawl Team
+ `,
+ });
+ if (sendResult.data?.id) {
+ logger.info("Agent sponsor confirmation email sent", {
+ to: email,
+ resendId: sendResult.data.id,
+ });
+ } else {
+ logger.warn(
+ "Agent sponsor confirmation email failed or returned no id",
+ {
+ to: email,
+ error: sendResult.error,
+ },
+ );
+ }
+ } catch (err) {
+ logger.error("Failed to send agent sponsor confirmation email", {
+ to: email,
+ error: err,
+ message: err instanceof Error ? err.message : String(err),
+ });
+ }
+ } else {
+ logger.warn(
+ "RESEND_API_KEY not set; skipping agent sponsor confirmation email",
+ {
+ to: email,
+ },
+ );
+ }
+
+ // If sponsor email matches an existing user, queue in-app notification
+ const { data: existingUser } = await supabase_rr_service
+ .from("users")
+ .select("team_id")
+ .eq("email", email)
+ .limit(1);
+
+ if (existingUser && existingUser.length > 0) {
+ await supabase_service
+ .from("user_notifications")
+ .insert({
+ team_id: existingUser[0].team_id,
+ notification_type: "agentSponsorConfirm",
+ sent_date: new Date().toISOString(),
+ timestamp: new Date().toISOString(),
+ metadata: {
+ agent_name,
+ confirm_url: confirmUrl,
+ block_url: blockUrl,
+ verification_token: verificationToken,
+ deadline: deadline.toISOString(),
+ },
+ } as any)
+ .then(({ error }) => {
+ if (error) {
+ logger.error("Failed to insert in-app notification", { error });
+ }
+ });
+ }
+
+ logger.info("Agent signup completed", {
+ email,
+ agent_name,
+ teamId,
+ apiKeyId: apiKeyRecord.id,
+ });
+
+ return res.status(201).json({
+ success: true,
+ api_key: apiKeyToFcApiKey(apiKeyRecord.key),
+ sponsor_status: "pending",
+ credit_limit: 50,
+ credits_remaining: 50,
+ verification_deadline_at: deadline.toISOString(),
+ tos_url: "https://firecrawl.dev/terms-of-service",
+ });
+ } catch (error) {
+ if (error instanceof z.ZodError) {
+ return res.status(400).json({
+ success: false,
+ error:
+ "Invalid request body: " +
+ (error as z.ZodError).issues
+ .map((e: z.ZodIssue) => e.message)
+ .join(", "),
+ });
+ }
+ logger.error("Unexpected error in agent signup", { error });
+ return res
+ .status(500)
+ .json({ success: false, error: "Internal server error" });
+ }
+}
+
+function escapeHtml(str: string): string {
+ return str
+ .replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+}
diff --git a/apps/api/src/controllers/v2/agent-status.ts b/apps/api/src/controllers/v2/agent-status.ts
index a2c99ce5f4..482445f07d 100644
--- a/apps/api/src/controllers/v2/agent-status.ts
+++ b/apps/api/src/controllers/v2/agent-status.ts
@@ -4,8 +4,9 @@ import {
supabaseGetAgentByIdDirect,
supabaseGetAgentRequestByIdDirect,
} from "../../lib/supabase-jobs";
-import { logger as _logger } from "../../lib/logger";
+import { logger as _logger, logger } from "../../lib/logger";
import { getJobFromGCS } from "../../lib/gcs-jobs";
+import { config } from "../../config";
export async function agentStatusController(
req: RequestWithAuth<{ jobId: string }, AgentStatusResponse, any>,
@@ -24,6 +25,49 @@ export async function agentStatusController(
const agent = await supabaseGetAgentByIdDirect(req.params.jobId);
+ let model: "spark-1-pro" | "spark-1-mini";
+ if (agent) {
+ model = (agent.options?.model ?? "spark-1-pro") as
+ | "spark-1-pro"
+ | "spark-1-mini";
+ } else {
+ try {
+ const optionsRequest = await fetch(
+ config.EXTRACT_V3_BETA_URL +
+ "/v2/extract/" +
+ req.params.jobId +
+ "/options",
+ {
+ headers: {
+ Authorization: `Bearer ${config.AGENT_INTEROP_SECRET}`,
+ },
+ },
+ );
+
+ if (optionsRequest.status !== 200) {
+ logger.warn("Failed to get agent request details", {
+ status: optionsRequest.status,
+ method: "agentStatusController",
+ module: "api/v2",
+ text: await optionsRequest.text(),
+ });
+ model = "spark-1-pro"; // fall back to this value
+ } else {
+ model = ((await optionsRequest.json()).model ?? "spark-1-pro") as
+ | "spark-1-pro"
+ | "spark-1-mini";
+ }
+ } catch (error) {
+ logger.warn("Failed to get agent request details", {
+ error,
+ method: "agentStatusController",
+ module: "api/v2",
+ extractId: req.params.jobId,
+ });
+ model = "spark-1-pro"; // fall back to this value
+ }
+ }
+
let data: any = undefined;
if (agent?.is_successful) {
data = await getJobFromGCS(agent.id);
@@ -38,6 +82,7 @@ export async function agentStatusController(
: "failed",
error: agent?.error || undefined,
data,
+ model,
expiresAt: new Date(
new Date(agent?.created_at ?? agentRequest.created_at).getTime() +
1000 * 60 * 60 * 24,
diff --git a/apps/api/src/controllers/v2/agent.ts b/apps/api/src/controllers/v2/agent.ts
index 7fd8e7d755..bb86e850d2 100644
--- a/apps/api/src/controllers/v2/agent.ts
+++ b/apps/api/src/controllers/v2/agent.ts
@@ -101,6 +101,8 @@ export async function agentController(
isFreeRequest,
maxCredits: req.body.maxCredits ?? undefined,
strictConstrainToURLs: req.body.strictConstrainToURLs ?? undefined,
+ webhook: req.body.webhook ?? undefined,
+ model: req.body.model,
}),
},
);
diff --git a/apps/api/src/controllers/v2/batch-scrape.ts b/apps/api/src/controllers/v2/batch-scrape.ts
index 7614f513b4..50da40aa08 100644
--- a/apps/api/src/controllers/v2/batch-scrape.ts
+++ b/apps/api/src/controllers/v2/batch-scrape.ts
@@ -23,7 +23,7 @@ import { getJobPriority } from "../../lib/job-priority";
import { addScrapeJobs } from "../../services/queue-jobs";
import { createWebhookSender, WebhookEvent } from "../../services/webhook";
import { logger as _logger } from "../../lib/logger";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../lib/strings";
import { isUrlBlocked } from "../../scraper/WebScraper/utils/blocklist";
import { checkPermissions } from "../../lib/permissions";
import { crawlGroup } from "../../services/worker/nuq";
@@ -109,7 +109,7 @@ export async function batchScrapeController(
if (!res.headersSent) {
return res.status(403).json({
success: false,
- error: BLOCKLISTED_URL_MESSAGE,
+ error: UNSUPPORTED_SITE_MESSAGE,
});
}
}
@@ -154,6 +154,7 @@ export async function batchScrapeController(
? true
: false,
zeroDataRetention,
+ bypassBilling: !(req.body.__agentInterop?.shouldBill ?? true),
}, // NOTE: smart wait disabled for batch scrapes to ensure contentful scrape, speed does not matter
team_id: req.auth.team_id,
createdAt: Date.now(),
@@ -161,6 +162,15 @@ export async function batchScrapeController(
zeroDataRetention,
};
+ if (req.body.appendToId) {
+ if (!sc || sc.team_id !== req.auth.team_id) {
+ return res.status(404).json({
+ success: false,
+ error: "Job not found",
+ });
+ }
+ }
+
if (!req.body.appendToId) {
await crawlGroup.addGroup(
id,
diff --git a/apps/api/src/controllers/v2/browser.ts b/apps/api/src/controllers/v2/browser.ts
new file mode 100644
index 0000000000..fe3fdcd8c1
--- /dev/null
+++ b/apps/api/src/controllers/v2/browser.ts
@@ -0,0 +1,714 @@
+import { createHash } from "crypto";
+import { v7 as uuidv7 } from "uuid";
+import { Request, Response } from "express";
+import { z } from "zod";
+import { logger as _logger } from "../../lib/logger";
+import { config } from "../../config";
+import {
+ insertBrowserSession,
+ getBrowserSession,
+ getBrowserSessionByBrowserId,
+ listBrowserSessions,
+ updateBrowserSessionActivity,
+ updateBrowserSessionStatus,
+ updateBrowserSessionCreditsUsed,
+ claimBrowserSessionDestroyed,
+ getActiveBrowserSessionCount,
+ invalidateActiveBrowserSessionCount,
+ MAX_ACTIVE_BROWSER_SESSIONS_PER_TEAM,
+} from "../../lib/browser-sessions";
+import { RequestWithAuth } from "./types";
+import { billTeam } from "../../services/billing/credit_billing";
+import { enqueueBrowserSessionActivity } from "../../lib/browser-session-activity";
+import { logRequest } from "../../services/logging/log_job";
+import { integrationSchema } from "../../utils/integration";
+
+const BROWSER_CREDITS_PER_HOUR = 120;
+
+/**
+ * Calculate credits to bill for a browser session based on its duration.
+ * Prorates to the millisecond. Minimum charge is 1 credit.
+ */
+function calculateBrowserSessionCredits(durationMs: number): number {
+ const hours = durationMs / 3_600_000;
+ return Math.max(1, Math.ceil(hours * BROWSER_CREDITS_PER_HOUR));
+}
+
+// ---------------------------------------------------------------------------
+// Zod schemas
+// ---------------------------------------------------------------------------
+
+const browserCreateRequestSchema = z.object({
+ ttl: z.number().min(30).max(3600).default(600),
+ activityTtl: z.number().min(10).max(3600).default(300),
+ streamWebView: z.boolean().default(true),
+ integration: integrationSchema.optional().transform(val => val || null),
+ profile: z
+ .object({
+ name: z.string().min(1).max(128),
+ saveChanges: z.boolean().default(true),
+ })
+ .optional(),
+});
+
+type BrowserCreateRequest = z.infer;
+
+interface BrowserCreateResponse {
+ success: boolean;
+ id?: string;
+ cdpUrl?: string;
+ liveViewUrl?: string;
+ interactiveLiveViewUrl?: string;
+ expiresAt?: string;
+ error?: string;
+}
+
+const browserExecuteRequestSchema = z.object({
+ code: z.string().min(1).max(100_000),
+ language: z.enum(["python", "node", "bash"]).default("node"),
+ timeout: z.number().min(1).max(300).default(30),
+ origin: z.string().optional(),
+});
+
+type BrowserExecuteRequest = z.infer;
+
+interface BrowserExecuteResponse {
+ success: boolean;
+ stdout?: string;
+ result?: string;
+ stderr?: string;
+ exitCode?: number;
+ killed?: boolean;
+ error?: string;
+}
+
+interface BrowserDeleteResponse {
+ success: boolean;
+ sessionDurationMs?: number;
+ creditsBilled?: number;
+ error?: string;
+}
+
+interface BrowserListResponse {
+ success: boolean;
+ sessions?: Array<{
+ id: string;
+ status: string;
+ cdpUrl: string;
+ liveViewUrl: string;
+ interactiveLiveViewUrl: string;
+ streamWebView: boolean;
+ createdAt: string;
+ lastActivity: string;
+ }>;
+ error?: string;
+}
+
+// ---------------------------------------------------------------------------
+// Helpers
+// ---------------------------------------------------------------------------
+
+/**
+ * Build headers for authenticating against the browser service.
+ */
+function browserServiceHeaders(
+ extra?: Record,
+): Record {
+ const headers: Record = {
+ "Content-Type": "application/json",
+ ...(extra ?? {}),
+ };
+ if (config.BROWSER_SERVICE_API_KEY) {
+ headers["Authorization"] = `Bearer ${config.BROWSER_SERVICE_API_KEY}`;
+ }
+ return headers;
+}
+
+class BrowserServiceError extends Error {
+ status: number;
+ constructor(status: number, message: string) {
+ super(message);
+ this.status = status;
+ }
+}
+
+/**
+ * Call the browser service and return parsed JSON.
+ * Throws on non-2xx responses.
+ */
+async function browserServiceRequest(
+ method: string,
+ path: string,
+ body?: unknown,
+): Promise {
+ const url = `${config.BROWSER_SERVICE_URL}${path}`;
+ const res = await fetch(url, {
+ method,
+ headers: browserServiceHeaders(),
+ body: body ? JSON.stringify(body) : undefined,
+ });
+
+ if (!res.ok) {
+ const text = await res.text();
+ throw new BrowserServiceError(
+ res.status,
+ `Browser service ${method} ${path} failed (${res.status}): ${text}`,
+ );
+ }
+
+ if (res.status === 204) return undefined as T;
+ return res.json() as Promise;
+}
+
+// ---------------------------------------------------------------------------
+// Browser service response types
+// ---------------------------------------------------------------------------
+
+interface BrowserServiceCreateResponse {
+ sessionId: string;
+ cdpUrl: string;
+ viewUrl: string;
+ iframeUrl: string;
+ interactiveIframeUrl: string;
+ expiresAt: string;
+}
+
+interface BrowserServiceExecResponse {
+ stdout: string;
+ result: string;
+ stderr: string;
+ exitCode: number;
+ killed: boolean;
+}
+
+interface BrowserServiceDeleteResponse {
+ ok: boolean;
+ sessionDurationMs: number;
+}
+
+// ---------------------------------------------------------------------------
+// Controllers
+// ---------------------------------------------------------------------------
+
+export async function browserCreateController(
+ req: RequestWithAuth<{}, BrowserCreateResponse, BrowserCreateRequest>,
+ res: Response,
+) {
+ // if (!req.acuc?.flags?.browserBeta) {
+ // return res.status(403).json({
+ // success: false,
+ // error:
+ // "Browser is currently in beta. Please contact support@firecrawl.com to request access.",
+ // });
+ // }
+
+ const sessionId = uuidv7();
+ const logger = _logger.child({
+ sessionId,
+ teamId: req.auth.team_id,
+ module: "api/v2",
+ method: "browserCreateController",
+ });
+
+ req.body = browserCreateRequestSchema.parse(req.body);
+
+ const { ttl, activityTtl, streamWebView, profile, integration } = req.body;
+
+ if (!config.BROWSER_SERVICE_URL) {
+ return res.status(503).json({
+ success: false,
+ error:
+ "Browser feature is not configured (BROWSER_SERVICE_URL is missing).",
+ });
+ }
+
+ logger.info("Creating browser session", { ttl, activityTtl });
+
+ // 0a. Check if team has enough credits for the full TTL
+ const estimatedCredits = calculateBrowserSessionCredits(ttl * 1000);
+ if (req.acuc && req.acuc.remaining_credits < estimatedCredits) {
+ logger.warn("Insufficient credits for browser session TTL", {
+ estimatedCredits,
+ remainingCredits: req.acuc.remaining_credits,
+ ttl,
+ });
+ return res.status(402).json({
+ success: false,
+ error: `Insufficient credits for a ${ttl}s browser session (requires ~${estimatedCredits} credits). For more credits, you can upgrade your plan at https://firecrawl.dev/pricing.`,
+ });
+ }
+
+ // 0b. Enforce per-team active session limit
+ const activeCount = await getActiveBrowserSessionCount(req.auth.team_id);
+ if (activeCount >= MAX_ACTIVE_BROWSER_SESSIONS_PER_TEAM) {
+ logger.warn("Active browser session limit reached", {
+ activeCount,
+ limit: MAX_ACTIVE_BROWSER_SESSIONS_PER_TEAM,
+ });
+ return res.status(429).json({
+ success: false,
+ error: `You have reached the maximum number of active browser sessions (${MAX_ACTIVE_BROWSER_SESSIONS_PER_TEAM}). Please destroy existing sessions before creating new ones.`,
+ });
+ }
+
+ // 1. Create a browser session via the browser service (retry up to 3 times)
+ const MAX_CREATE_RETRIES = 3;
+ let svcResponse: BrowserServiceCreateResponse | undefined;
+ let lastCreateError: unknown;
+
+ // Build persistentStorage from profile if provided
+ let persistentStorage: { uniqueId: string; write: boolean } | undefined;
+ if (profile) {
+ const teamHash = createHash("sha256")
+ .update(req.auth.team_id)
+ .digest("hex")
+ .slice(0, 16);
+ persistentStorage = {
+ uniqueId: `${teamHash}_${profile.name}`,
+ write: profile.saveChanges !== false,
+ };
+ }
+
+ for (let attempt = 1; attempt <= MAX_CREATE_RETRIES; attempt++) {
+ try {
+ svcResponse = await browserServiceRequest(
+ "POST",
+ "/browsers",
+ {
+ ttl,
+ ...(activityTtl !== undefined ? { activityTtl } : {}),
+ ...(persistentStorage !== undefined ? { persistentStorage } : {}),
+ },
+ );
+ break;
+ } catch (err) {
+ // 409 means the profile is locked by another writer — don't retry
+ if (err instanceof BrowserServiceError && err.status === 409) {
+ logger.warn("Profile is locked", {
+ profileName: profile?.name,
+ error: err,
+ });
+ return res.status(409).json({
+ success: false,
+ error:
+ "Another session is currently writing to this profile. Only one writer is allowed at a time. You can still access it with saveChanges: false, or try again later.",
+ });
+ }
+
+ lastCreateError = err;
+ logger.warn("Browser session creation attempt failed", {
+ attempt,
+ maxRetries: MAX_CREATE_RETRIES,
+ error: err,
+ });
+ if (attempt < MAX_CREATE_RETRIES) {
+ await new Promise(resolve => setTimeout(resolve, 200 * attempt));
+ }
+ }
+ }
+
+ if (!svcResponse) {
+ logger.error("Failed to create browser session after all retries", {
+ error: lastCreateError,
+ attempts: MAX_CREATE_RETRIES,
+ });
+ return res.status(502).json({
+ success: false,
+ error: "Failed to create browser session.",
+ });
+ }
+
+ // 2. Persist session in Supabase
+ try {
+ await logRequest({
+ id: sessionId,
+ kind: "browser",
+ api_version: "v2",
+ team_id: req.auth.team_id,
+ target_hint: "Browser session",
+ origin: "api",
+ integration: integration ?? null,
+ zeroDataRetention: false,
+ api_key_id: req.acuc!.api_key_id,
+ });
+ await insertBrowserSession({
+ id: sessionId,
+ team_id: req.auth.team_id,
+ browser_id: svcResponse.sessionId,
+ workspace_id: "",
+ context_id: "",
+ cdp_url: svcResponse.cdpUrl,
+ cdp_path: svcResponse.iframeUrl, // repurposed: stores view URL
+ cdp_interactive_path: svcResponse.interactiveIframeUrl, // repurposed: stores interactive view URL
+ stream_web_view: streamWebView,
+ status: "active",
+ ttl_total: ttl,
+ ttl_without_activity: activityTtl ?? null,
+ credits_used: null,
+ });
+ } catch (err) {
+ // If we can't persist, tear down the browser session
+ logger.error("Failed to persist browser session, cleaning up", {
+ error: err,
+ });
+ await browserServiceRequest(
+ "DELETE",
+ `/browsers/${svcResponse.sessionId}`,
+ ).catch(() => {});
+ return res.status(500).json({
+ success: false,
+ error: "Failed to persist browser session.",
+ });
+ }
+
+ // Invalidate cached count so next check reflects the new session
+ invalidateActiveBrowserSessionCount(req.auth.team_id).catch(() => {});
+
+ logger.info("Browser session created", {
+ sessionId,
+ browserId: svcResponse.sessionId,
+ });
+
+ return res.status(200).json({
+ success: true,
+ id: sessionId,
+ cdpUrl: svcResponse.cdpUrl,
+ liveViewUrl: svcResponse.iframeUrl,
+ interactiveLiveViewUrl: svcResponse.interactiveIframeUrl,
+ expiresAt: svcResponse.expiresAt,
+ });
+}
+
+export async function browserExecuteController(
+ req: RequestWithAuth<
+ { sessionId: string },
+ BrowserExecuteResponse,
+ BrowserExecuteRequest
+ >,
+ res: Response,
+) {
+ // if (!req.acuc?.flags?.browserBeta) {
+ // return res.status(403).json({
+ // success: false,
+ // error:
+ // "Browser is currently in beta. Please contact support@firecrawl.com to request access.",
+ // });
+ // }
+
+ req.body = browserExecuteRequestSchema.parse(req.body);
+
+ const id = req.params.sessionId;
+ const { code, language, timeout, origin } = req.body;
+
+ const logger = _logger.child({
+ sessionId: id,
+ teamId: req.auth.team_id,
+ module: "api/v2",
+ method: "browserExecuteController",
+ });
+
+ // Look up session from Supabase
+ const session = await getBrowserSession(id);
+
+ if (!session) {
+ return res.status(404).json({
+ success: false,
+ error: "Browser session not found.",
+ });
+ }
+
+ if (session.team_id !== req.auth.team_id) {
+ return res.status(403).json({
+ success: false,
+ error: "Forbidden.",
+ });
+ }
+
+ if (session.status === "destroyed") {
+ return res.status(410).json({
+ success: false,
+ error: "Browser session has been destroyed.",
+ });
+ }
+
+ // Update activity timestamp (fire-and-forget)
+ updateBrowserSessionActivity(id).catch(() => {});
+
+ logger.info("Executing code in browser session", { language, timeout });
+
+ // Execute code via the browser service
+ let execResult: BrowserServiceExecResponse;
+ try {
+ execResult = await browserServiceRequest(
+ "POST",
+ `/browsers/${session.browser_id}/exec`,
+ { code, language, timeout, origin },
+ );
+ } catch (err) {
+ logger.error("Failed to execute code via browser service", { error: err });
+ return res.status(502).json({
+ success: false,
+ error: "Failed to execute code in browser session.",
+ });
+ }
+
+ logger.debug("Execution result", {
+ exitCode: execResult.exitCode,
+ killed: execResult.killed,
+ stdoutLength: execResult.stdout?.length,
+ stderrLength: execResult.stderr?.length,
+ });
+
+ enqueueBrowserSessionActivity({
+ team_id: req.auth.team_id,
+ session_id: id,
+ language,
+ timeout,
+ exit_code: execResult.exitCode ?? null,
+ killed: execResult.killed ?? false,
+ });
+
+ const hasError = execResult.exitCode !== 0 || execResult.killed;
+
+ return res.status(200).json({
+ success: true,
+ stdout: execResult.stdout,
+ result: execResult.result,
+ stderr: execResult.stderr,
+ exitCode: execResult.exitCode,
+ killed: execResult.killed,
+ ...(hasError ? { error: execResult.stderr || "Execution failed" } : {}),
+ });
+}
+
+export async function browserDeleteController(
+ req: RequestWithAuth<{ sessionId: string }, BrowserDeleteResponse>,
+ res: Response,
+) {
+ // if (!req.acuc?.flags?.browserBeta) {
+ // return res.status(403).json({
+ // success: false,
+ // error:
+ // "Browser is currently in beta. Please contact support@firecrawl.com to request access.",
+ // });
+ // }
+
+ const id = req.params.sessionId;
+
+ const logger = _logger.child({
+ sessionId: id,
+ teamId: req.auth.team_id,
+ module: "api/v2",
+ method: "browserDeleteController",
+ });
+
+ const session = await getBrowserSession(id);
+
+ if (!session) {
+ return res.status(404).json({
+ success: false,
+ error: "Browser session not found.",
+ });
+ }
+
+ if (session.team_id !== req.auth.team_id) {
+ return res.status(403).json({
+ success: false,
+ error: "Forbidden.",
+ });
+ }
+
+ logger.info("Deleting browser session");
+
+ // Release the browser session via the browser service
+ let sessionDurationMs: number | undefined;
+ try {
+ const deleteResult =
+ await browserServiceRequest(
+ "DELETE",
+ `/browsers/${session.browser_id}`,
+ );
+ sessionDurationMs = deleteResult?.sessionDurationMs;
+ } catch (err) {
+ logger.warn("Failed to delete browser session via browser service", {
+ error: err,
+ });
+ }
+
+ const claimed = await claimBrowserSessionDestroyed(session.id);
+
+ // Invalidate cached count so next check reflects the destroyed session
+ invalidateActiveBrowserSessionCount(session.team_id).catch(() => {});
+
+ if (!claimed) {
+ // The webhook (or another DELETE call) already transitioned and billed.
+ logger.info("Session already destroyed by another path, skipping billing", {
+ sessionId: session.id,
+ });
+ return res.status(200).json({
+ success: true,
+ });
+ }
+
+ const durationMs =
+ sessionDurationMs ?? Date.now() - new Date(session.created_at).getTime();
+ const creditsBilled = calculateBrowserSessionCredits(durationMs);
+
+ updateBrowserSessionCreditsUsed(session.id, creditsBilled).catch(error => {
+ logger.error("Failed to update credits_used on browser session", {
+ error,
+ sessionId: session.id,
+ creditsBilled,
+ });
+ });
+
+ billTeam(
+ req.auth.team_id,
+ req.acuc?.sub_id ?? undefined,
+ creditsBilled,
+ req.acuc?.api_key_id ?? null,
+ ).catch(error => {
+ logger.error("Failed to bill team for browser session", {
+ error,
+ creditsBilled,
+ durationMs,
+ });
+ });
+
+ logger.info("Browser session destroyed", {
+ sessionDurationMs: durationMs,
+ creditsBilled,
+ });
+
+ return res.status(200).json({
+ success: true,
+ });
+}
+
+export async function browserListController(
+ req: RequestWithAuth<{}, BrowserListResponse>,
+ res: Response,
+) {
+ // if (!req.acuc?.flags?.browserBeta) {
+ // return res.status(403).json({
+ // success: false,
+ // error:
+ // "Browser is currently in beta. Please contact support@firecrawl.com to request access.",
+ // });
+ // }
+
+ const logger = _logger.child({
+ teamId: req.auth.team_id,
+ module: "api/v2",
+ method: "browserListController",
+ });
+
+ logger.info("Listing browser sessions");
+
+ const statusFilter = (req.query as Record).status as
+ | "active"
+ | "destroyed"
+ | undefined;
+
+ const rows = await listBrowserSessions(req.auth.team_id, {
+ status: statusFilter,
+ });
+
+ return res.status(200).json({
+ success: true,
+ sessions: rows.map(r => ({
+ id: r.id,
+ status: r.status,
+ cdpUrl: r.cdp_url,
+ liveViewUrl: r.cdp_path, // cdp_path stores the view URL
+ interactiveLiveViewUrl: r.cdp_interactive_path, // cdp_interactive_path stores the interactive view URL
+ streamWebView: r.stream_web_view,
+ createdAt: r.created_at,
+ lastActivity: r.updated_at,
+ })),
+ });
+}
+
+export async function browserWebhookDestroyedController(
+ req: Request,
+ res: Response,
+) {
+ const logger = _logger.child({
+ module: "api/v2",
+ method: "browserWebhookDestroyedController",
+ });
+
+ // Validate browser service secret
+ const secret = req.headers["x-browser-service-secret"];
+ if (
+ !config.BROWSER_SERVICE_WEBHOOK_SECRET ||
+ !secret ||
+ secret !== config.BROWSER_SERVICE_WEBHOOK_SECRET
+ ) {
+ return res.status(401).json({ error: "Unauthorized" });
+ }
+
+ const { sessionId } = req.body as { sessionId?: string };
+ if (!sessionId) {
+ return res.status(400).json({ error: "Missing browserId" });
+ }
+ let browserId = sessionId;
+
+ logger.info("Received destroyed webhook from browser service", { browserId });
+
+ const session = await getBrowserSessionByBrowserId(browserId);
+ if (!session) {
+ logger.warn("No session found for destroyed webhook", { browserId });
+ return res.status(200).json({ ok: true });
+ }
+
+ const claimed = await claimBrowserSessionDestroyed(session.id);
+
+ invalidateActiveBrowserSessionCount(session.team_id).catch(() => {});
+
+ if (!claimed) {
+ logger.info("Session already destroyed by another path, skipping billing", {
+ sessionId: session.id,
+ browserId,
+ });
+ return res.status(200).json({ ok: true });
+ }
+
+ const durationMs = Date.now() - new Date(session.created_at).getTime();
+ const creditsBilled = calculateBrowserSessionCredits(durationMs);
+
+ updateBrowserSessionCreditsUsed(session.id, creditsBilled).catch(error => {
+ logger.error(
+ "Failed to update credits_used on browser session via webhook",
+ {
+ error,
+ sessionId: session.id,
+ creditsBilled,
+ },
+ );
+ });
+
+ billTeam(
+ session.team_id,
+ undefined, // subscription_id — billTeam will look it up
+ creditsBilled,
+ null, // api_key_id not available in webhook context
+ ).catch(error => {
+ logger.error("Failed to bill team for browser session via webhook", {
+ error,
+ teamId: session.team_id,
+ sessionId: session.id,
+ creditsBilled,
+ durationMs,
+ });
+ });
+
+ logger.info("Session marked as destroyed via webhook", {
+ sessionId: session.id,
+ browserId,
+ durationMs,
+ creditsBilled,
+ });
+
+ return res.status(200).json({ ok: true });
+}
diff --git a/apps/api/src/controllers/v2/crawl-params-preview.ts b/apps/api/src/controllers/v2/crawl-params-preview.ts
index cdeaf2b28c..312a3af9af 100644
--- a/apps/api/src/controllers/v2/crawl-params-preview.ts
+++ b/apps/api/src/controllers/v2/crawl-params-preview.ts
@@ -29,7 +29,7 @@ type CrawlParamsPreviewResponse =
crawlEntireDomain?: boolean;
allowExternalLinks?: boolean;
allowSubdomains?: boolean;
- sitemap?: "skip" | "include";
+ sitemap?: "skip" | "include" | "only";
ignoreQueryParameters?: boolean;
deduplicateSimilarURLs?: boolean;
delay?: number;
diff --git a/apps/api/src/controllers/v2/crawl-status.ts b/apps/api/src/controllers/v2/crawl-status.ts
index 9d29491e0d..7b7d44cfa5 100644
--- a/apps/api/src/controllers/v2/crawl-status.ts
+++ b/apps/api/src/controllers/v2/crawl-status.ts
@@ -294,7 +294,7 @@ export async function crawlStatusController(
next:
(outputBulkA.total ?? 0) > start + iteratedOver ||
outputBulkA.status !== "completed"
- ? `${req.protocol}://${req.get("host")}/v1/${isBatch ? "batch/scrape" : "crawl"}/${req.params.jobId}?skip=${start + iteratedOver}${req.query.limit ? `&limit=${req.query.limit}` : ""}`
+ ? `${req.protocol}://${req.get("host")}/v2/${isBatch ? "batch/scrape" : "crawl"}/${req.params.jobId}?skip=${start + iteratedOver}${req.query.limit ? `&limit=${req.query.limit}` : ""}`
: undefined,
};
diff --git a/apps/api/src/controllers/v2/extract.ts b/apps/api/src/controllers/v2/extract.ts
index f5f5504074..44b69a5b7e 100644
--- a/apps/api/src/controllers/v2/extract.ts
+++ b/apps/api/src/controllers/v2/extract.ts
@@ -8,7 +8,7 @@ import {
} from "./types";
import { addExtractJobToQueue } from "../../services/queue-service";
import { saveExtract } from "../../lib/extract/extract-redis";
-import { BLOCKLISTED_URL_MESSAGE } from "../../lib/strings";
+import { UNSUPPORTED_SITE_MESSAGE } from "../../lib/strings";
import { isUrlBlocked } from "../../scraper/WebScraper/utils/blocklist";
import { logger as _logger } from "../../lib/logger";
import { logRequest } from "../../services/logging/log_job";
@@ -51,7 +51,8 @@ export async function extractController(
if (req.body.agent?.model === "v3-beta") {
return res.status(400).json({
success: false,
- error: "Use the new /agent endpoint instead of passing agent.model=v3-beta into /extract.",
+ error:
+ "Use the new /agent endpoint instead of passing agent.model=v3-beta into /extract.",
});
}
@@ -64,7 +65,7 @@ export async function extractController(
if (!res.headersSent) {
return res.status(403).json({
success: false,
- error: BLOCKLISTED_URL_MESSAGE,
+ error: UNSUPPORTED_SITE_MESSAGE,
});
}
}
@@ -113,8 +114,8 @@ export async function extractController(
urlTrace: [],
...(invalidURLs.length > 0 && req.body.ignoreInvalidURLs
? {
- invalidURLs,
- }
+ invalidURLs,
+ }
: {}),
});
}
diff --git a/apps/api/src/controllers/v2/map.ts b/apps/api/src/controllers/v2/map.ts
index 14599f0f6b..4c5adcf139 100644
--- a/apps/api/src/controllers/v2/map.ts
+++ b/apps/api/src/controllers/v2/map.ts
@@ -90,6 +90,7 @@ export async function mapController(
filterByPath: req.body.filterByPath !== false,
flags: req.acuc?.flags ?? null,
useIndex: req.body.useIndex,
+ ignoreCache: req.body.ignoreCache,
location: req.body.location,
headers: req.body.headers,
id: mapId,
diff --git a/apps/api/src/controllers/v2/scrape.ts b/apps/api/src/controllers/v2/scrape.ts
index a595992554..4dc37720ad 100644
--- a/apps/api/src/controllers/v2/scrape.ts
+++ b/apps/api/src/controllers/v2/scrape.ts
@@ -20,6 +20,10 @@ import { ScrapeJobData } from "../../types";
import { teamConcurrencySemaphore } from "../../services/worker/team-semaphore";
import { getJobPriority } from "../../lib/job-priority";
import { logRequest } from "../../services/logging/log_job";
+import { getErrorContactMessage } from "../../lib/deployment";
+import { captureExceptionWithZdrCheck } from "../../services/sentry";
+
+const AGENT_INTEROP_CONCURRENCY_BOOST = 3;
export async function scrapeController(
req: RequestWithAuth<{}, ScrapeResponse, ScrapeRequest>,
@@ -98,6 +102,8 @@ export async function scrapeController(
const shouldBill = req.body.__agentInterop?.shouldBill ?? true;
const agentRequestId = req.body.__agentInterop?.requestId ?? null;
+ const boostConcurrency =
+ req.body.__agentInterop?.boostConcurrency ?? false;
const logger = _logger.child({
method: "scrapeController",
@@ -120,7 +126,7 @@ export async function scrapeController(
});
if (!agentRequestId) {
- await logRequest({
+ logRequest({
id: jobId,
kind: "scrape",
api_version: "v2",
@@ -130,7 +136,9 @@ export async function scrapeController(
target_hint: req.body.url,
zeroDataRetention: zeroDataRetention || false,
api_key_id: req.acuc?.api_key_id ?? null,
- });
+ }).catch(err =>
+ logger.warn("Background request log failed", { error: err, jobId }),
+ );
}
setSpanAttributes(span, {
@@ -170,10 +178,15 @@ export async function scrapeController(
}
req.on("close", () => aborter.abort());
+ const baseConcurrency = req.acuc?.concurrency || 1;
+ const concurrency = boostConcurrency
+ ? baseConcurrency * AGENT_INTEROP_CONCURRENCY_BOOST
+ : baseConcurrency;
+
doc = await teamConcurrencySemaphore.withSemaphore(
req.auth.team_id,
jobId,
- req.acuc?.concurrency || 1,
+ concurrency,
aborter.signal,
timeout ?? 60_000,
async limited => {
@@ -258,13 +271,6 @@ export async function scrapeController(
const timeoutErr =
e instanceof TransportableError && e.code === "SCRAPE_TIMEOUT";
- if (!timeoutErr) {
- logger.error(`Error in scrapeController`, {
- version: "v2",
- error: e,
- });
- }
-
setSpanAttributes(span, {
"scrape.error": e instanceof Error ? e.message : String(e),
"scrape.error_type":
@@ -272,6 +278,12 @@ export async function scrapeController(
});
if (e instanceof TransportableError) {
+ if (!timeoutErr) {
+ logger.error(`Error in scrapeController`, {
+ version: "v2",
+ error: e,
+ });
+ }
// DNS resolution errors should return 200 with success: false
if (e.code === "SCRAPE_DNS_RESOLUTION_ERROR") {
setSpanAttributes(span, {
@@ -295,6 +307,17 @@ export async function scrapeController(
});
}
+ if (e.code === "SCRAPE_ACTIONS_NOT_SUPPORTED") {
+ setSpanAttributes(span, {
+ "scrape.status_code": 400,
+ });
+ return res.status(400).json({
+ success: false,
+ code: e.code,
+ error: e.message,
+ });
+ }
+
const statusCode = e.code === "SCRAPE_TIMEOUT" ? 408 : 500;
setSpanAttributes(span, {
"scrape.status_code": statusCode,
@@ -305,12 +328,34 @@ export async function scrapeController(
error: e.message,
});
} else {
+ const id = uuidv7();
+ logger.error(`Error in scrapeController`, {
+ version: "v2",
+ error: e,
+ errorId: id,
+ path: req.path,
+ teamId: req.auth.team_id,
+ });
+ captureExceptionWithZdrCheck(e, {
+ tags: {
+ errorId: id,
+ version: "v2",
+ teamId: req.auth.team_id,
+ },
+ extra: {
+ path: req.path,
+ url: req.body.url,
+ },
+ zeroDataRetention,
+ });
setSpanAttributes(span, {
"scrape.status_code": 500,
+ "scrape.error_id": id,
});
return res.status(500).json({
success: false,
- error: `(Internal server error) - ${e && e.message ? e.message : e}`,
+ code: "UNKNOWN_ERROR",
+ error: getErrorContactMessage(id),
});
}
} finally {
diff --git a/apps/api/src/controllers/v2/search.ts b/apps/api/src/controllers/v2/search.ts
index 37334c5c03..44d738aaba 100644
--- a/apps/api/src/controllers/v2/search.ts
+++ b/apps/api/src/controllers/v2/search.ts
@@ -1,221 +1,28 @@
import { Response } from "express";
import { config } from "../../config";
import {
- Document,
RequestWithAuth,
SearchRequest,
SearchResponse,
searchRequestSchema,
- ScrapeOptions,
- TeamFlags,
} from "./types";
import { billTeam } from "../../services/billing/credit_billing";
import { v7 as uuidv7 } from "uuid";
-import { addScrapeJob, waitForJob } from "../../services/queue-jobs";
import { logSearch, logRequest } from "../../services/logging/log_job";
-import { search } from "../../search/v2";
-import { isUrlBlocked } from "../../scraper/WebScraper/utils/blocklist";
import { logger as _logger } from "../../lib/logger";
-import type { Logger } from "winston";
-import { getJobPriority } from "../../lib/job-priority";
-import { CostTracking } from "../../lib/cost-tracking";
-import { supabase_service } from "../../services/supabase";
-import { SearchV2Response } from "../../lib/entities";
import { ScrapeJobTimeoutError } from "../../lib/error";
-import { scrapeQueue } from "../../services/worker/nuq";
import { z } from "zod";
-import {
- buildSearchQuery,
- getCategoryFromUrl,
- CategoryOption,
-} from "../../lib/search-query-builder";
+import { CategoryOption } from "../../lib/search-query-builder";
import {
applyZdrScope,
captureExceptionWithZdrCheck,
} from "../../services/sentry";
-
-interface DocumentWithCostTracking {
- document: Document;
- costTracking: ReturnType;
-}
-
-interface ScrapeJobInput {
- url: string;
- title: string;
- description: string;
-}
-
-async function startScrapeJob(
- searchResult: { url: string; title: string; description: string },
- options: {
- teamId: string;
- origin: string;
- timeout: number;
- scrapeOptions: ScrapeOptions;
- bypassBilling?: boolean;
- apiKeyId: number | null;
- zeroDataRetention?: boolean;
- requestId?: string;
- },
- logger: Logger,
- flags: TeamFlags,
- directToBullMQ: boolean = false,
- isSearchPreview: boolean = false,
-): Promise {
- const jobId = uuidv7();
-
- const zeroDataRetention =
- flags?.forceZDR || (options.zeroDataRetention ?? false);
-
- logger.info("Adding scrape job", {
- scrapeId: jobId,
- url: searchResult.url,
- teamId: options.teamId,
- origin: options.origin,
- zeroDataRetention,
- });
-
- const jobPriority = await getJobPriority({
- team_id: options.teamId,
- basePriority: 10,
- });
-
- await addScrapeJob(
- {
- url: searchResult.url,
- mode: "single_urls",
- team_id: options.teamId,
- scrapeOptions: {
- ...options.scrapeOptions,
- // TODO: fix this
- maxAge: 3 * 24 * 60 * 60 * 1000, // 3 days
- },
- internalOptions: {
- teamId: options.teamId,
- bypassBilling: options.bypassBilling ?? true,
- zeroDataRetention,
- },
- origin: options.origin,
- // Do not touch this flag
- is_scrape: options.bypassBilling ?? false,
- startTime: Date.now(),
- zeroDataRetention,
- apiKeyId: options.apiKeyId,
- requestId: options.requestId,
- },
- jobId,
- jobPriority,
- directToBullMQ,
- true,
- );
-
- return jobId;
-}
-
-async function scrapeSearchResult(
- searchResult: { url: string; title: string; description: string },
- options: {
- teamId: string;
- origin: string;
- timeout: number;
- scrapeOptions: ScrapeOptions;
- bypassBilling?: boolean;
- apiKeyId: number | null;
- zeroDataRetention?: boolean;
- requestId?: string;
- },
- logger: Logger,
- flags: TeamFlags,
- directToBullMQ: boolean = false,
- isSearchPreview: boolean = false,
-): Promise {
- try {
- // Start the scrape job
- const jobId = await startScrapeJob(
- searchResult,
- options,
- logger,
- flags,
- directToBullMQ,
- isSearchPreview,
- );
-
- const doc: Document = await waitForJob(
- jobId,
- options.timeout,
- options.zeroDataRetention ?? false,
- logger,
- );
-
- logger.info("Scrape job completed", {
- scrapeId: jobId,
- url: searchResult.url,
- teamId: options.teamId,
- origin: options.origin,
- });
-
- await scrapeQueue.removeJob(jobId, logger);
-
- const document = {
- title: searchResult.title,
- description: searchResult.description,
- url: searchResult.url,
- ...doc,
- };
-
- let costTracking: ReturnType;
- if (config.USE_DB_AUTHENTICATION) {
- const { data: costTrackingResponse, error: costTrackingError } =
- await supabase_service
- .from("scrapes")
- .select("cost_tracking")
- .eq("id", jobId);
-
- if (costTrackingError) {
- logger.error("Error getting cost tracking", {
- error: costTrackingError,
- });
- throw costTrackingError;
- }
-
- costTracking = costTrackingResponse?.[0]?.cost_tracking;
- } else {
- costTracking = new CostTracking().toJSON();
- }
-
- return {
- document,
- costTracking,
- };
- } catch (error) {
- logger.error(`Error in scrapeSearchResult: ${error}`, {
- url: searchResult.url,
- teamId: options.teamId,
- });
-
- const document: Document = {
- title: searchResult.title,
- description: searchResult.description,
- url: searchResult.url,
- metadata: {
- statusCode: 500,
- error: error.message,
- proxyUsed: "basic",
- },
- };
-
- return {
- document,
- costTracking: new CostTracking().toJSON(),
- };
- }
-}
+import { executeSearch } from "../../search/execute";
export async function searchController(
req: RequestWithAuth<{}, SearchResponse, SearchRequest>,
res: Response,
) {
- // Get timing data from middleware (includes all middleware processing time)
const middlewareStartTime =
(req as any).requestTiming?.startTime || new Date().getTime();
const controllerStartTime = new Date().getTime();
@@ -242,8 +49,6 @@ export async function searchController(
config.SEARCH_PREVIEW_TOKEN !== undefined &&
config.SEARCH_PREVIEW_TOKEN === req.body.__searchPreviewToken;
- let credits_billed = 0;
-
let zeroDataRetention = false;
try {
@@ -289,411 +94,55 @@ export async function searchController(
origin: req.body.origin ?? "api",
integration: req.body.integration,
target_hint: req.body.query,
- zeroDataRetention: isZDROrAnon ?? false, // not supported for search
+ zeroDataRetention: isZDROrAnon ?? false,
api_key_id: req.acuc?.api_key_id ?? null,
});
}
- let limit = req.body.limit;
-
- // Buffer results by 50% to account for filtered URLs
- const num_results_buffer = Math.floor(limit * 2);
-
- logger.info("Searching for results");
-
- // Extract unique types from sources for the search function
- // After transformation, sources is always an array of objects
- const searchTypes = [...new Set(req.body.sources.map((s: any) => s.type))];
-
- // Build search query with category filters
- const { query: searchQuery, categoryMap } = buildSearchQuery(
- req.body.query,
- req.body.categories as CategoryOption[],
- );
-
- const searchResponse = (await search({
- query: searchQuery,
- logger,
- advanced: false,
- num_results: num_results_buffer,
- tbs: req.body.tbs,
- filter: req.body.filter,
- lang: req.body.lang,
- country: req.body.country,
- location: req.body.location,
- type: searchTypes,
- enterprise: req.body.enterprise,
- })) as SearchV2Response;
-
- // Add category labels to web results
- if (searchResponse.web && searchResponse.web.length > 0) {
- searchResponse.web = searchResponse.web.map(result => ({
- ...result,
- category: getCategoryFromUrl(result.url, categoryMap),
- }));
- }
-
- // Add category labels to news results
- if (searchResponse.news && searchResponse.news.length > 0) {
- searchResponse.news = searchResponse.news.map(result => ({
- ...result,
- category: result.url
- ? getCategoryFromUrl(result.url, categoryMap)
- : undefined,
- }));
- }
-
- // Apply limit to each result type separately
- let totalResultsCount = 0;
-
- // Apply limit to web results
- if (searchResponse.web && searchResponse.web.length > 0) {
- if (searchResponse.web.length > limit) {
- searchResponse.web = searchResponse.web.slice(0, limit);
- }
- totalResultsCount += searchResponse.web.length;
- }
-
- // Apply limit to images
- if (searchResponse.images && searchResponse.images.length > 0) {
- if (searchResponse.images.length > limit) {
- searchResponse.images = searchResponse.images.slice(0, limit);
- }
- totalResultsCount += searchResponse.images.length;
- }
-
- // Apply limit to news
- if (searchResponse.news && searchResponse.news.length > 0) {
- if (searchResponse.news.length > limit) {
- searchResponse.news = searchResponse.news.slice(0, limit);
- }
- totalResultsCount += searchResponse.news.length;
- }
-
- // Check if scraping is requested
- const shouldScrape =
- req.body.scrapeOptions?.formats &&
- req.body.scrapeOptions.formats.length > 0;
- const isAsyncScraping = req.body.asyncScraping && shouldScrape;
-
- if (!shouldScrape) {
- const creditsPerTenResults = isZDR ? 10 : 2;
- credits_billed = Math.ceil(totalResultsCount / 10) * creditsPerTenResults;
- } else {
- // Common setup for both async and sync scraping
- logger.info(
- `Starting ${isAsyncScraping ? "async" : "sync"} search scraping`,
- );
-
- // Safely extract scrapeOptions with runtime check
- if (!req.body.scrapeOptions) {
- logger.error(
- "scrapeOptions is undefined despite shouldScrape being true",
- );
- return res.status(500).json({
- success: false,
- error: "Internal server error: scrapeOptions is missing",
- });
- }
-
- const bodyScrapeOptions = req.body.scrapeOptions;
-
- // Create common options
- const scrapeOptions = {
+ const result = await executeSearch(
+ {
+ query: req.body.query,
+ limit: req.body.limit,
+ tbs: req.body.tbs,
+ filter: req.body.filter,
+ lang: req.body.lang,
+ country: req.body.country,
+ location: req.body.location,
+ sources: req.body.sources as Array<{ type: string }>,
+ categories: req.body.categories as CategoryOption[],
+ enterprise: req.body.enterprise,
+ scrapeOptions: req.body.scrapeOptions,
+ timeout: req.body.timeout,
+ },
+ {
teamId: req.auth.team_id,
origin: req.body.origin,
- timeout: req.body.timeout,
- scrapeOptions: bodyScrapeOptions,
- bypassBilling: !shouldBill, // Scrape jobs always bill themselves
apiKeyId: req.acuc?.api_key_id ?? null,
- zeroDataRetention: isZDROrAnon,
+ flags: req.acuc?.flags ?? null,
requestId: agentRequestId ?? jobId,
- };
-
- const directToBullMQ = (req.acuc?.price_credits ?? 0) <= 3000;
-
- // Prepare all items to scrape with their original data
- const itemsToScrape: Array<{
- item: any;
- type: "web" | "news" | "image";
- scrapeInput: ScrapeJobInput;
- }> = [];
-
- // Add web results (skip blocked URLs)
- if (searchResponse.web) {
- searchResponse.web.forEach(item => {
- if (!isUrlBlocked(item.url, req.acuc?.flags ?? null)) {
- itemsToScrape.push({
- item,
- type: "web",
- scrapeInput: {
- url: item.url,
- title: item.title,
- description: item.description,
- },
- });
- } else {
- logger.info(`Skipping blocked URL: ${item.url}`);
- }
- });
- }
-
- // Add news results (only those with URLs and not blocked)
- if (searchResponse.news) {
- searchResponse.news
- .filter(item => item.url)
- .forEach(item => {
- if (!isUrlBlocked(item.url!, req.acuc?.flags ?? null)) {
- itemsToScrape.push({
- item,
- type: "news",
- scrapeInput: {
- url: item.url!,
- title: item.title || "",
- description: item.snippet || "",
- },
- });
- } else {
- logger.info(`Skipping blocked URL: ${item.url}`);
- }
- });
- }
-
- // Add image results (only those with URLs and not blocked)
- if (searchResponse.images) {
- searchResponse.images
- .filter(item => item.url)
- .forEach(item => {
- if (!isUrlBlocked(item.url!, req.acuc?.flags ?? null)) {
- itemsToScrape.push({
- item,
- type: "image",
- scrapeInput: {
- url: item.url!,
- title: item.title || "",
- description: "",
- },
- });
- } else {
- logger.info(`Skipping blocked URL: ${item.url}`);
- }
- });
- }
-
- // Create all promises based on mode (async vs sync)
- const allPromises = itemsToScrape.map(({ scrapeInput }) =>
- isAsyncScraping
- ? startScrapeJob(
- scrapeInput,
- scrapeOptions,
- logger,
- req.acuc?.flags ?? null,
- directToBullMQ,
- isSearchPreview,
- )
- : scrapeSearchResult(
- scrapeInput,
- scrapeOptions,
- logger,
- req.acuc?.flags ?? null,
- directToBullMQ,
- isSearchPreview,
- ),
- );
-
- // Execute all operations in parallel
- const results = await Promise.all(allPromises);
-
- if (isAsyncScraping) {
- // Async mode: organize job IDs and return immediately
- const allJobIds = results as string[];
- const scrapeIds: {
- web?: string[];
- news?: string[];
- images?: string[];
- } = {};
-
- // Organize job IDs by type
- const webItems = itemsToScrape.filter(i => i.type === "web");
- const newsItems = itemsToScrape.filter(i => i.type === "news");
- const imageItems = itemsToScrape.filter(i => i.type === "image");
-
- let currentIndex = 0;
-
- if (webItems.length > 0) {
- scrapeIds.web = allJobIds.slice(
- currentIndex,
- currentIndex + webItems.length,
- );
- currentIndex += webItems.length;
- }
-
- if (newsItems.length > 0) {
- scrapeIds.news = allJobIds.slice(
- currentIndex,
- currentIndex + newsItems.length,
- );
- currentIndex += newsItems.length;
- }
-
- if (imageItems.length > 0) {
- scrapeIds.images = allJobIds.slice(
- currentIndex,
- currentIndex + imageItems.length,
- );
- }
-
- const creditsPerTenResults = isZDR ? 10 : 2;
- credits_billed =
- Math.ceil(totalResultsCount / 10) * creditsPerTenResults;
-
- // Bill for search results now (scrape jobs will bill themselves when they complete)
- if (!isSearchPreview) {
- billTeam(
- req.auth.team_id,
- req.acuc?.sub_id ?? undefined,
- credits_billed,
- req.acuc?.api_key_id ?? null,
- ).catch(error => {
- logger.error(
- `Failed to bill team ${req.acuc?.sub_id} for ${credits_billed} credits: ${error}`,
- );
- });
- }
-
- const endTime = new Date().getTime();
- const timeTakenInSeconds = (endTime - middlewareStartTime) / 1000;
-
- logger.info("Logging job (async scraping)", {
- num_docs: credits_billed,
- time_taken: timeTakenInSeconds,
- scrapeIds,
- });
-
- logSearch(
- {
- id: jobId,
- request_id: jobId,
- query: req.body.query,
- is_successful: true,
- error: undefined,
- results: searchResponse as any,
- num_results: totalResultsCount,
- time_taken: timeTakenInSeconds,
- team_id: req.auth.team_id,
- options: req.body,
- credits_cost: credits_billed,
- zeroDataRetention: isZDROrAnon ?? false,
- },
- false,
- );
-
- // Log final timing information for async mode
- const totalRequestTime = new Date().getTime() - middlewareStartTime;
- const controllerTime = new Date().getTime() - controllerStartTime;
- logger.info("Search completed successfully (async)", {
- version: "v2",
- jobId,
- middlewareStartTime,
- controllerStartTime,
- middlewareTime,
- controllerTime,
- totalRequestTime,
- creditsUsed: credits_billed,
- scrapeful: shouldScrape,
- });
-
- return res.status(200).json({
- success: true,
- data: searchResponse,
- scrapeIds,
- creditsUsed: credits_billed,
- id: jobId,
- });
- } else {
- // Sync mode: process scraped documents
- const allDocsWithCostTracking = results as DocumentWithCostTracking[];
- const scrapedResponse: SearchV2Response = {};
-
- // Create a map of results indexed by URL for easy lookup
- const resultsMap = new Map();
- itemsToScrape.forEach((item, index) => {
- resultsMap.set(
- item.scrapeInput.url,
- allDocsWithCostTracking[index].document,
- );
- });
-
- // Process web results - preserve all original fields and add scraped content
- if (searchResponse.web && searchResponse.web.length > 0) {
- scrapedResponse.web = searchResponse.web.map(item => {
- const doc = resultsMap.get(item.url);
- return {
- ...item, // Preserve ALL original fields
- ...doc, // Override/add scraped content
- };
- });
- }
-
- // Process news results - preserve all original fields and add scraped content
- if (searchResponse.news && searchResponse.news.length > 0) {
- scrapedResponse.news = searchResponse.news.map(item => {
- const doc = item.url ? resultsMap.get(item.url) : undefined;
- return {
- ...item, // Preserve ALL original fields
- ...doc, // Override/add scraped content
- };
- });
- }
-
- // Process image results - preserve all original fields and add scraped content
- if (searchResponse.images && searchResponse.images.length > 0) {
- scrapedResponse.images = searchResponse.images.map(item => {
- const doc = item.url ? resultsMap.get(item.url) : undefined;
- return {
- ...item, // Preserve ALL original fields
- ...doc, // Override/add scraped content
- };
- });
- }
-
- // Calculate search credits only - scrape jobs bill themselves
- const creditsPerTenResults = isZDR ? 10 : 2;
- credits_billed =
- Math.ceil(totalResultsCount / 10) * creditsPerTenResults;
-
- // Update response with scraped data
- Object.assign(searchResponse, scrapedResponse);
- }
- }
+ bypassBilling: !shouldBill,
+ zeroDataRetention: isZDROrAnon,
+ },
+ logger,
+ );
- // Bill team for search credits only
- // - Scrape jobs always handle their own billing (both sync and async)
- // - Search job only bills for search costs (credits per 10 results)
- if (
- !isSearchPreview &&
- (!shouldScrape || (shouldScrape && !isAsyncScraping))
- ) {
+ // Bill team for search credits only (scrape jobs bill themselves)
+ if (!isSearchPreview && shouldBill) {
billTeam(
req.auth.team_id,
req.acuc?.sub_id ?? undefined,
- credits_billed,
+ result.searchCredits,
req.acuc?.api_key_id ?? null,
- ).catch(error => {
+ ).catch(error =>
logger.error(
- `Failed to bill team ${req.acuc?.sub_id} for ${credits_billed} credits: ${error}`,
- );
- });
+ `Failed to bill team ${req.acuc?.sub_id} for ${result.searchCredits} credits: ${error}`,
+ ),
+ );
}
const endTime = new Date().getTime();
const timeTakenInSeconds = (endTime - middlewareStartTime) / 1000;
- logger.info("Logging job", {
- num_docs: credits_billed,
- time_taken: timeTakenInSeconds,
- });
-
logSearch(
{
id: jobId,
@@ -701,18 +150,17 @@ export async function searchController(
query: req.body.query,
is_successful: true,
error: undefined,
- results: searchResponse as any,
- num_results: totalResultsCount,
+ results: result.response as any,
+ num_results: result.totalResultsCount,
time_taken: timeTakenInSeconds,
team_id: req.auth.team_id,
options: req.body,
- credits_cost: shouldBill ? credits_billed : 0,
- zeroDataRetention: isZDROrAnon ?? false, // not supported
+ credits_cost: shouldBill ? result.searchCredits : 0,
+ zeroDataRetention: isZDROrAnon ?? false,
},
false,
);
- // Log final timing information
const totalRequestTime = new Date().getTime() - middlewareStartTime;
const controllerTime = new Date().getTime() - controllerStartTime;
@@ -725,15 +173,16 @@ export async function searchController(
middlewareTime,
controllerTime,
totalRequestTime,
- creditsUsed: credits_billed,
- scrapeful: shouldScrape,
+ searchCredits: result.searchCredits,
+ scrapeCredits: result.scrapeCredits,
+ totalCredits: result.totalCredits,
+ scrapeful: result.shouldScrape,
});
- // For sync scraping or no scraping, don't include scrapeIds
return res.status(200).json({
success: true,
- data: searchResponse,
- creditsUsed: credits_billed,
+ data: result.response,
+ creditsUsed: result.totalCredits,
id: jobId,
});
} catch (error) {
diff --git a/apps/api/src/controllers/v2/types.ts b/apps/api/src/controllers/v2/types.ts
index b0280bd81b..5f461da215 100644
--- a/apps/api/src/controllers/v2/types.ts
+++ b/apps/api/src/controllers/v2/types.ts
@@ -21,7 +21,10 @@ import { ErrorCodes } from "../../lib/error";
import Ajv from "ajv";
import addFormats from "ajv-formats";
import { integrationSchema } from "../../utils/integration";
-import { webhookSchema } from "../../services/webhook/schema";
+import {
+ webhookSchema,
+ createWebhookSchema,
+} from "../../services/webhook/schema";
import { BrandingProfile } from "../../types/branding";
// Base URL schema with common validation logic
@@ -68,7 +71,7 @@ export const URL = z.preprocess(
return false;
}
}, "Invalid URL"),
- // .refine((x) => !isUrlBlocked(x as string), BLOCKLISTED_URL_MESSAGE),
+ // .refine((x) => !isUrlBlocked(x as string), UNSUPPORTED_SITE_MESSAGE),
);
const strictMessage =
@@ -410,8 +413,13 @@ export type FormatObject =
| AttributesFormatWithOptions
| { type: "branding" };
+const pdfModeSchema = z.enum(["fast", "auto", "ocr"]);
+
+export type PDFMode = z.infer;
+
const pdfParserWithOptions = z.strictObject({
type: z.literal("pdf"),
+ mode: pdfModeSchema.optional(),
maxPages: z.int().positive().finite().max(10000).optional(),
});
@@ -446,6 +454,17 @@ export function getPDFMaxPages(parsers?: Parsers): number | undefined {
return undefined;
}
+export function getPDFMode(parsers?: Parsers): PDFMode {
+ if (!parsers) return "auto";
+ for (const parser of parsers) {
+ if (parser === "pdf") return "auto";
+ if (typeof parser === "object" && parser.type === "pdf") {
+ return parser.mode ?? "auto";
+ }
+ }
+ return "auto";
+}
+
function transformIframeSelector(selector: string): string {
return selector.replace(/(?:^|[\s,])iframe(?=\s|$|[.#\[:,])/g, match => {
const prefix = match.match(/^[\s,]/)?.[0] || "";
@@ -525,8 +544,9 @@ const baseScrapeOptions = z.strictObject({
.transform(tags => tags.map(transformIframeSelector))
.optional(),
onlyMainContent: z.boolean().prefault(true),
- timeout: z.int().positive().finite().optional(),
- waitFor: z.int().nonnegative().finite().max(60000).prefault(0),
+ onlyCleanContent: z.boolean().prefault(false),
+ timeout: z.int().positive().min(1000).optional(),
+ waitFor: z.int().nonnegative().max(60000).prefault(0),
mobile: z.boolean().prefault(false),
parsers: parsersSchema.optional(),
actions: actionsSchema.optional(),
@@ -538,7 +558,7 @@ const baseScrapeOptions = z.strictObject({
fastMode: z.boolean().prefault(false),
useMock: z.string().optional(),
blockAds: z.boolean().prefault(true),
- proxy: z.enum(["basic", "stealth", "auto"]).prefault("auto"),
+ proxy: z.enum(["basic", "stealth", "enhanced", "auto"]).prefault("auto"),
maxAge: z.int().gte(0).optional(),
minAge: z.int().gte(0).optional(),
storeInCache: z.boolean().prefault(true),
@@ -593,7 +613,9 @@ const extractTransformImpl = (
}
if (
- (obj.proxy === "stealth" || obj.proxy === "auto") &&
+ (obj.proxy === "stealth" ||
+ obj.proxy === "enhanced" ||
+ obj.proxy === "auto") &&
obj.timeout === 30000
) {
result = { ...result, timeout: 120000 };
@@ -676,12 +698,13 @@ const extractOptions = z
origin: z.string().optional().prefault("api"),
integration: integrationSchema.optional().transform(val => val || null),
urlTrace: z.boolean().prefault(false),
- timeout: z.int().positive().finite().optional(),
+ timeout: z.int().positive().min(1000).optional(),
agent: agentOptionsExtract.optional(),
__experimental_streamSteps: z.boolean().prefault(false),
__experimental_llmUsage: z.boolean().prefault(false),
__experimental_showSources: z.boolean().prefault(false),
showSources: z.boolean().prefault(false),
+ // These two below don't do anything anymore
__experimental_cacheKey: z.string().optional(),
__experimental_cacheMode: z
.enum(["direct", "save", "load"])
@@ -711,6 +734,14 @@ export const extractRequestSchema = extractOptions;
export type ExtractRequest = z.infer;
export type ExtractRequestInput = z.input;
+const agentWebhookSchema = createWebhookSchema([
+ "started",
+ "action",
+ "completed",
+ "failed",
+ "cancelled",
+]);
+
export const agentRequestSchema = z.strictObject({
urls: URL.array().optional(),
prompt: z.string().max(10000),
@@ -738,8 +769,10 @@ export const agentRequestSchema = z.strictObject({
integration: integrationSchema.optional().transform(val => val || null),
maxCredits: z.number().optional(),
strictConstrainToURLs: z.boolean().optional(),
+ webhook: agentWebhookSchema.optional(),
overrideWhitelist: z.string().optional(),
+ model: z.enum(["spark-1-pro", "spark-1-mini"]).default("spark-1-pro"),
});
export type AgentRequest = z.infer;
@@ -755,6 +788,7 @@ const scrapeRequestSchemaBase = baseScrapeOptions.extend({
auth: z.string(),
requestId: z.string(),
shouldBill: z.boolean(),
+ boostConcurrency: z.boolean().optional(),
})
.optional(),
});
@@ -855,7 +889,7 @@ export const crawlerOptions = z.strictObject({
allowExternalLinks: z.boolean().prefault(false),
allowSubdomains: z.boolean().prefault(false),
ignoreRobotsTxt: z.boolean().prefault(false),
- sitemap: z.enum(["skip", "include"]).prefault("include"),
+ sitemap: z.enum(["skip", "include", "only"]).prefault("include"),
deduplicateSimilarURLs: z.boolean().prefault(true),
ignoreQueryParameters: z.boolean().prefault(false),
regexOnFullURL: z.boolean().prefault(false),
@@ -929,6 +963,7 @@ const mapRequestSchemaBase = crawlerOptions
useMock: z.string().optional(),
filterByPath: z.boolean().prefault(true),
useIndex: z.boolean().prefault(true),
+ ignoreCache: z.boolean().prefault(false),
location: locationSchema,
headers: z.record(z.string(), z.string()).optional(),
});
@@ -1119,6 +1154,7 @@ export type AgentStatusResponse =
status: "processing" | "completed" | "failed";
error?: string;
data?: any;
+ model?: "spark-1-pro" | "spark-1-mini";
expiresAt: string;
creditsUsed?: number;
};
@@ -1233,10 +1269,10 @@ export type TeamFlags = {
allowZDR?: boolean;
zdrCost?: number;
checkRobotsOnScrape?: boolean;
- allowTeammateInvites?: boolean;
crawlTtlHours?: number;
ipWhitelist?: boolean;
bypassCreditChecks?: boolean;
+ debugBranding?: boolean;
} | null;
interface RequestWithMaybeACUC<
@@ -1269,6 +1305,7 @@ export function toV0CrawlerOptions(x: CrawlerOptions) {
allowSubdomains: x.allowSubdomains,
ignoreRobotsTxt: x.ignoreRobotsTxt,
ignoreSitemap: x.sitemap === "skip",
+ sitemapOnly: x.sitemap === "only",
deduplicateSimilarURLs: x.deduplicateSimilarURLs,
ignoreQueryParameters: x.ignoreQueryParameters,
regexOnFullURL: x.regexOnFullURL,
@@ -1287,7 +1324,7 @@ export function toV2CrawlerOptions(x: any): CrawlerOptions {
allowExternalLinks: x.allowExternalContentLinks,
allowSubdomains: x.allowSubdomains,
ignoreRobotsTxt: x.ignoreRobotsTxt,
- sitemap: x.ignoreSitemap ? "skip" : "include",
+ sitemap: x.sitemapOnly ? "only" : x.ignoreSitemap ? "skip" : "include",
deduplicateSimilarURLs: x.deduplicateSimilarURLs,
ignoreQueryParameters: x.ignoreQueryParameters,
regexOnFullURL: x.regexOnFullURL,
@@ -1312,7 +1349,7 @@ function fromV0CrawlerOptions(
allowExternalLinks: x.allowExternalContentLinks,
allowSubdomains: x.allowSubdomains,
ignoreRobotsTxt: x.ignoreRobotsTxt,
- sitemap: x.ignoreSitemap ? "skip" : "include",
+ sitemap: x.sitemapOnly ? "only" : x.ignoreSitemap ? "skip" : "include",
deduplicateSimilarURLs: x.deduplicateSimilarURLs,
ignoreQueryParameters: x.ignoreQueryParameters,
regexOnFullURL: x.regexOnFullURL,
diff --git a/apps/api/src/harness.ts b/apps/api/src/harness.ts
index 71dda37946..1deef110ac 100644
--- a/apps/api/src/harness.ts
+++ b/apps/api/src/harness.ts
@@ -34,6 +34,7 @@ interface Services {
worker?: ProcessResult;
nuqWorkers: ProcessResult[];
nuqPrefetchWorker?: ProcessResult;
+ nuqReconcilerWorker?: ProcessResult;
extractWorker?: ProcessResult;
indexWorker?: ProcessResult;
command?: ProcessResult;
@@ -101,6 +102,7 @@ const EXTRACT_WORKER_PORT = config.EXTRACT_WORKER_PORT;
const NUQ_WORKER_START_PORT = config.NUQ_WORKER_START_PORT;
const NUQ_WORKER_COUNT = config.NUQ_WORKER_COUNT;
const NUQ_PREFETCH_WORKER_PORT = NUQ_WORKER_START_PORT + NUQ_WORKER_COUNT;
+const NUQ_RECONCILER_WORKER_PORT = NUQ_PREFETCH_WORKER_PORT + 1;
// PostgreSQL credentials (with defaults for backward compatibility)
const POSTGRES_USER = config.POSTGRES_USER;
@@ -779,6 +781,18 @@ async function startServices(command?: string[]): Promise {
},
);
+ const nuqReconcilerWorker = execForward(
+ "nuq-reconciler",
+ process.argv[2] === "--start-docker"
+ ? "node dist/src/services/worker/nuq-reconciler-worker.js"
+ : "pnpm nuq-reconciler-worker:production",
+ {
+ NUQ_RECONCILER_WORKER_PORT: String(NUQ_RECONCILER_WORKER_PORT),
+ NUQ_REDUCE_NOISE: "true",
+ NUQ_POD_NAME: "nuq-reconciler-worker-0",
+ },
+ );
+
const indexWorker = config.USE_DB_AUTHENTICATION
? execForward(
"index-worker",
@@ -813,6 +827,7 @@ async function startServices(command?: string[]): Promise {
worker,
nuqWorkers,
nuqPrefetchWorker,
+ nuqReconcilerWorker,
indexWorker,
extractWorker,
command: commandProcess,
@@ -829,6 +844,7 @@ async function stopDevelopmentServices(services: Services) {
services.worker?.process,
...services.nuqWorkers.map(w => w.process),
services.nuqPrefetchWorker?.process,
+ services.nuqReconcilerWorker?.process,
services.indexWorker?.process,
services.extractWorker?.process,
services.command?.process,
@@ -992,6 +1008,8 @@ async function waitForTermination(services: Services): Promise {
if (services.extractWorker) promises.push(services.extractWorker.promise);
if (services.nuqPrefetchWorker)
promises.push(services.nuqPrefetchWorker.promise);
+ if (services.nuqReconcilerWorker)
+ promises.push(services.nuqReconcilerWorker.promise);
promises.push(...services.nuqWorkers.map(w => w.promise));
diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts
index 57450a5a52..e2ac0b8235 100644
--- a/apps/api/src/index.ts
+++ b/apps/api/src/index.ts
@@ -26,17 +26,18 @@ import {
ResponseWithSentry,
} from "./controllers/v1/types";
import { ZodError } from "zod";
+import { QueueFullError } from "./lib/concurrency-limit";
import { v7 as uuidv7 } from "uuid";
import { attachWsProxy } from "./services/agentLivecastWS";
import { cacheableLookup } from "./scraper/scrapeURL/lib/cacheableLookup";
import { v2Router } from "./routes/v2";
-import domainFrequencyRouter from "./routes/domain-frequency";
import { nuqShutdown } from "./services/worker/nuq";
import { getErrorContactMessage } from "./lib/deployment";
import { initializeBlocklist } from "./scraper/WebScraper/utils/blocklist";
import { initializeEngineForcing } from "./scraper/WebScraper/utils/engine-forcing";
import responseTime from "response-time";
import { shutdownWebhookQueue } from "./services/webhook";
+import { shutdownIndexerQueue } from "./services/indexing/indexer-queue";
const { createBullBoard } = require("@bull-board/api");
const { BullMQAdapter } = require("@bull-board/api/bullMQAdapter");
@@ -106,7 +107,6 @@ app.use(v0Router);
app.use("/v1", v1Router);
app.use("/v2", v2Router);
app.use(adminRouter);
-app.use(domainFrequencyRouter);
const DEFAULT_PORT = config.PORT;
const HOST = config.HOST;
@@ -140,8 +140,10 @@ async function startServer(port = DEFAULT_PORT) {
logger.info("Server closed.");
nuqShutdown().finally(() => {
shutdownWebhookQueue().finally(() => {
- logger.info("NUQ shutdown complete");
- process.exit(0);
+ shutdownIndexerQueue().finally(() => {
+ logger.info("NUQ shutdown complete");
+ process.exit(0);
+ });
});
});
});
@@ -172,7 +174,12 @@ app.use(
res: Response,
next: NextFunction,
) => {
- if (err instanceof ZodError) {
+ if (err instanceof QueueFullError) {
+ res.status(429).json({
+ success: false,
+ error: err.message,
+ });
+ } else if (err instanceof ZodError) {
// In zod v4, ZodError uses 'issues' instead of 'errors'
const issues = err.issues;
diff --git a/apps/api/src/lib/__tests__/html-transformer.test.ts b/apps/api/src/lib/__tests__/html-transformer.test.ts
index 8e93e3f82f..cee16f0156 100644
--- a/apps/api/src/lib/__tests__/html-transformer.test.ts
+++ b/apps/api/src/lib/__tests__/html-transformer.test.ts
@@ -261,6 +261,51 @@ describe("HTML Transformer", () => {
const metadata = await extractMetadata(html);
expect(metadata).toBeDefined();
});
+
+ it("should backfill title from og:title when title tag is missing", async () => {
+ const html = `
+
+
+
+
+
+
+
+ `;
+ const metadata = await extractMetadata(html);
+ expect(metadata.title).toBe("OpenGraph Title");
+ expect(metadata.ogTitle).toBe("OpenGraph Title");
+ });
+
+ it("should backfill title from twitter:title when title and og:title are missing", async () => {
+ const html = `
+
+
+
+
+
+
+
+ `;
+ const metadata = await extractMetadata(html);
+ expect(metadata.title).toBe("Twitter Title");
+ });
+
+ it("should not backfill title when title tag exists", async () => {
+ const html = `
+
+
+ Primary Title
+
+
+
+
+
+ `;
+ const metadata = await extractMetadata(html);
+ expect(metadata.title).toBe("Primary Title");
+ expect(metadata.ogTitle).toBe("OpenGraph Title");
+ });
});
describe("transformHtml", () => {
diff --git a/apps/api/src/lib/branding/extractHeaderHtmlChunk.ts b/apps/api/src/lib/branding/extractHeaderHtmlChunk.ts
new file mode 100644
index 0000000000..132b03fbce
--- /dev/null
+++ b/apps/api/src/lib/branding/extractHeaderHtmlChunk.ts
@@ -0,0 +1,50 @@
+/**
+ * Extract a small chunk of HTML from the top/header area for LLM context when
+ * no logo candidates were found. Helps the LLM infer brand name and note that
+ * a logo may exist but wasn't captured (e.g. inline SVG, shadow DOM).
+ *
+ * Strategy: strip noise, find header/nav/body start, take first N chars.
+ */
+
+const MAX_HEADER_CHUNK_CHARS = 5500;
+
+/**
+ * Remove script and style tags and their content, and HTML comments.
+ * Uses regex; safe for typical page header content.
+ */
+function stripNoise(html: string): string {
+ let out = html;
+ // Comments
+ out = out.replace(//g, "");
+ // Scripts (non-greedy to first )
+ out = out.replace(/