diff --git a/.dockerignore b/.dockerignore
index 5b57b57f..04c4f9dc 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,35 +1,46 @@
-.devenv*
-.direnv
-.devcontainer
.git
.github
.husky
.vscode
+.idea
+.devcontainer
.envrc
-devenv.yaml
-devenv.nix
-.prettierrc.js
-.prettierignore
-.editorconfig
-.npmrc
-.firebaserc
+.devenv*
+.direnv
+devenv.local.nix
node_modules
**/node_modules
-**/*/node_modules
+.pnpm-store
**/dist
**/build
**/target
+**/coverage
+**/.cache
+**/.parcel-cache
+**/.svelte-kit
+**/.nuxt
**/__tests__
**/*.test.*
-**/coverage
+**/*.spec.*
+tests/*/screenshots
+tests/*/videos
+docs
*.md
+!README.md
LICENSE
CODEOWNERS
-.DS_Store
+.firebase
+.firebaserc
+firebase.json
+firestore.indexes.json
+firestore.rules
+netlify.toml
+
*.log
+.DS_Store
diff --git a/.firebaserc b/.firebaserc
deleted file mode 100644
index feafd4b5..00000000
--- a/.firebaserc
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "projects": {
- "default": "postwoman-api"
- }
-}
diff --git a/CODEOWNERS b/CODEOWNERS
deleted file mode 100644
index 5c837665..00000000
--- a/CODEOWNERS
+++ /dev/null
@@ -1,21 +0,0 @@
-# CODEOWNERS is prioritized from bottom to top
-
-# Packages
-/packages/codemirror-lang-graphql/ @AndrewBastin
-/packages/hoppscotch-cli/ @jamesgeorge007
-/packages/hoppscotch-data/ @AndrewBastin
-/packages/hoppscotch-js-sandbox/ @jamesgeorge007
-/packages/hoppscotch-selfhost-web/ @jamesgeorge007
-/packages/hoppscotch-selfhost-desktop/ @AndrewBastin
-/packages/hoppscotch-sh-admin/ @JoelJacobStephen
-/packages/hoppscotch-backend/ @balub
-
-# READMEs and other documentation files
-*.md @liyasthomas
-
-# Self Host deployment related files
-*.Dockerfile @balub
-docker-compose.yml @balub
-docker-compose.deploy.yml @balub
-*.Caddyfile @balub
-.dockerignore @balub
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
deleted file mode 100644
index 5a23ef52..00000000
--- a/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,132 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-We as members, contributors, and leaders pledge to make participation in our
-community a harassment-free experience for everyone, regardless of age, body
-size, visible or invisible disability, ethnicity, sex characteristics, gender
-identity and expression, level of experience, education, socio-economic status,
-nationality, personal appearance, race, caste, color, religion, or sexual
-identity and orientation.
-
-We pledge to act and interact in ways that contribute to an open, welcoming,
-diverse, inclusive, and healthy community.
-
-## Our Standards
-
-Examples of behavior that contributes to a positive environment for our
-community include:
-
-* Demonstrating empathy and kindness toward other people
-* Being respectful of differing opinions, viewpoints, and experiences
-* Giving and gracefully accepting constructive feedback
-* Accepting responsibility and apologizing to those affected by our mistakes,
- and learning from the experience
-* Focusing on what is best not just for us as individuals, but for the overall
- community
-
-Examples of unacceptable behavior include:
-
-* The use of sexualized language or imagery, and sexual attention or advances of
- any kind
-* Trolling, insulting or derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or email address,
- without their explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
- professional setting
-
-## Enforcement Responsibilities
-
-Community leaders are responsible for clarifying and enforcing our standards of
-acceptable behavior and will take appropriate and fair corrective action in
-response to any behavior that they deem inappropriate, threatening, offensive,
-or harmful.
-
-Community leaders have the right and responsibility to remove, edit, or reject
-comments, commits, code, wiki edits, issues, and other contributions that are
-not aligned to this Code of Conduct, and will communicate reasons for moderation
-decisions when appropriate.
-
-## Scope
-
-This Code of Conduct applies within all community spaces, and also applies when
-an individual is officially representing the community in public spaces.
-Examples of representing our community include using an official e-mail address,
-posting via an official social media account, or acting as an appointed
-representative at an online or offline event.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported to the community leaders responsible for enforcement at
-support@hoppscotch.io.
-All complaints will be reviewed and investigated promptly and fairly.
-
-All community leaders are obligated to respect the privacy and security of the
-reporter of any incident.
-
-## Enforcement Guidelines
-
-Community leaders will follow these Community Impact Guidelines in determining
-the consequences for any action they deem in violation of this Code of Conduct:
-
-### 1. Correction
-
-**Community Impact**: Use of inappropriate language or other behavior deemed
-unprofessional or unwelcome in the community.
-
-**Consequence**: A private, written warning from community leaders, providing
-clarity around the nature of the violation and an explanation of why the
-behavior was inappropriate. A public apology may be requested.
-
-### 2. Warning
-
-**Community Impact**: A violation through a single incident or series of
-actions.
-
-**Consequence**: A warning with consequences for continued behavior. No
-interaction with the people involved, including unsolicited interaction with
-those enforcing the Code of Conduct, for a specified period of time. This
-includes avoiding interactions in community spaces as well as external channels
-like social media. Violating these terms may lead to a temporary or permanent
-ban.
-
-### 3. Temporary Ban
-
-**Community Impact**: A serious violation of community standards, including
-sustained inappropriate behavior.
-
-**Consequence**: A temporary ban from any sort of interaction or public
-communication with the community for a specified period of time. No public or
-private interaction with the people involved, including unsolicited interaction
-with those enforcing the Code of Conduct, is allowed during this period.
-Violating these terms may lead to a permanent ban.
-
-### 4. Permanent Ban
-
-**Community Impact**: Demonstrating a pattern of violation of community
-standards, including sustained inappropriate behavior, harassment of an
-individual, or aggression toward or disparagement of classes of individuals.
-
-**Consequence**: A permanent ban from any sort of public interaction within the
-community.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage],
-version 2.1, available at
-[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
-
-Community Impact Guidelines were inspired by
-[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
-
-For answers to common questions about this code of conduct, see the FAQ at
-[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
-[https://www.contributor-covenant.org/translations][translations].
-
-[homepage]: https://www.contributor-covenant.org
-[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
-[Mozilla CoC]: https://github.com/mozilla/diversity
-[FAQ]: https://www.contributor-covenant.org/faq
-[translations]: https://www.contributor-covenant.org/translations
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index ce37ce4b..00000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Contributing
-
-When contributing to this repository, please first discuss the change you wish to make via issue,
-email, or any other method with the owners of this repository before making a change.
-
-Please note we have a code of conduct, please follow it in all your interactions with the project.
-
-## Pull Request Process
-
-1. Ensure any install or build dependencies are removed before the end of the layer when doing a
- build.
-2. Update the README.md with details of changes to the interface, this includes new environment
- variables, exposed ports, useful file locations and container parameters.
-3. Make sure you do not expose environment variables or other sensitive information in your PR.
diff --git a/Makefile b/Makefile
index c2bde3e4..2680aadc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,21 +1,20 @@
COMPOSE := docker compose
-PROFILE := default
ENV_FILE := .env
ENV_EXAMPLE := .env.example
.PHONY: up down logs ps ensure-env
up: ensure-env
- $(COMPOSE) --profile $(PROFILE) up -d --build
+ $(COMPOSE) up -d --build
down:
- $(COMPOSE) --profile $(PROFILE) down
+ $(COMPOSE) down
logs:
- $(COMPOSE) --profile $(PROFILE) logs -f
+ $(COMPOSE) logs -f
ps:
- $(COMPOSE) --profile $(PROFILE) ps
+ $(COMPOSE) ps
ensure-env:
@test -f $(ENV_FILE) || cp $(ENV_EXAMPLE) $(ENV_FILE)
diff --git a/README.md b/README.md
index ffe946ee..17c0e990 100644
--- a/README.md
+++ b/README.md
@@ -1,299 +1,78 @@
-
-
-
-
-
-
- Hoppscotch
-
-
-
- Open Source API Development Ecosystem
-
-
+# Hoppscotch AIO
-[](CODE_OF_CONDUCT.md) [](https://hoppscotch.io) [](https://github.com/hoppscotch/hoppscotch/actions) [](https://x.com/share?text=%F0%9F%91%BD%20Hoppscotch%20%E2%80%A2%20Open%20source%20API%20development%20ecosystem%20-%20Helps%20you%20create%20requests%20faster,%20saving%20precious%20time%20on%20development.&url=https://hoppscotch.io&hashtags=hoppscotch&via=hoppscotch_io)
+Fork interne de Hoppscotch réduit au déploiement self-host all-in-one pour
+Coolify.
-
-
-
- Built with ❤︎ by
-
- contributors
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+## Contenu conservé
-_We highly recommend you take a look at the [**Hoppscotch Documentation**](https://docs.hoppscotch.io) to learn more about the app._
+- Application web self-host : `packages/hoppscotch-selfhost-web`
+- Backend NestJS et Prisma : `packages/hoppscotch-backend`
+- Admin self-host : `packages/hoppscotch-sh-admin`
+- Packages partagés requis au build : `hoppscotch-common`, `hoppscotch-data`,
+ `hoppscotch-kernel`, `hoppscotch-js-sandbox`, `codemirror-lang-graphql`
+- Image Docker de production : `prod.Dockerfile`
+- Déploiement Compose AIO : `docker-compose.yml`
-#### **Support**
+## Déploiement Coolify
-[](https://hoppscotch.io/discord) [](https://hoppscotch.io/telegram) [](https://github.com/hoppscotch/hoppscotch/discussions)
+Utiliser `docker-compose.yml` comme source Compose.
-### **Features**
+Services créés :
-❤️ **Lightweight:** Crafted with minimalistic UI design.
+- `hoppscotch-aio` : image AIO construite depuis `prod.Dockerfile`, target
+ `aio`
+- `hoppscotch-db` : PostgreSQL 15 avec volume persistant
-⚡️ **Fast:** Send requests and get responses in real time.
+Ports exposés :
-🗄️ **HTTP Methods:** Request methods define the type of action you are requesting to be performed.
+- `3080` -> Caddy AIO HTTP
+- `3000` -> app web
+- `3100` -> admin
+- `3170` -> backend
+- `3200` -> serveur de bundles webapp
-- `GET` - Requests retrieve resource information
-- `POST` - The server creates a new entry in a database
-- `PUT` - Updates an existing resource
-- `PATCH` - Very similar to `PUT` but makes a partial update on a resource
-- `DELETE` - Deletes resource or related component
-- `HEAD` - Retrieve response headers identical to those of a GET request, but without the response body.
-- `CONNECT` - Establishes a tunnel to the server identified by the target resource
-- `OPTIONS` - Describe the communication options for the target resource
-- `TRACE` - Performs a message loop-back test along the path to the target resource
-- `` - Some APIs use custom request methods such as `LIST`. Type in your custom methods.
+Variables minimales à vérifier dans Coolify :
-🌈 **Theming:** Customizable combinations for background, foreground, and accent colors — [customize now](https://hoppscotch.io/settings).
+```env
+POSTGRES_PASSWORD=
+POSTGRES_DB=hoppscotch
+DATA_ENCRYPTION_KEY=
+VITE_BASE_URL=https://
+VITE_SHORTCODE_BASE_URL=https://
+VITE_ADMIN_URL=https://
+VITE_BACKEND_GQL_URL=https:///graphql
+VITE_BACKEND_WS_URL=wss:///graphql
+VITE_BACKEND_API_URL=https:///v1
+WHITELISTED_ORIGINS=https://,https://
+TRUST_PROXY=true
+```
-- Choose a theme: System preference, Light, Dark, and Black
-- Choose accent colors: Green, Teal, Blue, Indigo, Purple, Yellow, Orange, Red, and Pink
-- Distraction-free Zen mode
+`DATABASE_URL` est généré par `docker-compose.yml` pour la base PostgreSQL
+incluse. Si le déploiement passe plus tard sur une base externe, adapter
+explicitement le service `hoppscotch-aio`.
-_Customized themes are synced with your cloud/local session._
+## Local
-🔥 **PWA:** Install as a [Progressive Web App](https://web.dev/progressive-web-apps) on your device.
+Créer le fichier `.env` si nécessaire :
-- Instant loading with Service Workers
-- Offline support
-- Low RAM/memory and CPU usage
-- Add to Home Screen
-- Desktop PWA
+```sh
+cp .env.example .env
+```
-🚀 **Request:** Retrieve response from endpoint instantly.
+Démarrer l'AIO local :
-1. Choose `method`
-2. Enter `URL`
-3. Send
+```sh
+docker compose up -d --build
+```
-- Copy/share public "Share URL"
-- Generate/copy request code snippets for 10+ languages and frameworks
-- Import `cURL`
-- Label requests
+Voir les logs :
-🔌 **WebSocket:** Establish full-duplex communication channels over a single TCP connection.
+```sh
+docker compose logs -f
+```
-📡 **Server-Sent Events:** Receive a stream of updates from a server over an HTTP connection without resorting to polling.
+Arrêter :
-🌩 **Socket.IO:** Send and Receive data with the SocketIO server.
-
-🦟 **MQTT:** Subscribe and Publish to topics of an MQTT Broker.
-
-🔮 **GraphQL:** GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.
-
-- Set endpoint and get schema
-- Multi-column docs
-- Set custom request headers
-- Query schema
-- Get query response
-
-🔐 **Authorization:** Allows to identify the end-user.
-
-- None
-- Basic
-- Bearer Token
-- OAuth 2.0
-- OIDC Access Token/PKCE
-
-📢 **Headers:** Describes the format the body of your request is being sent in.
-
-📫 **Parameters:** Use request parameters to set varying parts in simulated requests.
-
-📃 **Request Body:** Used to send and receive data via the REST API.
-
-- Set `Content Type`
-- FormData, JSON, and many more
-- Toggle between key-value and RAW input parameter list
-
-📮 **Response:** Contains the status line, headers, and the message/response body.
-
-- Copy the response to the clipboard
-- Download the response as a file
-- View response headers
-- View raw and preview HTML, image, JSON, and XML responses
-
-⏰ **History:** Request entries are synced with your cloud/local session storage.
-
-📁 **Collections:** Keep your API requests organized with collections and folders. Reuse them with a single click.
-
-- Unlimited collections, folders, and requests
-- Nested folders
-- Export and import as a file or GitHub gist
-
-_Collections are synced with your cloud/local session storage._
-
-📜 **Pre-Request Scripts:** Snippets of code associated with a request that is executed before the request is sent.
-
-- Set environment variables
-- Include timestamp in the request headers
-- Send a random alphanumeric string in the URL parameters
-- Any JavaScript functions
-
-👨👩👧👦 **Teams:** Helps you collaborate across your teams to design, develop, and test APIs faster.
-
-- Create unlimited teams
-- Create unlimited shared collections
-- Create unlimited team members
-- Role-based access control
-- Cloud sync
-- Multiple devices
-
-👥 **Workspaces:** Organize your personal and team collections environments into workspaces. Easily switch between workspaces to manage multiple projects.
-
-- Create unlimited workspaces
-- Switch between personal and team workspaces
-
-⌨️ **Keyboard Shortcuts:** Optimized for efficiency.
-
-> **[Read our documentation on Keyboard Shortcuts](https://docs.hoppscotch.io/documentation/features/shortcuts)**
-
-🌐 **Proxy:** Enable Proxy Mode from Settings to access blocked APIs.
-
-- Hide your IP address
-- Fixes [`CORS`](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) (Cross-Origin Resource Sharing) issues
-- Access APIs served in non-HTTPS (`http://`) endpoints
-- Use your Proxy URL
-
-_Official proxy server is hosted by Hoppscotch - **[GitHub](https://github.com/hoppscotch/proxyscotch)** - **[Privacy Policy](https://docs.hoppscotch.io/support/privacy)**._
-
-🌎 **i18n:** Experience the app in your language.
-
-Help us to translate Hoppscotch. Please read [`TRANSLATIONS`](TRANSLATIONS.md) for details on our [`CODE OF CONDUCT`](CODE_OF_CONDUCT.md) and the process for submitting pull requests to us.
-
-☁️ **Auth + Sync:** Sign in and sync your data in real-time across all your devices.
-
-**Sign in with:**
-
-- GitHub
-- Google
-- Microsoft
-- Email
-- SSO (Single Sign-On)[^EE]
-
-**🔄 Synchronize your data:** Handoff to continue tasks on your other devices.
-
-- Workspaces
-- History
-- Collections
-- Environments
-- Settings
-
-✅ **Post-Request Tests:** Write tests associated with a request that is executed after the request's response.
-
-- Check the status code as an integer
-- Filter response headers
-- Parse the response data
-- Set environment variables
-- Write JavaScript code
-
-🌱 **Environments:** Environment variables allow you to store and reuse values in your requests and scripts.
-
-- Unlimited environments and variables
-- Initialize through the pre-request script
-- Export as / import from GitHub gist
-
-
- Use-cases
-
----
-
-- By storing a value in a variable, you can reference it throughout your request section
-- If you need to update the value, you only have to change it in one place
-- Using variables increases your ability to work efficiently and minimizes the likelihood of error
-
----
-
-
-
-🚚 **Bulk Edit:** Edit key-value pairs in bulk.
-
-- Entries are separated by newline
-- Keys and values are separated by `:`
-- Prepend `#` to any row you want to add but keep disabled
-
-🎛️ **Admin dashboard:** Manage your team and invite members.
-
-- Insights
-- Manage users
-- Manage teams
-
-📦 **Add-ons:** Official add-ons for hoppscotch.
-
-- **[Hoppscotch CLI](https://github.com/hoppscotch/hoppscotch/tree/main/packages/hoppscotch-cli)** - Command-line interface for Hoppscotch.
-- **[Proxy](https://github.com/hoppscotch/proxyscotch)** - A simple proxy server created for Hoppscotch.
-- **[Browser Extensions](https://github.com/hoppscotch/hoppscotch-extension)** - Browser extensions that enhance your Hoppscotch experience.
-
- [ **Firefox**](https://addons.mozilla.org/en-US/firefox/addon/hoppscotch) | [ **Chrome**](https://chrome.google.com/webstore/detail/hoppscotch-extension-for-c/amknoiejhlmhancpahfcfcfhllgkpbld)
-
- > **Extensions fix `CORS` issues.**
-
-_Add-ons are developed and maintained under **[Hoppscotch Organization](https://github.com/hoppscotch)**._
-
-**For a complete list of features, please read our [documentation](https://docs.hoppscotch.io).**
-
-## **Demo**
-
-- Web : [hoppscotch.io](https://hoppscotch.io)
-- Windows/Linux/macOS : [Desktop Apps](https://docs.hoppscotch.io/documentation/clients/desktop#download-hoppscotch-desktop-app)
-
-## Usage
-
-1. Provide your API endpoint in the URL field
-2. Click "Send" to simulate the request
-3. View the response
-
-## Developing
-
-Follow our [self-hosting documentation](https://docs.hoppscotch.io/documentation/self-host/getting-started) to get started with the development environment.
-
-## Contributing
-
-Please contribute using [GitHub Flow](https://guides.github.com/introduction/flow). Create a branch, add commits, and [open a pull request](https://github.com/hoppscotch/hoppscotch/compare).
-
-Please read [`CONTRIBUTING`](CONTRIBUTING.md) for details on our [`CODE OF CONDUCT`](CODE_OF_CONDUCT.md), and the process for submitting pull requests to us.
-
-## Continuous Integration
-
-We use [GitHub Actions](https://github.com/features/actions) for continuous integration. Check out our [build workflows](https://github.com/hoppscotch/hoppscotch/actions).
-
-## Changelog
-
-See the [`CHANGELOG`](CHANGELOG.md) file for details.
-
-## Authors
-
-This project owes its existence to the collective efforts of all those who contribute — [contribute now](CONTRIBUTING.md).
-
-
-
-## License
-
-This project is licensed under the [MIT License](https://opensource.org/licenses/MIT) — see the [`LICENSE`](LICENSE) file for details.
-
-[^EE]: Enterprise edition feature. [Learn more](https://docs.hoppscotch.io/documentation/self-host/getting-started).
+```sh
+docker compose down
+```
diff --git a/SECURITY.md b/SECURITY.md
deleted file mode 100644
index 0ecb916c..00000000
--- a/SECURITY.md
+++ /dev/null
@@ -1,135 +0,0 @@
-# Security Policy
-
-- [Security Policy](#security-policy)
- - [Scope](#scope)
- - [Architecture and threat model](#architecture-and-threat-model)
- - [Desktop app](#desktop-app)
- - [Hoppscotch Agent](#hoppscotch-agent)
- - [Self-hosted instances](#self-hosted-instances)
- - [Security controls](#security-controls)
- - [Reporting a security vulnerability](#reporting-a-security-vulnerability)
- - [What does not qualify as a vulnerability](#what-does-not-qualify-as-a-vulnerability)
-
-## Scope
-
-This policy covers components in the [hoppscotch/hoppscotch](https://github.com/hoppscotch/hoppscotch) repository:
-
-- **Desktop app**: the Tauri-based desktop client, including standalone use and connections to self-hosted or cloud-hosted instances.
-- **Hoppscotch Agent**: the local relay service that runs on the user's machine and proxies requests from the web client.
-- **Hoppscotch CLI**: the command-line client for running collections and tests, against either local collection files or an instance.
-- **Self-hosted backend**: the Node.js backend, PostgreSQL data layer, and associated services deployed by self-hosting organisations.
-- **Self-hosted web client and admin panel**: the web frontend and admin dashboard served by a self-hosted instance.
-
-**Out of scope** (separate security boundaries):
-
-- The cloud-hosted platform at hoppscotch.io or the website at hoppscotch.com.
- - If you find a vulnerability that spans both the cloud platform and a component covered here, report it; we will coordinate triage across boundaries.
-- The Hoppscotch browser extension (separate repository and distribution channel).
-- Third-party proxies or community forks.
-
-## Architecture and threat model
-
-Hoppscotch is a client-side API development and testing tool. The threat model differs by deployment mode.
-
-### Desktop app
-
-**The user is the operator.** The person sending API requests is the same person who configured the tool and entered their credentials. This is fundamentally different from a multi-tenant web service where untrusted users submit input to a shared backend.
-
-**Local data storage is by design.** In standalone mode, the Desktop app persists collections, environments, request history, and credentials (including tokens, API keys, and other secrets) in local storage. This data is protected by OS-level access controls and, where enabled, full-disk encryption (FileVault, BitLocker, LUKS). When connected to a self-hosted or cloud backend, data syncs to the server while a local copy is retained (see the [self-hosted section](#self-hosted-instances)).
-
-**Secret environment variables are stored locally and never synced to the server.** Environment variables marked as secret are kept in the client's local store (the Desktop app's data store or the browser's local storage, depending on platform) and are excluded from server sync. They follow the same local-data security posture as other credentials on that platform.
-
-**The relay sends HTTP requests to arbitrary URLs provided by the user.** This includes localhost, private IP ranges, and cloud metadata endpoints. The relay runs on the user's machine, and the user controls what URLs it reaches. Separately, the Desktop app's realtime features (including WebSocket, SSE, Socket.IO, and MQTT) can also connect to user-specified endpoints under the same trust model: the user initiates and controls the connection.
-
-**Per-domain TLS configuration is user-controlled.** The relay supports custom CA certificates, client certificates (PEM and PKCS#12), and per-domain toggles for host and peer verification. Users can disable TLS verification for specific domains to work with self-signed certificates or corporate PKI environments. These are deliberate operator choices on the user's own machine.
-
-**The Desktop app loads web application bundles from instances the user adds.** When a user adds a self-hosted instance, the app downloads the instance's compiled web application (HTML, JavaScript, CSS) and runs it in an embedded webview. Remote bundles are verified with Ed25519 signatures and per-file BLAKE3 integrity hashes before loading (see [Security controls](#security-controls)). Bundles shipped with the installer are trusted as part of the build and release signing process. Adding an instance is an explicit trust decision, comparable to installing an extension or connecting to a self-hosted service.
-
-**Debug-level logging is intentional.** The Desktop app logs at debug level by default and writes to rotating local log files. The log files sit alongside the same data in the application's own data store.
-
-**Auto-updates are signature-verified.** The Desktop app checks `releases.hoppscotch.com` for available updates. Update manifests are verified against a public key before any binary is applied. This is a read-only check; no user data, credentials, or usage information is transmitted.
-
-**Local backups are created on version changes.** The Desktop app creates backups of the local data store when the application version changes, retaining up to three backups. These backups follow the same security posture as the primary data store: local files protected by OS access controls.
-
-### Hoppscotch Agent
-
-The Agent is a standalone local service that acts as an HTTP relay for the Hoppscotch web client, providing capabilities the browser sandbox restricts (custom headers, localhost access, client certificates, CORS bypass).
-
-**The Agent runs on the user's machine and listens on localhost.** It binds to port 9119 with a permissive CORS policy, meaning any origin can reach the port at the network level. Access control is enforced at the application layer through a registration handshake: the user enters a 6-digit one-time password displayed in the Agent UI, which establishes an encrypted communication channel (AES-256-GCM with X25519 key exchange). After registration, subsequent requests are authenticated and encrypted. The OTP does not expire and registration attempts are not rate-limited; the security assumption is that the user initiates registration intentionally while the Agent UI is visible.
-
-**The same relay trust model applies.** The Agent sends requests to arbitrary user-specified URLs, including private IP ranges and localhost. The user controls what URLs it reaches and what TLS, proxy, and certificate configuration applies per domain.
-
-**Agent data is stored locally.** Registration keys, per-domain settings (proxy configuration, client certificates, CA certificates, TLS verification toggles), and logs follow the same local-data security posture as the Desktop app.
-
-### Self-hosted instances
-
-With the backend deployed, the security model changes:
-
-**The instance administrator is the operator; users are tenants.** Self-hosted instances support multiple users, teams, role-based access control, and shared collections. Authentication and authorisation boundaries must hold between users, and server-side data must be protected at rest and in transit.
-
-**Data is stored server-side and locally.** Collections, environments, request history, and team data are persisted in PostgreSQL. Desktop app users connected to a self-hosted backend also retain a local copy; the local copy follows the same posture described in the [Desktop app section](#desktop-app). Credentials in shared team collections are accessible to team members with appropriate roles. The self-hosting organisation is responsible for database encryption, backup security, and access controls.
-
-**Collections can be published via public URLs.** Self-hosted instances allow publishing collections as documentation accessible via UUID-based slugs. Published documentation is publicly accessible without authentication. The self-hosting organisation controls which collections are published.
-
-**The admin dashboard has elevated privileges.** Instance administrators can view and manage all users, send invitations, and configure instance-wide settings through the admin interface. Admin actions are subject to role checks but operate across all teams and users on the instance.
-
-**Infrastructure API tokens provide programmatic access.** The backend supports API tokens (infra tokens) with configurable expiry for programmatic access to instance management. These tokens should be treated with the same care as admin credentials.
-
-**Backend session management.** User sessions use configurable cookie names and auto-generated session secrets. The self-hosting organisation can override session configuration via environment variables. Session secrets must be set explicitly in production deployments; auto-generated values are not suitable for production use.
-
-**Optional analytics.** If `INFRA.ALLOW_ANALYTICS_COLLECTION` is enabled, the backend sends aggregate instance telemetry (user count, workspace count, version) to PostHog. Opt-in, disabled by default. No request content, credentials, or per-user data is included.
-
-## Security controls
-
-**Bundle signature verification.** Remote bundles from self-hosted instances are verified with Ed25519 signatures and per-file BLAKE3 hashes. A bundle with an invalid signature or hash mismatch is rejected and will not load. The signing key is fetched from the serving instance over the instance connection (TLS/HTTPS strongly recommended). Signature verification protects against bundle corruption in the local cache and against tampering in transit when the connection is trusted. It does not protect against a compromised instance, since the instance provides both the key and the bundle, nor against an active man-in-the-middle if the key is fetched over untrusted transport, since an attacker could replace both. The trust boundary is the connection to the instance and the user's decision to add it.
-
-**Script sandboxing.** Pre-request and post-request scripts are isolated from the host environment. By default, scripts run in a QuickJS WebAssembly sandbox on every platform — isolated from the browser context, the Tauri IPC layer (on Desktop), and the host OS. The opt-out mechanism for the legacy compatibility mode differs per platform: Desktop and web expose the "Experimental scripting sandbox" toggle in Settings (on by default); the CLI opts in via the `--legacy-sandbox` flag. The legacy compatibility mode is retained as a backward-compatibility path for scripts that rely on host JavaScript semantics not exposed under QuickJS — on Desktop and web it runs scripts in a dedicated Web Worker using the `Function` constructor; on the CLI it runs scripts in an `isolated-vm` V8 isolate. The Web Worker legacy path does not provide the same isolation guarantees as QuickJS; the `isolated-vm` legacy path provides V8-isolate-level isolation but a different API surface from the QuickJS path. In the QuickJS paths, scripts receive controlled access to request data via the `pw`, `hopp`, and `pm` API namespaces, with request mutation limited to the documented pre-request APIs; network access is mediated through a controlled fetch hook, and scripts cannot make arbitrary system calls or access the filesystem. The Web Worker legacy mode preserves a separate Web Worker execution context but exposes only the `pw` namespace and does not mediate access to standard worker globals such as `fetch`; users opting in accept that scripts can reach any URL the worker context can reach. Scripts imported from external collection files follow the same default-versus-legacy execution path and constraints as locally authored scripts.
-
-**Update signature verification.** The auto-updater verifies update manifests against a public key before applying any update. A tampered manifest or binary will be rejected.
-
-**Rate limiting.** The self-hosted backend enforces request rate limiting via configurable TTL and max-request thresholds (`INFRA.RATE_LIMIT_TTL`, `INFRA.RATE_LIMIT_MAX`). This applies to REST and GraphQL endpoints by default, though some authenticated mutations opt out of throttling where rate limiting would interfere with normal interactive use.
-
-**GraphQL query complexity limiting.** The self-hosted backend enforces query complexity limits on the GraphQL API to prevent denial-of-service through deeply nested or expensive queries.
-
-## Reporting a security vulnerability
-
-We use [GitHub Security Advisories](https://github.com/hoppscotch/hoppscotch/security/advisories) to manage reports. If you do not receive a response, reach out to support@hoppscotch.io with the GHSA advisory link.
-
-If you disagree with our assessment, reply on the advisory with additional context or evidence. We will re-evaluate.
-
-Reports must demonstrate familiarity with the architecture and threat model described in this document. A report that flags a behaviour already documented here as intentional, or that applies a generic vulnerability classification (such as SSRF, insecure storage, or CORS misconfiguration) without explaining how the finding circumvents the stated trust model, will be closed. This applies to all reports regardless of how they were produced, including those generated with AI tools, LLMs, or automated scanners.
-
-> [!NOTE]
-> Advisories may move to the relevant repository (for example, an XSS in a UI component might belong in [`@hoppscotch/ui`](https://github.com/hoppscotch/ui)). If in doubt, open your report in `hoppscotch/hoppscotch` GHSA.
-
-**Do not create a GitHub issue to report a security vulnerability.**
-
-## What does not qualify as a vulnerability
-
-Review the threat model above before reporting. The architecture and threat model section documents deliberate design decisions for each component. A finding that matches a known vulnerability class (CWE, OWASP category, or similar) is not automatically a vulnerability in this project; the threat model explains why. Reports that restate a documented design decision as a vulnerability will be closed without further analysis. The following are by design or out of scope.
-
-**Intended Desktop app and Agent behaviour:**
-- The relay or Agent sending requests to private IP ranges, localhost, or cloud metadata endpoints. This is the product's core function.
-- Credentials, tokens, or API keys stored in local storage, the application data store, local log files, or local backups on the user's machine. Local data is protected by OS-level access controls.
-- Debug-level log output containing request details including headers and authentication data. The same data already exists in the local data store.
-- A self-hosted instance bundle having access to application data within the Desktop app after passing signature verification. Adding an instance is an explicit trust decision.
-- Users disabling TLS host or peer verification for specific domains. This is an operator-controlled per-domain setting for working with self-signed or internal certificates.
-- WebSocket, SSE, Socket.IO, or MQTT connections reaching user-specified endpoints, including internal addresses. These are separate realtime features under the same trust model as HTTP relay requests.
-- Pre-request or post-request scripts from imported collections executing in the sandbox. The sandbox applies equally to imported and locally authored scripts.
-- The Desktop app checking `releases.hoppscotch.com` for updates. No user data is transmitted; update manifests are signature-verified.
-- The Agent accepting connections from any origin on localhost:9119. CORS is permissive by design; access control is enforced through the registration handshake and encrypted channel.
-- The Agent's registration OTP having no expiry and registration attempts not being rate-limited. The security assumption, documented in the Agent section above, is that the user initiates registration intentionally while the Agent UI is visible on their own machine. This is not CWE-307 (improper restriction of excessive authentication attempts) because the Agent is a local service, not a remote authentication endpoint.
-- Theoretical attacks against the Desktop app or Agent that require prior local access to the user's machine, since the attacker already has access to the same data through the operating system.
-
-**Intended self-hosted behaviour:**
-- First-run configuration endpoints being accessible without authentication before any administrator exists. These endpoints are intentionally unauthenticated during initial bootstrap so that the self-hosting organisation can complete setup, and are gated once an administrator is provisioned. This is not CWE-306 (missing authentication for critical function); it is the documented bootstrap path. Reports against an uninitialised instance describe the intended path. Bootstrap-related findings against an instance that has already been onboarded are a distinct issue and should be reported.
-- Published collections being accessible without authentication via their public URL. The self-hosting organisation controls which collections are published. This is not CWE-284 (improper access control); publication is an explicit operator action.
-- The auto-generated session secret used when `INFRA.SESSION_SECRET` is not set. The threat model already notes that auto-generated values are not suitable for production deployments. The self-hosting organisation is responsible for setting explicit secrets in their environment configuration.
-- Some authenticated GraphQL mutations opting out of rate limiting. These opt-outs are intentional where throttling would interfere with normal interactive use and are scoped to authenticated sessions.
-
-**Out of scope:**
-- Vulnerabilities in dependencies without a demonstrated practical attack against Hoppscotch.
-- Automated scanner output, AI-generated vulnerability reports, or generic security assessments that have not been validated against this document's architecture and threat model. A report must identify what specific security control is missing or bypassable in context, not merely flag a code pattern that matches a known vulnerability class. Tools that scan a codebase and produce findings without reading the threat model will generate false positives against this project.
-- Applying a generic vulnerability classification to behaviour this document explains as intentional. Sending HTTP requests to user-specified private IP ranges is the product's core function, not server-side request forgery (CWE-918). Storing credentials in local files on the user's own machine is the expected data model for a single-user developer tool, not insecure credential storage (CWE-312). A permissive CORS policy on a localhost service with application-layer authentication is documented above, not a CORS misconfiguration (CWE-942).
-- Missing HTTP security headers (Content-Security-Policy, Strict-Transport-Security, X-Frame-Options) on the self-hosted web client without a demonstrated attack that the header would have prevented in this application's deployment context.
-- Findings against hoppscotch.io or hoppscotch.com; report through the platform's security channel. Cross-boundary reports involving both a self-hosted component and the cloud platform are accepted here and will be coordinated.
diff --git a/TRANSLATIONS.md b/TRANSLATIONS.md
deleted file mode 100644
index fa58f381..00000000
--- a/TRANSLATIONS.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Translations
-
-Thanks for showing your interest in helping us to translate the software.
-
-## Creating a new translation
-
-Before you start working on a new language, please look through the [open pull requests](https://github.com/hoppscotch/hoppscotch/pulls) to see if anyone is already working on a translation. If you find one, please join the discussion and help us keep the existing translations up to date.
-
-if there is no existing translation, you can create a new one by following these steps:
-
-1. **[Fork the repository](https://github.com/hoppscotch/hoppscotch/fork).**
-2. **Checkout the `main` branch for latest translations.**
-3. **Create a new branch for your translation with base branch `main`.**
-4. **Create target language file in the [`/packages/hoppscotch-common/locales`](https://github.com/hoppscotch/hoppscotch/tree/main/packages/hoppscotch-common/locales) directory.**
-5. **Copy the contents of the source file [`/packages/hoppscotch-common/locales/en.json`](https://github.com/hoppscotch/hoppscotch/blob/main/packages/hoppscotch-common/locales/en.json) to the target language file.**
-6. **Translate the strings in the target language file.**
-7. **Add your language entry to [`/packages/hoppscotch-common/languages.json`](https://github.com/hoppscotch/hoppscotch/blob/main/packages/hoppscotch-common/languages.json).**
-8. **Save and commit changes.**
-9. **Send a pull request.**
-
-_You may send a pull request before all steps above are complete: e.g., you may want to ask for help with translations, or getting tests to pass. However, your pull request will not be merged until all steps above are complete._
-
-Completing an initial translation of the whole site is a fairly large task. One way to break that task up is to work with other translators through pull requests on your fork. You can also [add collaborators to your fork](https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/inviting-collaborators-to-a-personal-repository) if you'd like to invite other translators to commit directly to your fork and share responsibility for merging pull requests.
-
-## Updating a translation
-
-### Corrections
-
-If you notice spelling or grammar errors, typos, or opportunities for better phrasing, open a pull request with your suggested fix. If you see a problem that you aren't sure of or don't have time to fix, [open an issue](https://github.com/hoppscotch/hoppscotch/issues/new/choose).
-
-### Broken links
-
-When tests find broken links, try to fix them across all translations. Ideally, only update the linked URLs, so that translation changes will definitely not be necessary.
diff --git a/docker-compose.deploy.yml b/docker-compose.deploy.yml
deleted file mode 100644
index e9b7919a..00000000
--- a/docker-compose.deploy.yml
+++ /dev/null
@@ -1,59 +0,0 @@
-# THIS IS NOT TO BE USED FOR PERSONAL DEPLOYMENTS!
-# Internal Docker Compose Image used for internal testing deployments
-
-services:
- hoppscotch-db:
- image: postgres:15
- user: postgres
- environment:
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: testpass
- POSTGRES_DB: hoppscotch
- healthcheck:
- test:
- [
- "CMD-SHELL",
- "sh -c 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}'",
- ]
- interval: 5s
- timeout: 5s
- retries: 10
-
- hoppscotch-aio:
- container_name: hoppscotch-aio
- build:
- dockerfile: prod.Dockerfile
- context: .
- target: aio
- environment:
- # DATABASE_URL is read from the .env file to allow the backend to connect with an external database.
- # This allows the backend to retain existing data and prevents database resets during deployments.
- # - DATABASE_URL=postgresql://postgres:testpass@hoppscotch-db:5432/hoppscotch
- - ENABLE_SUBPATH_BASED_ACCESS=true
- env_file:
- - ./.env
- depends_on:
- hoppscotch-db:
- condition: service_healthy
- command:
- [
- "sh",
- "-c",
- "pnpm exec prisma migrate deploy && node /usr/src/app/aio_run.mjs",
- ]
- healthcheck:
- test:
- [
- "CMD",
- "curl",
- "-f",
- "-s",
- "-o",
- "/dev/null",
- "-w",
- "%{http_code}",
- "http://localhost:80",
- ]
- interval: 2s
- timeout: 10s
- retries: 30
diff --git a/docker-compose.yml b/docker-compose.yml
index 6f103935..55d08340 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,160 +1,13 @@
-# To make it easier to self-host, we have a preset docker compose config that also
-# has a container with a Postgres instance running.
-# You can tweak around this file to match your instances
-
-# PROFILES EXPLANATION:
-#
-# We use Docker Compose profiles to manage different deployment scenarios and avoid port conflicts.
-#
-# These are all the available profiles:
-# - default: All-in-one service + database + auto-migration (recommended for most users)
-# - default-no-db: All-in-one service without database (for users with external DB)
-# - backend: The backend service only
-# - app: The main Hoppscotch application and the webapp server
-# - admin: The self-host admin dashboard only
-# - database: Just the PostgreSQL database
-# - just-backend: All services except webapp for local development
-# - deprecated: All deprecated services (not recommended)
-
-# USAGE:
-#
-# To run the default setup: docker compose --profile default up
-# To run without database: docker compose --profile default-no-db up
-# To run specific components: docker compose --profile backend up
-# To run all except webapp: docker compose --profile just-backend up
-# To run deprecated services: docker compose --profile deprecated up
-
-# NOTE: The default and default-no-db profiles should not be mixed with individual service
-# profiles as they would conflict on ports.
-
services:
- # This service runs the backend app in the port 3170
- hoppscotch-backend:
- profiles: ["backend", "just-backend", "app", "admin"]
- container_name: hoppscotch-backend
- build:
- dockerfile: prod.Dockerfile
- context: .
- target: backend
- env_file:
- - ./.env
- restart: always
- environment:
- # Edit the below line to match your PostgresDB URL if you have an outside DB (make sure to update the .env file as well)
- - DATABASE_URL=postgresql://postgres:testpass@hoppscotch-db:5432/hoppscotch?connect_timeout=300
- - PORT=8080
- volumes:
- # Uncomment the line below when modifying code. Only applicable when using the "dev" target.
- # - ./packages/hoppscotch-backend/:/usr/src/app
- - /usr/src/app/node_modules/
- depends_on:
- hoppscotch-db:
- condition: service_healthy
- ports:
- - "3180:80"
- - "3170:3170"
-
- # The main hoppscotch app with integrated webapp server. This will be hosted at port 3000
- # The webapp server will be accessible at port 3200
- # NOTE: To do TLS or play around with how the app is hosted, you can look into the Caddyfile for
- # the SH admin dashboard server at packages/hoppscotch-selfhost-web/Caddyfile
- hoppscotch-app:
- profiles: ["app"]
- container_name: hoppscotch-app
- build:
- dockerfile: prod.Dockerfile
- context: .
- target: app
- env_file:
- - ./.env
- depends_on:
- - hoppscotch-backend
- ports:
- - "3080:80"
- - "3000:3000"
- - "3200:3200"
-
- # The Self Host dashboard for managing the app. This will be hosted at port 3100
- # NOTE: To do TLS or play around with how the app is hosted, you can look into the Caddyfile for
- # the SH admin dashboard server at packages/hoppscotch-sh-admin/Caddyfile
- hoppscotch-sh-admin:
- profiles: ["admin"]
- container_name: hoppscotch-sh-admin
- build:
- dockerfile: prod.Dockerfile
- context: .
- target: sh_admin
- env_file:
- - ./.env
- depends_on:
- - hoppscotch-backend
- ports:
- - "3280:80"
- - "3100:3100"
-
- # The service that spins up all services at once in one container
- hoppscotch-aio:
- profiles: ["default"]
- container_name: hoppscotch-aio
- restart: unless-stopped
- build:
- dockerfile: prod.Dockerfile
- context: .
- target: aio
- env_file:
- - ./.env
- depends_on:
- hoppscotch-db:
- condition: service_healthy
- ports:
- - "3000:3000"
- - "3100:3100"
- - "3170:3170"
- - "3200:3200"
- - "3080:80"
-
- # Profile with no database dependency (purely developmental)
- hoppscotch-aio-no-db:
- profiles: ["default-no-db"]
- container_name: hoppscotch-aio
- restart: unless-stopped
- build:
- dockerfile: prod.Dockerfile
- context: .
- target: aio
- env_file:
- - ./.env
- ports:
- - "3000:3000"
- - "3100:3100"
- - "3170:3170"
- - "3200:3200"
- - "3080:80"
-
- # The preset DB service, you can delete/comment the below lines if
- # you are using an external postgres instance
- # This will be exposed at port 5432
hoppscotch-db:
- profiles:
- [
- "default",
- "database",
- "just-backend",
- "backend",
- "app",
- "admin",
- "deprecated",
- ]
image: postgres:15
- ports:
- - "5432:5432"
user: postgres
environment:
- # The default user defined by the docker image
POSTGRES_USER: postgres
- # NOTE: Please UPDATE THIS PASSWORD!
- POSTGRES_PASSWORD: testpass
- POSTGRES_DB: hoppscotch
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-testpass}
+ POSTGRES_DB: ${POSTGRES_DB:-hoppscotch}
+ volumes:
+ - hoppscotch-db:/var/lib/postgresql/data
healthcheck:
test:
[
@@ -165,93 +18,32 @@ services:
timeout: 5s
retries: 10
- # Auto-migration service - handles database migrations automatically
- hoppscotch-migrate:
- profiles: ["default", "just-backend", "backend", "app", "admin"]
+ hoppscotch-aio:
+ container_name: hoppscotch-aio
+ restart: unless-stopped
build:
dockerfile: prod.Dockerfile
context: .
- target: backend
+ target: aio
env_file:
- ./.env
- depends_on:
- hoppscotch-db:
- condition: service_healthy
- command: sh -c "pnpm exec prisma migrate deploy"
-
- # All the services listed below are deprecated
- # These services are kept for backward compatibility but should not be used for new deployments
- hoppscotch-old-backend:
- profiles: ["deprecated"]
- container_name: hoppscotch-old-backend
- build:
- dockerfile: packages/hoppscotch-backend/Dockerfile
- context: .
- target: prod
- env_file:
- - ./.env
- restart: always
environment:
- # Edit the below line to match your PostgresDB URL if you have an outside DB (make sure to update the .env file as well)
- - DATABASE_URL=postgresql://postgres:testpass@hoppscotch-db:5432/hoppscotch?connect_timeout=300
- - PORT=3000
- volumes:
- # Uncomment the line below when modifying code. Only applicable when using the "dev" target.
- # - ./packages/hoppscotch-backend/:/usr/src/app
- - /usr/src/app/node_modules/
+ DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD:-testpass}@hoppscotch-db:5432/${POSTGRES_DB:-hoppscotch}
depends_on:
hoppscotch-db:
condition: service_healthy
+ command:
+ [
+ "sh",
+ "-c",
+ "pnpm exec prisma migrate deploy && node /usr/src/app/aio_run.mjs",
+ ]
ports:
- - "3170:3000"
+ - "3000:3000"
+ - "3100:3100"
+ - "3170:3170"
+ - "3200:3200"
+ - "3080:80"
- hoppscotch-old-app:
- profiles: ["deprecated"]
- container_name: hoppscotch-old-app
- build:
- dockerfile: packages/hoppscotch-selfhost-web/Dockerfile
- context: .
- env_file:
- - ./.env
- depends_on:
- - hoppscotch-old-backend
- ports:
- - "3000:8080"
-
- hoppscotch-old-sh-admin:
- profiles: ["deprecated"]
- container_name: hoppscotch-old-sh-admin
- build:
- dockerfile: packages/hoppscotch-sh-admin/Dockerfile
- context: .
- env_file:
- - ./.env
- depends_on:
- - hoppscotch-old-backend
- ports:
- - "3100:8080"
-
-# DEPLOYMENT SCENARIOS:
-# 1. Default deployment (recommended):
-# docker compose --profile default up
-# This will start: AIO + database + auto-migration
-#
-# 2. Default deployment without database:
-# docker compose --profile default-no-db up
-# This will start: AIO only (use when you have an external database)
-#
-# 3. Individual service deployment:
-# docker compose --profile backend up # Just the backend
-# docker compose --profile app up # Just the app and webapp server
-# docker compose --profile admin up # Just the admin dashboard
-# docker compose --profile database up # Just the database
-#
-# 4. Development deployment:
-# docker compose --profile just-backend up # All services except webapp
-#
-# 5. Deprecated services:
-# docker compose --profile deprecated up
-# This will start all deprecated services (not recommended for new deployments)
-#
-# Remember: The default and default-no-db profiles should not be mixed with individual service
-# profiles as they would conflict on ports.
+volumes:
+ hoppscotch-db:
diff --git a/firebase.json b/firebase.json
deleted file mode 100644
index 4120bed0..00000000
--- a/firebase.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "firestore": {
- "rules": "firestore.rules",
- "indexes": "firestore.indexes.json"
- },
- "hosting": {
- "predeploy": [
- "mv .env.example .env && npm install -g pnpm && pnpm i && pnpm run generate"
- ],
- "public": "packages/hoppscotch-web/dist",
- "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
- "rewrites": [
- {
- "source": "**",
- "destination": "/index.html"
- }
- ]
- }
-}
diff --git a/firestore.indexes.json b/firestore.indexes.json
deleted file mode 100644
index 415027e5..00000000
--- a/firestore.indexes.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "indexes": [],
- "fieldOverrides": []
-}
diff --git a/firestore.rules b/firestore.rules
deleted file mode 100644
index 830e3972..00000000
--- a/firestore.rules
+++ /dev/null
@@ -1,13 +0,0 @@
-service cloud.firestore {
- match /databases/{database}/documents {
- // Make sure the uid of the requesting user matches name of the user
- // document. The wildcard expression {userId} makes the userId variable
- // available in rules.
- match /users/{userId} {
- allow read, write, create, update, delete: if request.auth.uid != null && request.auth.uid == userId;
- }
- match /users/{userId}/{document=**} {
- allow read, write, create, update, delete: if request.auth.uid != null && request.auth.uid == userId;
- }
- }
-}
diff --git a/netlify.toml b/netlify.toml
deleted file mode 100644
index 4a3899f4..00000000
--- a/netlify.toml
+++ /dev/null
@@ -1,77 +0,0 @@
-[build.environment]
- NODE_VERSION = "14"
- NPM_FLAGS = "--prefix=/dev/null"
-
-[build]
- base = "/"
- publish = "packages/hoppscotch-web/dist"
- command = "npx pnpm i --store=node_modules/.pnpm-store && npx pnpm run generate"
-
-[[headers]]
- for = "/*"
- [headers.values]
- X-Frame-Options = "SAMEORIGIN"
- X-XSS-Protection = "1; mode=block"
-
-[[redirects]]
- from = "/discord"
- to = "https://discord.gg/GAMWxmR"
- status = 301
- force = true
-
-[[redirects]]
- from = "/telegram"
- to = "https://t.me/hoppscotch"
- status = 301
- force = true
-
-[[redirects]]
- from = "/beta"
- to = "https://forms.gle/XPYDMp8m6JHNWcYp9"
- status = 301
- force = true
-
-[[redirects]]
- from = "/careers"
- to = "https://company.hoppscotch.io/careers"
- status = 301
- force = true
-
-[[redirects]]
- from = "/newsletter"
- to = "http://eepurl.com/hy0eWH"
- status = 301
- force = true
-
-[[redirects]]
- from = "/twitter"
- to = "https://x.com/hoppscotch_io"
- status = 301
- force = true
-
-[[redirects]]
- from = "/github"
- to = "https://github.com/hoppscotch/hoppscotch"
- status = 301
- force = true
-
-[[redirects]]
- from = "/announcements"
- to = "https://company.hoppscotch.io/announcements"
- status = 301
- force = true
-
-[[redirects]]
- from = "/robots.txt"
- to = "/robots.txt"
- status = 200
-
-[[redirects]]
- from = "/sitemap.xml"
- to = "/sitemap.xml"
- status = 200
-
-[[redirects]]
- from = "/*"
- to = "/index.html"
- status = 200
diff --git a/package.json b/package.json
index fbf13590..e76bb797 100644
--- a/package.json
+++ b/package.json
@@ -17,11 +17,17 @@
"typecheck": "pnpm -r do-typecheck",
"lintfix": "pnpm -r do-lintfix",
"pre-commit": "pnpm -r do-lint && pnpm -r do-typecheck",
- "test": "pnpm -r do-test",
- "generate-ui": "pnpm -r do-build-ui"
+ "test": "pnpm -r do-test"
},
"workspaces": [
- "./packages/*"
+ "./packages/codemirror-lang-graphql",
+ "./packages/hoppscotch-backend",
+ "./packages/hoppscotch-common",
+ "./packages/hoppscotch-data",
+ "./packages/hoppscotch-js-sandbox",
+ "./packages/hoppscotch-kernel",
+ "./packages/hoppscotch-selfhost-web",
+ "./packages/hoppscotch-sh-admin"
],
"devDependencies": {
"@commitlint/cli": "20.5.2",
diff --git a/packages/hoppscotch-agent/.gitignore b/packages/hoppscotch-agent/.gitignore
deleted file mode 100644
index e9f02db4..00000000
--- a/packages/hoppscotch-agent/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-dist
-dist-ssr
-*.local
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
-# Devenv
-.devenv*
-devenv.local.nix
-
-# direnv
-.direnv
-
-# pre-commit
-.pre-commit-config.yaml
diff --git a/packages/hoppscotch-agent/README.md b/packages/hoppscotch-agent/README.md
deleted file mode 100644
index 8d850ae4..00000000
--- a/packages/hoppscotch-agent/README.md
+++ /dev/null
@@ -1,281 +0,0 @@
-
-
-
Hoppscotch Agent
-
-
-
-
-
-#### Hoppscotch Agent is a cross-platform HTTP request relay for Hoppscotch built with [Tauri V2](https://v2.tauri.app/) that adds capabilities like custom headers, certificates, proxies, and local access typically restricted in browsers.
-
-The agent runs as a local system service on port `9119`, acting as an intermediary between the Hoppscotch web application and target APIs. It establishes an encrypted communication channel authenticated via an OTP registration process.
-
-## Installation
-
-### Standard Installation
-
-1. Download the latest version of Hoppscotch Agent from [releases](https://github.com/hoppscotch/agent-releases)
-2. Run the installer
-3. Follow the installation wizard to complete setup
-4. The agent automatically starts and appears in your system tray
-
-### Portable Version
-
-The portable version runs without installation and does not include automatic updates.
-
-1. Download the portable version for your operating system
-2. Extract the archive to your desired location
-3. Run the executable directly
-4. The agent will start and appear in your system tray
-
-> [!Note]
-> The portable version uses a separate configuration (`tauri.portable.conf.json`) that disables bundling and updater functionality.
-
-## Getting Started
-
-### Registration
-
-1. Open Hoppscotch web app and navigate to **Settings** → **Interceptors**
-2. Select **Agent** from the available interceptors
-3. Click **Register Agent** button
-4. The agent window displays a 6-digit verification code
-5. Enter the verification code in the OTP input field
-6. Click the confirm button to establish connection
-7. The agent displays a masked auth key hash when successfully registered
-
-### Usage
-
-Once registered, all HTTP requests made through Hoppscotch are processed by the agent. The agent provides:
-
-- CORS bypass by processing requests locally
-- Client certificate authentication for mutual TLS
-- HTTP Digest Authentication using challenge-response mechanisms
-- Custom headers that browsers typically restrict
-- Proxy routing with authentication support
-- Local network and localhost access
-- SSL/TLS verification controls
-- And much more
-
-## Domain-Specific Configuration
-
-The agent (and `Native`) interceptor supports per-domain configuration overrides with a global default (`*`) domain:
-
-### Domain Management
-- **Global Defaults**: Base settings applied to all domains (domain: `*`)
-- **Domain Overrides**: Specific settings for individual domains (e.g., `api.example.com`)
-- **Domain Addition**: Add new domains through the domain management modal
-- **Domain Removal**: Remove custom domain configurations (global default cannot be removed)
-
-### SSL/TLS Security Settings
-
-For each domain, configure:
-
-- **Verify Host**: Enable/disable hostname verification during SSL handshake
-- **Verify Peer**: Enable/disable peer certificate verification
-- **CA Certificates**: Upload custom Certificate Authority certificates for domain validation
-- **Client Certificates**: Configure client certificates for mutual TLS authentication
-
-## Client Certificates
-
-The agent supports client certificate authentication for APIs requiring mutual TLS:
-
-### Certificate Formats
-- **.pem certificates**: Requires separate certificate (.crt/.cer/.pem) and private key (.key/.pem) files
-- **.pfx/.pkcs12 certificates**: Single file format with optional password protection
-
-### Configuration
-
-1. Access **Settings** → **Interceptors** → **Agent** in Hoppscotch
-2. Select the target domain from the domain selector
-3. Click **Client Certificates** button
-4. Choose certificate format (PEM or PFX tab)
-5. Upload certificate files:
- - **PEM**: Upload certificate file and private key file separately
- - **PFX**: Upload .pfx/.pkcs12 file and enter password if required
-6. Configuration is automatically saved per domain
-
-### CA Certificates
-
-Custom Certificate Authority certificates can be added per domain:
-
-1. Navigate to the CA Certificates section for the target domain
-2. Click **Add Certificate File**
-3. Upload the CA certificate file
-4. Toggle certificate inclusion on/off as needed
-5. Remove certificates using the trash icon
-
-## Proxy Configuration
-
-The agent supports HTTP/HTTPS proxy routing with authentication (including NTLM):
-
-### Proxy Settings
-- **Proxy URL**: HTTP/HTTPS proxy server address with port
-- **Proxy Authentication**: Username and password for proxy server authentication
-- **Per-Domain**: Each domain can have different proxy configurations
-
-### Configuration
-
-1. Select the target domain
-2. Toggle the **Proxy** switch to enable
-3. Enter the proxy URL (e.g., `http://proxy.example.com:8080`)
-4. Configure proxy authentication if required:
- - Username field
- - Password field (with show/hide toggle)
-
-## System Integration
-
-### System Tray
-The agent runs with system tray integration, providing access to:
-- **Show Registrations**: View active connections and registration status
-- **Clear Registrations**: Remove all registered instances
-- **Maximize Window**: Show the agent interface window
-- **Quit**: Exit the agent application
-
-### Configuration Storage
-The agent stores configuration in platform-specific locations:
-
-- **Windows**: `%APPDATA%\io.hoppscotch.agent\`
-- **macOS**: `~/Library/Application Support/io.hoppscotch.agent/`
-- **Linux**: `~/.config/io.hoppscotch.agent/`
-
-### Logging
-Logs are stored in platform-specific directories:
-
-- **Windows**: `%LOCALAPPDATA%\io.hoppscotch.agent\logs\`
-- **macOS**: `~/Library/Logs/io.hoppscotch.agent/`
-- **Linux**: `~/.local/share/io.hoppscotch.agent/logs/`
-
-### Auto-Start Configuration
-The standard installation includes auto-start functionality. The portable version does not include auto-start and must be launched manually.
-
-## Building from Source
-
-### Prerequisites
-
-- [Node.js](https://nodejs.org/) (v18 or later)
-- [pnpm](https://pnpm.io/) package manager
-- [Rust](https://rustup.rs/) (latest stable)
-- [Tauri CLI](https://tauri.app/v1/guides/getting-started/prerequisites)
-
-### Development
-
-```bash
-# Clone the repository
-git clone https://github.com/hoppscotch/hoppscotch.git
-cd hoppscotch/packages/hoppscotch-agent
-
-# Install dependencies
-pnpm install
-
-# Start development server
-pnpm tauri dev
-```
-
-### Production Build
-
-```bash
-# Build standard version
-pnpm tauri build
-
-# Build portable version
-pnpm tauri build --config src-tauri/tauri.portable.conf.json
-```
-
-The built applications will be available in `src-tauri/target/release/bundle/`
-
-### Build Variants
-
-Two build configurations are available:
-
-- **Standard** (`tauri.conf.json`): Includes installer, auto-updater, and auto-start functionality
-- **Portable** (`tauri.portable.conf.json`): Standalone executable without installation requirements
-
-## Network Configuration
-
-### Default Port
-The agent runs on port `9119` by default. Make sure this port is not blocked by firewalls.
-
-### Communication Protocol
-- **Encryption**: AES-256-GCM for all agent-to-web-app communication
-- **Authentication**: X25519 key exchange for secure channel establishment
-- **Registration**: One-time 6-digit OTP verification process
-
-## System Requirements
-
-### Windows
-- **OS Version**: Windows 10 1803+ or Windows 11
-- **Architecture**: x64
-- **Dependencies**: WebView2 Runtime (auto-installed for standard version)
-
-### macOS
-- **OS Version**: macOS 10.15 (Catalina) or later
-- **Architecture**: Intel x64 or Apple Silicon (ARM64)
-
-### Linux
-- **Architecture**: x64
-- **Dependencies**: WebKit2GTK 2.44.0+ (usually pre-installed)
-- **Minimum**: Systems with GLIBC 2.38+
-
-## Troubleshooting
-
-### Agent Detection Issues
-1. **"Agent not detected" popup**: Verify the agent is running by checking the system tray for the Hoppscotch icon
-2. **Switching interceptors blocked**: If the "Agent not detected" popup prevents switching interceptors, restart your browser and stop the agent before changing interceptor settings
-3. **Port accessibility**: Check that no firewall is blocking port `9119`
-4. **Browser compatibility**: Safari on macOS may have CORS issues with localhost:9119 due to access control checks, try Chrome/Firefox for agent registration
-
-### Registration Failures
-1. **"Failed to initiate the registration"**: This error may occur due to browser security policies or extension conflicts
-2. **Missing OTP input field**: Verify the agent window is focused and displaying a 6-digit verification code
-3. **OTP expiration**: Registration codes have limited lifetime, restart the registration process if the code expires
-4. **Network connectivity**: Verify browser can reach localhost:9119/handshake
-5. **Version compatibility**: Some agent versions may be incompatible with specific Hoppscotch web app versions. For self-hosted setups, make sure Agent version in the release matches, see https://github.com/hoppscotch/hoppscotch/issues/4936#issuecomment-2756981053
-
-### Certificate Issues
-1. Verify certificate format is supported (.pem or .pfx/.pkcs12)
-2. Check certificate expiration dates
-3. Confirm private key matches certificate (for .pem files)
-4. Verify domain configuration matches target API hostname
-5. Confirm certificate password is correct (for .pfx/.pkcs12)
-6. Check CA certificate inclusion status (toggle on/off)
-
-### Request Processing Issues
-1. **Custom headers not applied**: Verify the agent is selected as interceptor, browsers may override headers like User-Agent when using default HTTP methods
-2. **CORS errors**: Confirm agent interceptor is active and requests are routing through localhost:9119
-3. **SSL/TLS verification**: Check verify host/peer settings for the target domain
-4. **Proxy routing**: Verify proxy URL format includes protocol (http:// or https://)
-
-### System-Specific Issues
-
-#### Windows
-1. Check WebView2 Runtime is installed (auto-installed with standard version)
-2. Check Windows Defender or antivirus exclusions for the agent executable
-3. Verify agent has network permissions through Windows Firewall
-
-#### macOS
-1. Safari browser may block agent connections due to CORS policies, try Chrome or Firefox instead
-2. Check macOS Gatekeeper settings if agent fails to start
-3. Verify agent is allowed in System Preferences → Security & Privacy
-
-#### Linux
-1. Check WebKit2GTK dependencies are installed
-2. Check systemd logs if agent fails to start as service
-3. Verify GLIBC version compatibility (requires 2.38+)
-
-### Portable Version Issues
-1. Manual WebView2 installation - may be required on older versions of Windows
-2. No auto-start capability - must launch manually after system restart
-3. No automatic updates - download new versions manually
-4. Verify executable permissions on Unix-like systems
-5. Check that portable version is extracted to a writable directory
-
-### Log
-Check agent logs for detailed error information:
-- **Windows**: `%LOCALAPPDATA%\io.hoppscotch.agent\logs\`
-- **macOS**: `~/Library/Logs/io.hoppscotch.agent/`
-- **Linux**: `~/.local/share/io.hoppscotch.agent/logs/`
-
-Look for connection errors, certificate validation failures, or proxy authentication issues in the log files.
diff --git a/packages/hoppscotch-agent/eslint.config.mjs b/packages/hoppscotch-agent/eslint.config.mjs
deleted file mode 100644
index 1ca0349d..00000000
--- a/packages/hoppscotch-agent/eslint.config.mjs
+++ /dev/null
@@ -1,67 +0,0 @@
-import pluginVue from "eslint-plugin-vue"
-import {
- defineConfigWithVueTs,
- vueTsConfigs,
-} from "@vue/eslint-config-typescript"
-import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"
-import globals from "globals"
-
-export default defineConfigWithVueTs(
- {
- ignores: [
- "**/*.d.ts",
- "dist/**",
- "node_modules/**",
- "src-tauri/**",
- ],
- },
- pluginVue.configs["flat/recommended"],
- vueTsConfigs.recommended,
- eslintPluginPrettierRecommended,
- {
- files: ["**/*.ts", "**/*.js", "**/*.vue"],
- linterOptions: {
- reportUnusedDisableDirectives: false,
- },
- languageOptions: {
- sourceType: "module",
- ecmaVersion: "latest",
- globals: {
- ...globals.browser,
- ...globals.node,
- },
- parserOptions: {
- requireConfigFile: false,
- ecmaFeatures: {
- jsx: false,
- },
- },
- },
- rules: {
- semi: [2, "never"],
- "no-console": "off",
- "no-debugger": process.env.HOPP_LINT_FOR_PROD === "true" ? "error" : "warn",
- "prettier/prettier":
- process.env.HOPP_LINT_FOR_PROD === "true" ? "error" : "warn",
- "vue/multi-word-component-names": "off",
- "vue/no-side-effects-in-computed-properties": "off",
- "@typescript-eslint/no-unused-vars": [
- process.env.HOPP_LINT_FOR_PROD === "true" ? "error" : "warn",
- {
- args: "all",
- argsIgnorePattern: "^_",
- caughtErrors: "all",
- caughtErrorsIgnorePattern: "^_",
- destructuredArrayIgnorePattern: "^_",
- varsIgnorePattern: "^_",
- ignoreRestSiblings: true,
- },
- ],
- "@typescript-eslint/no-unused-expressions": "off",
- "@typescript-eslint/no-non-null-assertion": "off",
- "@typescript-eslint/no-explicit-any": "off",
- "@typescript-eslint/no-unsafe-function-type": "off",
- "no-undef": "off",
- },
- }
-)
diff --git a/packages/hoppscotch-agent/index.html b/packages/hoppscotch-agent/index.html
deleted file mode 100644
index 7a5662ef..00000000
--- a/packages/hoppscotch-agent/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
- Hoppscotch Agent
-
-
-
-
-
-
diff --git a/packages/hoppscotch-agent/package.json b/packages/hoppscotch-agent/package.json
deleted file mode 100644
index 37d668e8..00000000
--- a/packages/hoppscotch-agent/package.json
+++ /dev/null
@@ -1,52 +0,0 @@
-{
- "name": "hoppscotch-agent",
- "private": true,
- "version": "0.1.17",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "vue-tsc --noEmit && vite build",
- "preview": "vite preview",
- "tauri": "tauri",
- "lint": "eslint src",
- "lint:ts": "vue-tsc --noEmit",
- "lintfix": "eslint --fix src",
- "prod-lint": "cross-env HOPP_LINT_FOR_PROD=true pnpm run lint",
- "do-lint": "pnpm run prod-lint",
- "do-typecheck": "pnpm run lint:ts",
- "do-lintfix": "pnpm run lintfix"
- },
- "dependencies": {
- "@hoppscotch/ui": "0.2.5",
- "@tauri-apps/api": "2.1.1",
- "@tauri-apps/plugin-shell": "2.3.3",
- "@vueuse/core": "14.2.1",
- "axios": "1.15.2",
- "fp-ts": "2.16.11",
- "lodash-es": "4.18.1",
- "vue": "3.5.33"
- },
- "devDependencies": {
- "@iconify-json/lucide": "1.2.104",
- "@tauri-apps/cli": "2.9.3",
- "@types/lodash-es": "4.17.12",
- "@types/node": "24.10.1",
- "@typescript-eslint/eslint-plugin": "8.59.0",
- "@typescript-eslint/parser": "8.59.0",
- "@vitejs/plugin-vue": "6.0.6",
- "@vue/eslint-config-typescript": "14.7.0",
- "autoprefixer": "10.5.0",
- "cross-env": "10.1.0",
- "eslint": "9.39.2",
- "eslint-plugin-prettier": "5.5.5",
- "eslint-plugin-vue": "10.9.0",
- "globals": "16.5.0",
- "postcss": "8.5.10",
- "tailwindcss": "3.4.16",
- "typescript": "5.9.3",
- "unplugin-icons": "22.5.0",
- "unplugin-vue-components": "30.0.0",
- "vite": "7.3.2",
- "vue-tsc": "2.2.0"
- }
-}
diff --git a/packages/hoppscotch-agent/postcss.config.js b/packages/hoppscotch-agent/postcss.config.js
deleted file mode 100644
index 2e7af2b7..00000000
--- a/packages/hoppscotch-agent/postcss.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- },
-}
diff --git a/packages/hoppscotch-agent/public/icon.png b/packages/hoppscotch-agent/public/icon.png
deleted file mode 100644
index 3778416d..00000000
Binary files a/packages/hoppscotch-agent/public/icon.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/public/tauri.svg b/packages/hoppscotch-agent/public/tauri.svg
deleted file mode 100644
index 31b62c92..00000000
--- a/packages/hoppscotch-agent/public/tauri.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/packages/hoppscotch-agent/public/vite.svg b/packages/hoppscotch-agent/public/vite.svg
deleted file mode 100644
index e7b8dfb1..00000000
--- a/packages/hoppscotch-agent/public/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/packages/hoppscotch-agent/src-tauri/.cargo/config.toml b/packages/hoppscotch-agent/src-tauri/.cargo/config.toml
deleted file mode 100644
index 9017258b..00000000
--- a/packages/hoppscotch-agent/src-tauri/.cargo/config.toml
+++ /dev/null
@@ -1,25 +0,0 @@
-# Enable static linking for C runtime library on Windows.
-#
-# Rust uses the msvc toolchain on Windows,
-# which by default dynamically links the C runtime (CRT) to the binary.
-#
-# This creates a runtime dependency on the Visual C++ Redistributable (`vcredist`),
-# meaning the target machine must have `vcredist` installed for the application to run.
-#
-# Since `portable` version doesn't have an installer,
-# we can't rely on it to install dependencies, so this config.
-#
-# Basically:
-# - The `+crt-static` flag instructs the Rust compiler to statically link the C runtime for Windows builds.\
-# - To avoids runtime errors related to missing `vcredist` installations.
-# - Results in a larger binary size because the runtime is bundled directly into the executable.
-#
-# For MSVC targets specifically, it will compile code with `/MT` or static linkage.
-# See: - RFC 1721: https://rust-lang.github.io/rfcs/1721-crt-static.html
-# - Rust Reference - Runtime: https://doc.rust-lang.org/reference/runtime.html
-# - MSVC Linking Options: https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library
-# - Rust Issue #37406: https://github.com/rust-lang/rust/issues/37406
-# - Tauri Issue #3048: https://github.com/tauri-apps/tauri/issues/3048
-# - Rust Linkage: https://doc.rust-lang.org/reference/linkage.html
-[target.'cfg(windows)']
-rustflags = ["-C", "target-feature=+crt-static"]
diff --git a/packages/hoppscotch-agent/src-tauri/.gitignore b/packages/hoppscotch-agent/src-tauri/.gitignore
deleted file mode 100644
index b21bd681..00000000
--- a/packages/hoppscotch-agent/src-tauri/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-# Generated by Cargo
-# will have compiled files and executables
-/target/
-
-# Generated by Tauri
-# will have schema files for capabilities auto-completion
-/gen/schemas
diff --git a/packages/hoppscotch-agent/src-tauri/Cargo.lock b/packages/hoppscotch-agent/src-tauri/Cargo.lock
deleted file mode 100644
index fd52c1d2..00000000
--- a/packages/hoppscotch-agent/src-tauri/Cargo.lock
+++ /dev/null
@@ -1,7334 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 4
-
-[[package]]
-name = "adler2"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
-
-[[package]]
-name = "aead"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
-dependencies = [
- "crypto-common",
- "generic-array",
-]
-
-[[package]]
-name = "aes"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
-dependencies = [
- "cfg-if",
- "cipher",
- "cpufeatures",
-]
-
-[[package]]
-name = "aes-gcm"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
-dependencies = [
- "aead",
- "aes",
- "cipher",
- "ctr",
- "ghash",
- "subtle",
-]
-
-[[package]]
-name = "aho-corasick"
-version = "1.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "alloc-no-stdlib"
-version = "2.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
-
-[[package]]
-name = "alloc-stdlib"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
-dependencies = [
- "alloc-no-stdlib",
-]
-
-[[package]]
-name = "android_system_properties"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "anstream"
-version = "0.6.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
-dependencies = [
- "anstyle",
- "anstyle-parse",
- "anstyle-query",
- "anstyle-wincon",
- "colorchoice",
- "is_terminal_polyfill",
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle"
-version = "1.0.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
-
-[[package]]
-name = "anstyle-parse"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
-dependencies = [
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle-query"
-version = "1.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
-dependencies = [
- "windows-sys 0.60.2",
-]
-
-[[package]]
-name = "anstyle-wincon"
-version = "3.0.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
-dependencies = [
- "anstyle",
- "once_cell_polyfill",
- "windows-sys 0.60.2",
-]
-
-[[package]]
-name = "anyhow"
-version = "1.0.100"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
-
-[[package]]
-name = "arbitrary"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
-dependencies = [
- "derive_arbitrary",
-]
-
-[[package]]
-name = "ascii"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
-
-[[package]]
-name = "ashpd"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df"
-dependencies = [
- "enumflags2",
- "futures-channel",
- "futures-util",
- "rand 0.9.2",
- "raw-window-handle 0.6.2",
- "serde",
- "serde_repr",
- "tokio",
- "url",
- "wayland-backend",
- "wayland-client",
- "wayland-protocols",
- "zbus",
-]
-
-[[package]]
-name = "async-broadcast"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
-dependencies = [
- "event-listener",
- "event-listener-strategy",
- "futures-core",
- "pin-project-lite",
-]
-
-[[package]]
-name = "async-channel"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
-dependencies = [
- "concurrent-queue",
- "event-listener-strategy",
- "futures-core",
- "pin-project-lite",
-]
-
-[[package]]
-name = "async-compression"
-version = "0.4.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0"
-dependencies = [
- "compression-codecs",
- "compression-core",
- "futures-core",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "async-executor"
-version = "1.13.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8"
-dependencies = [
- "async-task",
- "concurrent-queue",
- "fastrand",
- "futures-lite",
- "pin-project-lite",
- "slab",
-]
-
-[[package]]
-name = "async-io"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
-dependencies = [
- "autocfg",
- "cfg-if",
- "concurrent-queue",
- "futures-io",
- "futures-lite",
- "parking",
- "polling",
- "rustix 1.1.2",
- "slab",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "async-lock"
-version = "3.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc"
-dependencies = [
- "event-listener",
- "event-listener-strategy",
- "pin-project-lite",
-]
-
-[[package]]
-name = "async-process"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
-dependencies = [
- "async-channel",
- "async-io",
- "async-lock",
- "async-signal",
- "async-task",
- "blocking",
- "cfg-if",
- "event-listener",
- "futures-lite",
- "rustix 1.1.2",
-]
-
-[[package]]
-name = "async-recursion"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "async-signal"
-version = "0.2.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c"
-dependencies = [
- "async-io",
- "async-lock",
- "atomic-waker",
- "cfg-if",
- "futures-core",
- "futures-io",
- "rustix 1.1.2",
- "signal-hook-registry",
- "slab",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "async-task"
-version = "4.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
-
-[[package]]
-name = "async-trait"
-version = "0.1.89"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "atk"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b"
-dependencies = [
- "atk-sys",
- "glib",
- "libc",
-]
-
-[[package]]
-name = "atk-sys"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086"
-dependencies = [
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "atomic-waker"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
-
-[[package]]
-name = "auto-launch"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f012b8cc0c850f34117ec8252a44418f2e34a2cf501de89e29b241ae5f79471"
-dependencies = [
- "dirs 4.0.0",
- "thiserror 1.0.69",
- "winreg 0.10.1",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
-
-[[package]]
-name = "axum"
-version = "0.7.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
-dependencies = [
- "async-trait",
- "axum-core",
- "bytes",
- "futures-util",
- "http",
- "http-body",
- "http-body-util",
- "hyper",
- "hyper-util",
- "itoa",
- "matchit",
- "memchr",
- "mime",
- "percent-encoding",
- "pin-project-lite",
- "rustversion",
- "serde",
- "serde_json",
- "serde_path_to_error",
- "serde_urlencoded",
- "sync_wrapper",
- "tokio",
- "tower",
- "tower-layer",
- "tower-service",
- "tracing",
-]
-
-[[package]]
-name = "axum-core"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
-dependencies = [
- "async-trait",
- "bytes",
- "futures-util",
- "http",
- "http-body",
- "http-body-util",
- "mime",
- "pin-project-lite",
- "rustversion",
- "sync_wrapper",
- "tower-layer",
- "tower-service",
- "tracing",
-]
-
-[[package]]
-name = "axum-extra"
-version = "0.9.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c794b30c904f0a1c2fb7740f7df7f7972dfaa14ef6f57cb6178dc63e5dca2f04"
-dependencies = [
- "axum",
- "axum-core",
- "bytes",
- "fastrand",
- "futures-util",
- "headers",
- "http",
- "http-body",
- "http-body-util",
- "mime",
- "multer",
- "pin-project-lite",
- "serde",
- "tower",
- "tower-layer",
- "tower-service",
-]
-
-[[package]]
-name = "base16"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8"
-
-[[package]]
-name = "base64"
-version = "0.21.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
-
-[[package]]
-name = "base64"
-version = "0.22.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
-
-[[package]]
-name = "bitflags"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
-
-[[package]]
-name = "bitflags"
-version = "2.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "block"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
-
-[[package]]
-name = "block-buffer"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
-name = "block2"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
-dependencies = [
- "objc2 0.5.2",
-]
-
-[[package]]
-name = "block2"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
-dependencies = [
- "objc2 0.6.3",
-]
-
-[[package]]
-name = "blocking"
-version = "1.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
-dependencies = [
- "async-channel",
- "async-task",
- "futures-io",
- "futures-lite",
- "piper",
-]
-
-[[package]]
-name = "brotli"
-version = "8.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560"
-dependencies = [
- "alloc-no-stdlib",
- "alloc-stdlib",
- "brotli-decompressor",
-]
-
-[[package]]
-name = "brotli-decompressor"
-version = "5.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
-dependencies = [
- "alloc-no-stdlib",
- "alloc-stdlib",
-]
-
-[[package]]
-name = "bumpalo"
-version = "3.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
-
-[[package]]
-name = "bytemuck"
-version = "1.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
-
-[[package]]
-name = "byteorder"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
-
-[[package]]
-name = "byteorder-lite"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
-
-[[package]]
-name = "bytes"
-version = "1.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "cairo-rs"
-version = "0.18.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2"
-dependencies = [
- "bitflags 2.10.0",
- "cairo-sys-rs",
- "glib",
- "libc",
- "once_cell",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "cairo-sys-rs"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51"
-dependencies = [
- "glib-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "camino"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "cargo-platform"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "cargo_metadata"
-version = "0.19.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba"
-dependencies = [
- "camino",
- "cargo-platform",
- "semver",
- "serde",
- "serde_json",
- "thiserror 2.0.17",
-]
-
-[[package]]
-name = "cargo_toml"
-version = "0.22.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77"
-dependencies = [
- "serde",
- "toml 0.9.8",
-]
-
-[[package]]
-name = "cc"
-version = "1.2.43"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2"
-dependencies = [
- "find-msvc-tools",
- "shlex",
-]
-
-[[package]]
-name = "cesu8"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
-
-[[package]]
-name = "cfb"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f"
-dependencies = [
- "byteorder",
- "fnv",
- "uuid",
-]
-
-[[package]]
-name = "cfg-expr"
-version = "0.15.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
-dependencies = [
- "smallvec",
- "target-lexicon",
-]
-
-[[package]]
-name = "cfg-if"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
-
-[[package]]
-name = "cfg_aliases"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
-
-[[package]]
-name = "chrono"
-version = "0.4.42"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
-dependencies = [
- "iana-time-zone",
- "js-sys",
- "num-traits",
- "serde",
- "wasm-bindgen",
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "cipher"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
-dependencies = [
- "crypto-common",
- "inout",
-]
-
-[[package]]
-name = "cocoa"
-version = "0.25.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c"
-dependencies = [
- "bitflags 1.3.2",
- "block",
- "cocoa-foundation",
- "core-foundation 0.9.4",
- "core-graphics 0.23.2",
- "foreign-types 0.5.0",
- "libc",
- "objc",
-]
-
-[[package]]
-name = "cocoa-foundation"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7"
-dependencies = [
- "bitflags 1.3.2",
- "block",
- "core-foundation 0.9.4",
- "core-graphics-types 0.1.3",
- "libc",
- "objc",
-]
-
-[[package]]
-name = "colorchoice"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
-
-[[package]]
-name = "combine"
-version = "4.6.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
-dependencies = [
- "bytes",
- "memchr",
-]
-
-[[package]]
-name = "compression-codecs"
-version = "0.4.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23"
-dependencies = [
- "compression-core",
- "flate2",
- "memchr",
-]
-
-[[package]]
-name = "compression-core"
-version = "0.4.29"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb"
-
-[[package]]
-name = "concurrent-queue"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
-dependencies = [
- "crossbeam-utils",
-]
-
-[[package]]
-name = "convert_case"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
-
-[[package]]
-name = "cookie"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
-dependencies = [
- "percent-encoding",
- "time",
- "version_check",
-]
-
-[[package]]
-name = "cookie_store"
-version = "0.21.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9"
-dependencies = [
- "cookie",
- "document-features",
- "idna",
- "log",
- "publicsuffix",
- "serde",
- "serde_derive",
- "serde_json",
- "time",
- "url",
-]
-
-[[package]]
-name = "core-foundation"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "core-foundation"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.8.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
-
-[[package]]
-name = "core-graphics"
-version = "0.23.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation 0.9.4",
- "core-graphics-types 0.1.3",
- "foreign-types 0.5.0",
- "libc",
-]
-
-[[package]]
-name = "core-graphics"
-version = "0.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1"
-dependencies = [
- "bitflags 2.10.0",
- "core-foundation 0.10.1",
- "core-graphics-types 0.2.0",
- "foreign-types 0.5.0",
- "libc",
-]
-
-[[package]]
-name = "core-graphics-types"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation 0.9.4",
- "libc",
-]
-
-[[package]]
-name = "core-graphics-types"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb"
-dependencies = [
- "bitflags 2.10.0",
- "core-foundation 0.10.1",
- "libc",
-]
-
-[[package]]
-name = "cpufeatures"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "crc32fast"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
-dependencies = [
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
-
-[[package]]
-name = "crypto-common"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
-dependencies = [
- "generic-array",
- "rand_core 0.6.4",
- "typenum",
-]
-
-[[package]]
-name = "cssparser"
-version = "0.29.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa"
-dependencies = [
- "cssparser-macros",
- "dtoa-short",
- "itoa",
- "matches",
- "phf 0.10.1",
- "proc-macro2",
- "quote",
- "smallvec",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "cssparser-macros"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
-dependencies = [
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "ctor"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501"
-dependencies = [
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "ctr"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
-dependencies = [
- "cipher",
-]
-
-[[package]]
-name = "curl"
-version = "0.4.47"
-source = "git+https://github.com/CuriousCorrelation/curl-rust.git#1ec8079cf527b9cf47cc7a48c68b458affdae273"
-dependencies = [
- "curl-sys",
- "libc",
- "openssl-probe",
- "openssl-sys",
- "socket2 0.5.10",
-]
-
-[[package]]
-name = "curl-sys"
-version = "0.4.77+curl-8.10.1"
-source = "git+https://github.com/CuriousCorrelation/curl-rust.git#1ec8079cf527b9cf47cc7a48c68b458affdae273"
-dependencies = [
- "cc",
- "libc",
- "libz-sys",
- "openssl-sys",
- "pkg-config",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "curve25519-dalek"
-version = "4.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "curve25519-dalek-derive",
- "fiat-crypto",
- "rustc_version",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "curve25519-dalek-derive"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "darling"
-version = "0.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
-dependencies = [
- "darling_core",
- "darling_macro",
-]
-
-[[package]]
-name = "darling_core"
-version = "0.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
-dependencies = [
- "fnv",
- "ident_case",
- "proc-macro2",
- "quote",
- "strsim",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "darling_macro"
-version = "0.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
-dependencies = [
- "darling_core",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "dashmap"
-version = "6.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
- "hashbrown 0.14.5",
- "lock_api",
- "once_cell",
- "parking_lot_core",
- "serde",
-]
-
-[[package]]
-name = "data-url"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376"
-
-[[package]]
-name = "deranged"
-version = "0.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587"
-dependencies = [
- "powerfmt",
- "serde_core",
-]
-
-[[package]]
-name = "derive_arbitrary"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "derive_more"
-version = "0.99.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f"
-dependencies = [
- "convert_case",
- "proc-macro2",
- "quote",
- "rustc_version",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "digest"
-version = "0.10.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
-dependencies = [
- "block-buffer",
- "crypto-common",
-]
-
-[[package]]
-name = "dirs"
-version = "4.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
-dependencies = [
- "dirs-sys 0.3.7",
-]
-
-[[package]]
-name = "dirs"
-version = "6.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
-dependencies = [
- "dirs-sys 0.5.0",
-]
-
-[[package]]
-name = "dirs-next"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
-dependencies = [
- "cfg-if",
- "dirs-sys-next",
-]
-
-[[package]]
-name = "dirs-sys"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
-dependencies = [
- "libc",
- "redox_users 0.4.6",
- "winapi",
-]
-
-[[package]]
-name = "dirs-sys"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
-dependencies = [
- "libc",
- "option-ext",
- "redox_users 0.5.2",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "dirs-sys-next"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
-dependencies = [
- "libc",
- "redox_users 0.4.6",
- "winapi",
-]
-
-[[package]]
-name = "dispatch"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
-
-[[package]]
-name = "dispatch2"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
-dependencies = [
- "bitflags 2.10.0",
- "block2 0.6.2",
- "libc",
- "objc2 0.6.3",
-]
-
-[[package]]
-name = "displaydoc"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "dlib"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
-dependencies = [
- "libloading 0.8.9",
-]
-
-[[package]]
-name = "dlopen2"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b54f373ccf864bf587a89e880fb7610f8d73f3045f13580948ccbcaff26febff"
-dependencies = [
- "dlopen2_derive",
- "libc",
- "once_cell",
- "winapi",
-]
-
-[[package]]
-name = "dlopen2_derive"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "788160fb30de9cdd857af31c6a2675904b16ece8fc2737b2c7127ba368c9d0f4"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "document-features"
-version = "0.2.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
-dependencies = [
- "litrs",
-]
-
-[[package]]
-name = "downcast-rs"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
-
-[[package]]
-name = "dpi"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "dtoa"
-version = "1.0.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04"
-
-[[package]]
-name = "dtoa-short"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87"
-dependencies = [
- "dtoa",
-]
-
-[[package]]
-name = "dunce"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
-
-[[package]]
-name = "dyn-clone"
-version = "1.0.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
-
-[[package]]
-name = "either"
-version = "1.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
-
-[[package]]
-name = "embed-resource"
-version = "3.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55a075fc573c64510038d7ee9abc7990635863992f83ebc52c8b433b8411a02e"
-dependencies = [
- "cc",
- "memchr",
- "rustc_version",
- "toml 0.9.8",
- "vswhom",
- "winreg 0.55.0",
-]
-
-[[package]]
-name = "embed_plist"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7"
-
-[[package]]
-name = "encoding_rs"
-version = "0.8.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "endi"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
-
-[[package]]
-name = "enumflags2"
-version = "0.7.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
-dependencies = [
- "enumflags2_derive",
- "serde",
-]
-
-[[package]]
-name = "enumflags2_derive"
-version = "0.7.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "env_filter"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2"
-dependencies = [
- "log",
- "regex",
-]
-
-[[package]]
-name = "env_logger"
-version = "0.11.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
-dependencies = [
- "anstream",
- "anstyle",
- "env_filter",
- "jiff",
- "log",
-]
-
-[[package]]
-name = "equivalent"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
-
-[[package]]
-name = "erased-serde"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "259d404d09818dec19332e31d94558aeb442fea04c817006456c24b5460bbd4b"
-dependencies = [
- "serde",
- "serde_core",
- "typeid",
-]
-
-[[package]]
-name = "errno"
-version = "0.3.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
-dependencies = [
- "libc",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "event-listener"
-version = "5.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
-dependencies = [
- "concurrent-queue",
- "parking",
- "pin-project-lite",
-]
-
-[[package]]
-name = "event-listener-strategy"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
-dependencies = [
- "event-listener",
- "pin-project-lite",
-]
-
-[[package]]
-name = "fastrand"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
-
-[[package]]
-name = "fdeflate"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
-dependencies = [
- "simd-adler32",
-]
-
-[[package]]
-name = "fiat-crypto"
-version = "0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
-
-[[package]]
-name = "field-offset"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
-dependencies = [
- "memoffset",
- "rustc_version",
-]
-
-[[package]]
-name = "file-rotate"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e8e2fa049328a1f3295991407a88585805d126dfaadf74b9fe8c194c730aafc"
-dependencies = [
- "chrono",
- "flate2",
-]
-
-[[package]]
-name = "filetime"
-version = "0.2.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed"
-dependencies = [
- "cfg-if",
- "libc",
- "libredox",
- "windows-sys 0.60.2",
-]
-
-[[package]]
-name = "find-msvc-tools"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
-
-[[package]]
-name = "flate2"
-version = "1.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb"
-dependencies = [
- "crc32fast",
- "miniz_oxide",
-]
-
-[[package]]
-name = "fnv"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-
-[[package]]
-name = "foreign-types"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
-dependencies = [
- "foreign-types-shared 0.1.1",
-]
-
-[[package]]
-name = "foreign-types"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
-dependencies = [
- "foreign-types-macros",
- "foreign-types-shared 0.3.1",
-]
-
-[[package]]
-name = "foreign-types-macros"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
-
-[[package]]
-name = "form_urlencoded"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
-dependencies = [
- "percent-encoding",
-]
-
-[[package]]
-name = "futf"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843"
-dependencies = [
- "mac",
- "new_debug_unreachable",
-]
-
-[[package]]
-name = "futures-channel"
-version = "0.3.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
-dependencies = [
- "futures-core",
-]
-
-[[package]]
-name = "futures-core"
-version = "0.3.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
-
-[[package]]
-name = "futures-executor"
-version = "0.3.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
-
-[[package]]
-name = "futures-lite"
-version = "2.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
-dependencies = [
- "fastrand",
- "futures-core",
- "futures-io",
- "parking",
- "pin-project-lite",
-]
-
-[[package]]
-name = "futures-macro"
-version = "0.3.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "futures-sink"
-version = "0.3.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
-
-[[package]]
-name = "futures-task"
-version = "0.3.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
-
-[[package]]
-name = "futures-util"
-version = "0.3.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
-dependencies = [
- "futures-core",
- "futures-io",
- "futures-macro",
- "futures-sink",
- "futures-task",
- "memchr",
- "pin-project-lite",
- "pin-utils",
- "slab",
-]
-
-[[package]]
-name = "fxhash"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
-dependencies = [
- "byteorder",
-]
-
-[[package]]
-name = "gdk"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691"
-dependencies = [
- "cairo-rs",
- "gdk-pixbuf",
- "gdk-sys",
- "gio",
- "glib",
- "libc",
- "pango",
-]
-
-[[package]]
-name = "gdk-pixbuf"
-version = "0.18.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec"
-dependencies = [
- "gdk-pixbuf-sys",
- "gio",
- "glib",
- "libc",
- "once_cell",
-]
-
-[[package]]
-name = "gdk-pixbuf-sys"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7"
-dependencies = [
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "gdk-sys"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7"
-dependencies = [
- "cairo-sys-rs",
- "gdk-pixbuf-sys",
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "pango-sys",
- "pkg-config",
- "system-deps",
-]
-
-[[package]]
-name = "gdkwayland-sys"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69"
-dependencies = [
- "gdk-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "pkg-config",
- "system-deps",
-]
-
-[[package]]
-name = "gdkx11"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe"
-dependencies = [
- "gdk",
- "gdkx11-sys",
- "gio",
- "glib",
- "libc",
- "x11",
-]
-
-[[package]]
-name = "gdkx11-sys"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d"
-dependencies = [
- "gdk-sys",
- "glib-sys",
- "libc",
- "system-deps",
- "x11",
-]
-
-[[package]]
-name = "generic-array"
-version = "0.14.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
-dependencies = [
- "typenum",
- "version_check",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.1.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
-dependencies = [
- "cfg-if",
- "libc",
- "wasi 0.9.0+wasi-snapshot-preview1",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
-dependencies = [
- "cfg-if",
- "js-sys",
- "libc",
- "wasi 0.11.1+wasi-snapshot-preview1",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
-dependencies = [
- "cfg-if",
- "js-sys",
- "libc",
- "r-efi",
- "wasip2",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "ghash"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
-dependencies = [
- "opaque-debug",
- "polyval",
-]
-
-[[package]]
-name = "gio"
-version = "0.18.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-util",
- "gio-sys",
- "glib",
- "libc",
- "once_cell",
- "pin-project-lite",
- "smallvec",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "gio-sys"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2"
-dependencies = [
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
- "winapi",
-]
-
-[[package]]
-name = "glib"
-version = "0.18.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5"
-dependencies = [
- "bitflags 2.10.0",
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-task",
- "futures-util",
- "gio-sys",
- "glib-macros",
- "glib-sys",
- "gobject-sys",
- "libc",
- "memchr",
- "once_cell",
- "smallvec",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "glib-macros"
-version = "0.18.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc"
-dependencies = [
- "heck 0.4.1",
- "proc-macro-crate 2.0.2",
- "proc-macro-error",
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "glib-sys"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898"
-dependencies = [
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "glob"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
-
-[[package]]
-name = "gobject-sys"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44"
-dependencies = [
- "glib-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "gtk"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a"
-dependencies = [
- "atk",
- "cairo-rs",
- "field-offset",
- "futures-channel",
- "gdk",
- "gdk-pixbuf",
- "gio",
- "glib",
- "gtk-sys",
- "gtk3-macros",
- "libc",
- "pango",
- "pkg-config",
-]
-
-[[package]]
-name = "gtk-sys"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414"
-dependencies = [
- "atk-sys",
- "cairo-sys-rs",
- "gdk-pixbuf-sys",
- "gdk-sys",
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "pango-sys",
- "system-deps",
-]
-
-[[package]]
-name = "gtk3-macros"
-version = "0.18.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d"
-dependencies = [
- "proc-macro-crate 1.3.1",
- "proc-macro-error",
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "h2"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
-dependencies = [
- "atomic-waker",
- "bytes",
- "fnv",
- "futures-core",
- "futures-sink",
- "http",
- "indexmap 2.12.0",
- "slab",
- "tokio",
- "tokio-util",
- "tracing",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "hashbrown"
-version = "0.14.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
-
-[[package]]
-name = "hashbrown"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
-
-[[package]]
-name = "headers"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
-dependencies = [
- "base64 0.22.1",
- "bytes",
- "headers-core",
- "http",
- "httpdate",
- "mime",
- "sha1",
-]
-
-[[package]]
-name = "headers-core"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
-dependencies = [
- "http",
-]
-
-[[package]]
-name = "heck"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
-
-[[package]]
-name = "heck"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
-
-[[package]]
-name = "hermit-abi"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
-
-[[package]]
-name = "hex"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
-
-[[package]]
-name = "home"
-version = "0.5.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
-dependencies = [
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "hoppscotch-agent"
-version = "0.1.17"
-dependencies = [
- "aes-gcm",
- "axum",
- "axum-extra",
- "base16",
- "chrono",
- "dashmap",
- "dirs 6.0.0",
- "file-rotate",
- "lazy_static",
- "native-dialog",
- "rand 0.8.5",
- "relay",
- "serde",
- "serde_json",
- "sha2",
- "tauri",
- "tauri-build",
- "tauri-plugin-autostart",
- "tauri-plugin-dialog",
- "tauri-plugin-http",
- "tauri-plugin-shell",
- "tauri-plugin-single-instance",
- "tauri-plugin-store",
- "tauri-plugin-updater",
- "tempfile",
- "thiserror 1.0.69",
- "tokio",
- "tokio-util",
- "tower-http",
- "tracing",
- "tracing-appender",
- "tracing-subscriber",
- "uuid",
- "winreg 0.52.0",
- "x25519-dalek",
-]
-
-[[package]]
-name = "html5ever"
-version = "0.29.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c"
-dependencies = [
- "log",
- "mac",
- "markup5ever",
- "match_token",
-]
-
-[[package]]
-name = "http"
-version = "1.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
-dependencies = [
- "bytes",
- "fnv",
- "itoa",
-]
-
-[[package]]
-name = "http-body"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
-dependencies = [
- "bytes",
- "http",
-]
-
-[[package]]
-name = "http-body-util"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
-dependencies = [
- "bytes",
- "futures-core",
- "http",
- "http-body",
- "pin-project-lite",
-]
-
-[[package]]
-name = "http-serde"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f056c8559e3757392c8d091e796416e4649d8e49e88b8d76df6c002f05027fd"
-dependencies = [
- "http",
- "serde",
-]
-
-[[package]]
-name = "httparse"
-version = "1.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
-
-[[package]]
-name = "httpdate"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
-
-[[package]]
-name = "hyper"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e"
-dependencies = [
- "atomic-waker",
- "bytes",
- "futures-channel",
- "futures-core",
- "h2",
- "http",
- "http-body",
- "httparse",
- "httpdate",
- "itoa",
- "pin-project-lite",
- "pin-utils",
- "smallvec",
- "tokio",
- "want",
-]
-
-[[package]]
-name = "hyper-rustls"
-version = "0.27.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
-dependencies = [
- "http",
- "hyper",
- "hyper-util",
- "rustls",
- "rustls-pki-types",
- "tokio",
- "tokio-rustls",
- "tower-service",
- "webpki-roots",
-]
-
-[[package]]
-name = "hyper-util"
-version = "0.1.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
-dependencies = [
- "base64 0.22.1",
- "bytes",
- "futures-channel",
- "futures-core",
- "futures-util",
- "http",
- "http-body",
- "hyper",
- "ipnet",
- "libc",
- "percent-encoding",
- "pin-project-lite",
- "socket2 0.6.1",
- "system-configuration",
- "tokio",
- "tower-service",
- "tracing",
- "windows-registry",
-]
-
-[[package]]
-name = "iana-time-zone"
-version = "0.1.64"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
-dependencies = [
- "android_system_properties",
- "core-foundation-sys",
- "iana-time-zone-haiku",
- "js-sys",
- "log",
- "wasm-bindgen",
- "windows-core 0.62.2",
-]
-
-[[package]]
-name = "iana-time-zone-haiku"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "ico"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98"
-dependencies = [
- "byteorder",
- "png 0.17.16",
-]
-
-[[package]]
-name = "icu_collections"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43"
-dependencies = [
- "displaydoc",
- "potential_utf",
- "yoke",
- "zerofrom",
- "zerovec",
-]
-
-[[package]]
-name = "icu_locale_core"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6"
-dependencies = [
- "displaydoc",
- "litemap",
- "tinystr",
- "writeable",
- "zerovec",
-]
-
-[[package]]
-name = "icu_normalizer"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599"
-dependencies = [
- "icu_collections",
- "icu_normalizer_data",
- "icu_properties",
- "icu_provider",
- "smallvec",
- "zerovec",
-]
-
-[[package]]
-name = "icu_normalizer_data"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"
-
-[[package]]
-name = "icu_properties"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99"
-dependencies = [
- "icu_collections",
- "icu_locale_core",
- "icu_properties_data",
- "icu_provider",
- "zerotrie",
- "zerovec",
-]
-
-[[package]]
-name = "icu_properties_data"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899"
-
-[[package]]
-name = "icu_provider"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614"
-dependencies = [
- "displaydoc",
- "icu_locale_core",
- "writeable",
- "yoke",
- "zerofrom",
- "zerotrie",
- "zerovec",
-]
-
-[[package]]
-name = "ident_case"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
-
-[[package]]
-name = "idna"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
-dependencies = [
- "idna_adapter",
- "smallvec",
- "utf8_iter",
-]
-
-[[package]]
-name = "idna_adapter"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
-dependencies = [
- "icu_normalizer",
- "icu_properties",
-]
-
-[[package]]
-name = "image"
-version = "0.25.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7"
-dependencies = [
- "bytemuck",
- "byteorder-lite",
- "moxcms",
- "num-traits",
- "png 0.18.0",
-]
-
-[[package]]
-name = "indexmap"
-version = "1.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
-dependencies = [
- "autocfg",
- "hashbrown 0.12.3",
- "serde",
-]
-
-[[package]]
-name = "indexmap"
-version = "2.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
-dependencies = [
- "equivalent",
- "hashbrown 0.16.0",
- "serde",
- "serde_core",
-]
-
-[[package]]
-name = "infer"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc150e5ce2330295b8616ce0e3f53250e53af31759a9dbedad1621ba29151847"
-dependencies = [
- "cfb",
-]
-
-[[package]]
-name = "infer"
-version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7"
-dependencies = [
- "cfb",
-]
-
-[[package]]
-name = "inout"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
-name = "ipnet"
-version = "2.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
-
-[[package]]
-name = "iri-string"
-version = "0.7.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
-dependencies = [
- "memchr",
- "serde",
-]
-
-[[package]]
-name = "is-docker"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3"
-dependencies = [
- "once_cell",
-]
-
-[[package]]
-name = "is-wsl"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5"
-dependencies = [
- "is-docker",
- "once_cell",
-]
-
-[[package]]
-name = "is_terminal_polyfill"
-version = "1.70.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
-
-[[package]]
-name = "itertools"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
-dependencies = [
- "either",
-]
-
-[[package]]
-name = "itoa"
-version = "1.0.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
-
-[[package]]
-name = "javascriptcore-rs"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc"
-dependencies = [
- "bitflags 1.3.2",
- "glib",
- "javascriptcore-rs-sys",
-]
-
-[[package]]
-name = "javascriptcore-rs-sys"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124"
-dependencies = [
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "jiff"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
-dependencies = [
- "jiff-static",
- "log",
- "portable-atomic",
- "portable-atomic-util",
- "serde",
-]
-
-[[package]]
-name = "jiff-static"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "jni"
-version = "0.21.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
-dependencies = [
- "cesu8",
- "cfg-if",
- "combine",
- "jni-sys",
- "log",
- "thiserror 1.0.69",
- "walkdir",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "jni-sys"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
-
-[[package]]
-name = "js-sys"
-version = "0.3.82"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65"
-dependencies = [
- "once_cell",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "json-patch"
-version = "3.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08"
-dependencies = [
- "jsonptr",
- "serde",
- "serde_json",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "jsonptr"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70"
-dependencies = [
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "keyboard-types"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a"
-dependencies = [
- "bitflags 2.10.0",
- "serde",
- "unicode-segmentation",
-]
-
-[[package]]
-name = "kuchikiki"
-version = "0.8.8-speedreader"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2"
-dependencies = [
- "cssparser",
- "html5ever",
- "indexmap 2.12.0",
- "selectors",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
-
-[[package]]
-name = "libappindicator"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a"
-dependencies = [
- "glib",
- "gtk",
- "gtk-sys",
- "libappindicator-sys",
- "log",
-]
-
-[[package]]
-name = "libappindicator-sys"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf"
-dependencies = [
- "gtk-sys",
- "libloading 0.7.4",
- "once_cell",
-]
-
-[[package]]
-name = "libc"
-version = "0.2.177"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
-
-[[package]]
-name = "libloading"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
-dependencies = [
- "cfg-if",
- "winapi",
-]
-
-[[package]]
-name = "libloading"
-version = "0.8.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
-dependencies = [
- "cfg-if",
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "libredox"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
-dependencies = [
- "bitflags 2.10.0",
- "libc",
- "redox_syscall",
-]
-
-[[package]]
-name = "libz-sys"
-version = "1.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d"
-dependencies = [
- "cc",
- "libc",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.4.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
-
-[[package]]
-name = "litemap"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"
-
-[[package]]
-name = "litrs"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
-
-[[package]]
-name = "lock_api"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
-dependencies = [
- "scopeguard",
-]
-
-[[package]]
-name = "log"
-version = "0.4.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
-
-[[package]]
-name = "lru-slab"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
-
-[[package]]
-name = "mac"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
-
-[[package]]
-name = "malloc_buf"
-version = "0.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "markup5ever"
-version = "0.14.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18"
-dependencies = [
- "log",
- "phf 0.11.3",
- "phf_codegen 0.11.3",
- "string_cache",
- "string_cache_codegen",
- "tendril",
-]
-
-[[package]]
-name = "match_token"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "matchers"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
-dependencies = [
- "regex-automata",
-]
-
-[[package]]
-name = "matches"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
-
-[[package]]
-name = "matchit"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
-
-[[package]]
-name = "memchr"
-version = "2.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
-
-[[package]]
-name = "memoffset"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "mime"
-version = "0.3.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
-
-[[package]]
-name = "minimal-lexical"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-
-[[package]]
-name = "minisign-verify"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e856fdd13623a2f5f2f54676a4ee49502a96a80ef4a62bcedd23d52427c44d43"
-
-[[package]]
-name = "miniz_oxide"
-version = "0.8.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
-dependencies = [
- "adler2",
- "simd-adler32",
-]
-
-[[package]]
-name = "mio"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873"
-dependencies = [
- "libc",
- "wasi 0.11.1+wasi-snapshot-preview1",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "moxcms"
-version = "0.7.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fbdd3d7436f8b5e892b8b7ea114271ff0fa00bc5acae845d53b07d498616ef6"
-dependencies = [
- "num-traits",
- "pxfm",
-]
-
-[[package]]
-name = "muda"
-version = "0.17.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a"
-dependencies = [
- "crossbeam-channel",
- "dpi",
- "gtk",
- "keyboard-types",
- "objc2 0.6.3",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-foundation 0.3.2",
- "once_cell",
- "png 0.17.16",
- "serde",
- "thiserror 2.0.17",
- "windows-sys 0.60.2",
-]
-
-[[package]]
-name = "multer"
-version = "3.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b"
-dependencies = [
- "bytes",
- "encoding_rs",
- "futures-util",
- "http",
- "httparse",
- "memchr",
- "mime",
- "spin",
- "version_check",
-]
-
-[[package]]
-name = "native-dialog"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84e7038885d2aeab236bd60da9e159a5967b47cde3292da3b15ff1bec27c039f"
-dependencies = [
- "ascii",
- "block",
- "cocoa",
- "core-foundation 0.9.4",
- "dirs-next",
- "objc",
- "objc-foundation",
- "objc_id",
- "once_cell",
- "raw-window-handle 0.5.2",
- "thiserror 1.0.69",
- "versions",
- "wfd",
- "which",
- "winapi",
-]
-
-[[package]]
-name = "ndk"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4"
-dependencies = [
- "bitflags 2.10.0",
- "jni-sys",
- "log",
- "ndk-sys",
- "num_enum",
- "raw-window-handle 0.6.2",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "ndk-context"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
-
-[[package]]
-name = "ndk-sys"
-version = "0.6.0+11769913"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873"
-dependencies = [
- "jni-sys",
-]
-
-[[package]]
-name = "new_debug_unreachable"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
-
-[[package]]
-name = "nix"
-version = "0.30.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
-dependencies = [
- "bitflags 2.10.0",
- "cfg-if",
- "cfg_aliases",
- "libc",
- "memoffset",
-]
-
-[[package]]
-name = "nodrop"
-version = "0.1.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
-
-[[package]]
-name = "nom"
-version = "7.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
-dependencies = [
- "memchr",
- "minimal-lexical",
-]
-
-[[package]]
-name = "nu-ansi-term"
-version = "0.50.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
-dependencies = [
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "num-conv"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
-
-[[package]]
-name = "num-traits"
-version = "0.2.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num_enum"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c"
-dependencies = [
- "num_enum_derive",
- "rustversion",
-]
-
-[[package]]
-name = "num_enum_derive"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7"
-dependencies = [
- "proc-macro-crate 3.4.0",
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "objc"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
-dependencies = [
- "malloc_buf",
-]
-
-[[package]]
-name = "objc-foundation"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
-dependencies = [
- "block",
- "objc",
- "objc_id",
-]
-
-[[package]]
-name = "objc-sys"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
-
-[[package]]
-name = "objc2"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
-dependencies = [
- "objc-sys",
- "objc2-encode",
-]
-
-[[package]]
-name = "objc2"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05"
-dependencies = [
- "objc2-encode",
- "objc2-exception-helper",
-]
-
-[[package]]
-name = "objc2-app-kit"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c"
-dependencies = [
- "bitflags 2.10.0",
- "block2 0.6.2",
- "libc",
- "objc2 0.6.3",
- "objc2-cloud-kit",
- "objc2-core-data",
- "objc2-core-foundation",
- "objc2-core-graphics",
- "objc2-core-image",
- "objc2-core-text",
- "objc2-core-video",
- "objc2-foundation 0.3.2",
- "objc2-quartz-core 0.3.2",
-]
-
-[[package]]
-name = "objc2-cloud-kit"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c"
-dependencies = [
- "bitflags 2.10.0",
- "objc2 0.6.3",
- "objc2-foundation 0.3.2",
-]
-
-[[package]]
-name = "objc2-core-data"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa"
-dependencies = [
- "bitflags 2.10.0",
- "objc2 0.6.3",
- "objc2-foundation 0.3.2",
-]
-
-[[package]]
-name = "objc2-core-foundation"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
-dependencies = [
- "bitflags 2.10.0",
- "dispatch2",
- "objc2 0.6.3",
-]
-
-[[package]]
-name = "objc2-core-graphics"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807"
-dependencies = [
- "bitflags 2.10.0",
- "dispatch2",
- "objc2 0.6.3",
- "objc2-core-foundation",
- "objc2-io-surface",
-]
-
-[[package]]
-name = "objc2-core-image"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006"
-dependencies = [
- "objc2 0.6.3",
- "objc2-foundation 0.3.2",
-]
-
-[[package]]
-name = "objc2-core-text"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
-dependencies = [
- "bitflags 2.10.0",
- "objc2 0.6.3",
- "objc2-core-foundation",
- "objc2-core-graphics",
-]
-
-[[package]]
-name = "objc2-core-video"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6"
-dependencies = [
- "bitflags 2.10.0",
- "objc2 0.6.3",
- "objc2-core-foundation",
- "objc2-core-graphics",
- "objc2-io-surface",
-]
-
-[[package]]
-name = "objc2-encode"
-version = "4.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
-
-[[package]]
-name = "objc2-exception-helper"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "objc2-foundation"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
-dependencies = [
- "bitflags 2.10.0",
- "block2 0.5.1",
- "libc",
- "objc2 0.5.2",
-]
-
-[[package]]
-name = "objc2-foundation"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
-dependencies = [
- "bitflags 2.10.0",
- "block2 0.6.2",
- "libc",
- "objc2 0.6.3",
- "objc2-core-foundation",
-]
-
-[[package]]
-name = "objc2-io-surface"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d"
-dependencies = [
- "bitflags 2.10.0",
- "objc2 0.6.3",
- "objc2-core-foundation",
-]
-
-[[package]]
-name = "objc2-javascript-core"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a1e6550c4caed348956ce3370c9ffeca70bb1dbed4fa96112e7c6170e074586"
-dependencies = [
- "objc2 0.6.3",
- "objc2-core-foundation",
-]
-
-[[package]]
-name = "objc2-metal"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
-dependencies = [
- "bitflags 2.10.0",
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-foundation 0.2.2",
-]
-
-[[package]]
-name = "objc2-osa-kit"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f112d1746737b0da274ef79a23aac283376f335f4095a083a267a082f21db0c0"
-dependencies = [
- "bitflags 2.10.0",
- "objc2 0.6.3",
- "objc2-app-kit",
- "objc2-foundation 0.3.2",
-]
-
-[[package]]
-name = "objc2-quartz-core"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
-dependencies = [
- "bitflags 2.10.0",
- "block2 0.5.1",
- "objc2 0.5.2",
- "objc2-foundation 0.2.2",
- "objc2-metal",
-]
-
-[[package]]
-name = "objc2-quartz-core"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
-dependencies = [
- "bitflags 2.10.0",
- "objc2 0.6.3",
- "objc2-foundation 0.3.2",
-]
-
-[[package]]
-name = "objc2-security"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a"
-dependencies = [
- "bitflags 2.10.0",
- "objc2 0.6.3",
- "objc2-core-foundation",
-]
-
-[[package]]
-name = "objc2-ui-kit"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
-dependencies = [
- "bitflags 2.10.0",
- "objc2 0.6.3",
- "objc2-core-foundation",
- "objc2-foundation 0.3.2",
-]
-
-[[package]]
-name = "objc2-web-kit"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f"
-dependencies = [
- "bitflags 2.10.0",
- "block2 0.6.2",
- "objc2 0.6.3",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-foundation 0.3.2",
- "objc2-javascript-core",
- "objc2-security",
-]
-
-[[package]]
-name = "objc_id"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
-dependencies = [
- "objc",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
-
-[[package]]
-name = "once_cell_polyfill"
-version = "1.70.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
-
-[[package]]
-name = "opaque-debug"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
-
-[[package]]
-name = "open"
-version = "5.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95"
-dependencies = [
- "dunce",
- "is-wsl",
- "libc",
- "pathdiff",
-]
-
-[[package]]
-name = "openssl"
-version = "0.10.74"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654"
-dependencies = [
- "bitflags 2.10.0",
- "cfg-if",
- "foreign-types 0.3.2",
- "libc",
- "once_cell",
- "openssl-macros",
- "openssl-sys",
-]
-
-[[package]]
-name = "openssl-macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "openssl-probe"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
-
-[[package]]
-name = "openssl-src"
-version = "300.5.4+3.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "openssl-sys"
-version = "0.9.110"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2"
-dependencies = [
- "cc",
- "libc",
- "openssl-src",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
-name = "option-ext"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
-
-[[package]]
-name = "ordered-stream"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
-dependencies = [
- "futures-core",
- "pin-project-lite",
-]
-
-[[package]]
-name = "os_pipe"
-version = "1.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
-dependencies = [
- "libc",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "osakit"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b"
-dependencies = [
- "objc2 0.6.3",
- "objc2-foundation 0.3.2",
- "objc2-osa-kit",
- "serde",
- "serde_json",
- "thiserror 2.0.17",
-]
-
-[[package]]
-name = "pango"
-version = "0.18.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4"
-dependencies = [
- "gio",
- "glib",
- "libc",
- "once_cell",
- "pango-sys",
-]
-
-[[package]]
-name = "pango-sys"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5"
-dependencies = [
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "parking"
-version = "2.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
-
-[[package]]
-name = "parking_lot"
-version = "0.12.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
-dependencies = [
- "lock_api",
- "parking_lot_core",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.9.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
-dependencies = [
- "cfg-if",
- "libc",
- "redox_syscall",
- "smallvec",
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "pathdiff"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
-
-[[package]]
-name = "percent-encoding"
-version = "2.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
-
-[[package]]
-name = "phf"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
-dependencies = [
- "phf_shared 0.8.0",
-]
-
-[[package]]
-name = "phf"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259"
-dependencies = [
- "phf_macros 0.10.0",
- "phf_shared 0.10.0",
- "proc-macro-hack",
-]
-
-[[package]]
-name = "phf"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
-dependencies = [
- "phf_macros 0.11.3",
- "phf_shared 0.11.3",
-]
-
-[[package]]
-name = "phf_codegen"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815"
-dependencies = [
- "phf_generator 0.8.0",
- "phf_shared 0.8.0",
-]
-
-[[package]]
-name = "phf_codegen"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
-dependencies = [
- "phf_generator 0.11.3",
- "phf_shared 0.11.3",
-]
-
-[[package]]
-name = "phf_generator"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
-dependencies = [
- "phf_shared 0.8.0",
- "rand 0.7.3",
-]
-
-[[package]]
-name = "phf_generator"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
-dependencies = [
- "phf_shared 0.10.0",
- "rand 0.8.5",
-]
-
-[[package]]
-name = "phf_generator"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
-dependencies = [
- "phf_shared 0.11.3",
- "rand 0.8.5",
-]
-
-[[package]]
-name = "phf_macros"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0"
-dependencies = [
- "phf_generator 0.10.0",
- "phf_shared 0.10.0",
- "proc-macro-hack",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "phf_macros"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
-dependencies = [
- "phf_generator 0.11.3",
- "phf_shared 0.11.3",
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "phf_shared"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
-dependencies = [
- "siphasher 0.3.11",
-]
-
-[[package]]
-name = "phf_shared"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
-dependencies = [
- "siphasher 0.3.11",
-]
-
-[[package]]
-name = "phf_shared"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
-dependencies = [
- "siphasher 1.0.1",
-]
-
-[[package]]
-name = "pin-project-lite"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
-
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
-name = "piper"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
-dependencies = [
- "atomic-waker",
- "fastrand",
- "futures-io",
-]
-
-[[package]]
-name = "pkg-config"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
-
-[[package]]
-name = "plist"
-version = "1.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07"
-dependencies = [
- "base64 0.22.1",
- "indexmap 2.12.0",
- "quick-xml 0.38.3",
- "serde",
- "time",
-]
-
-[[package]]
-name = "png"
-version = "0.17.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
-dependencies = [
- "bitflags 1.3.2",
- "crc32fast",
- "fdeflate",
- "flate2",
- "miniz_oxide",
-]
-
-[[package]]
-name = "png"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0"
-dependencies = [
- "bitflags 2.10.0",
- "crc32fast",
- "fdeflate",
- "flate2",
- "miniz_oxide",
-]
-
-[[package]]
-name = "polling"
-version = "3.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
-dependencies = [
- "cfg-if",
- "concurrent-queue",
- "hermit-abi",
- "pin-project-lite",
- "rustix 1.1.2",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "polyval"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "opaque-debug",
- "universal-hash",
-]
-
-[[package]]
-name = "portable-atomic"
-version = "1.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
-
-[[package]]
-name = "portable-atomic-util"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
-dependencies = [
- "portable-atomic",
-]
-
-[[package]]
-name = "potential_utf"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
-dependencies = [
- "zerovec",
-]
-
-[[package]]
-name = "powerfmt"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
-dependencies = [
- "zerocopy",
-]
-
-[[package]]
-name = "precomputed-hash"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
-
-[[package]]
-name = "proc-macro-crate"
-version = "1.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
-dependencies = [
- "once_cell",
- "toml_edit 0.19.15",
-]
-
-[[package]]
-name = "proc-macro-crate"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24"
-dependencies = [
- "toml_datetime 0.6.3",
- "toml_edit 0.20.2",
-]
-
-[[package]]
-name = "proc-macro-crate"
-version = "3.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
-dependencies = [
- "toml_edit 0.23.7",
-]
-
-[[package]]
-name = "proc-macro-error"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
-dependencies = [
- "proc-macro-error-attr",
- "proc-macro2",
- "quote",
- "syn 1.0.109",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-error-attr"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
-dependencies = [
- "proc-macro2",
- "quote",
- "version_check",
-]
-
-[[package]]
-name = "proc-macro-hack"
-version = "0.5.20+deprecated"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.103"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "psl-types"
-version = "2.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
-
-[[package]]
-name = "publicsuffix"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf"
-dependencies = [
- "idna",
- "psl-types",
-]
-
-[[package]]
-name = "pxfm"
-version = "0.1.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3cbdf373972bf78df4d3b518d07003938e2c7d1fb5891e55f9cb6df57009d84"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "quick-xml"
-version = "0.37.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "quick-xml"
-version = "0.38.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "quinn"
-version = "0.11.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
-dependencies = [
- "bytes",
- "cfg_aliases",
- "pin-project-lite",
- "quinn-proto",
- "quinn-udp",
- "rustc-hash",
- "rustls",
- "socket2 0.6.1",
- "thiserror 2.0.17",
- "tokio",
- "tracing",
- "web-time",
-]
-
-[[package]]
-name = "quinn-proto"
-version = "0.11.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
-dependencies = [
- "bytes",
- "getrandom 0.3.4",
- "lru-slab",
- "rand 0.9.2",
- "ring",
- "rustc-hash",
- "rustls",
- "rustls-pki-types",
- "slab",
- "thiserror 2.0.17",
- "tinyvec",
- "tracing",
- "web-time",
-]
-
-[[package]]
-name = "quinn-udp"
-version = "0.5.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
-dependencies = [
- "cfg_aliases",
- "libc",
- "once_cell",
- "socket2 0.6.1",
- "tracing",
- "windows-sys 0.60.2",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.41"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "r-efi"
-version = "5.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
-
-[[package]]
-name = "rand"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
-dependencies = [
- "getrandom 0.1.16",
- "libc",
- "rand_chacha 0.2.2",
- "rand_core 0.5.1",
- "rand_hc",
- "rand_pcg",
-]
-
-[[package]]
-name = "rand"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
-dependencies = [
- "libc",
- "rand_chacha 0.3.1",
- "rand_core 0.6.4",
-]
-
-[[package]]
-name = "rand"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
-dependencies = [
- "rand_chacha 0.9.0",
- "rand_core 0.9.3",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.6.4",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.9.3",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
-dependencies = [
- "getrandom 0.1.16",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
-dependencies = [
- "getrandom 0.2.16",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
-dependencies = [
- "getrandom 0.3.4",
-]
-
-[[package]]
-name = "rand_hc"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
-dependencies = [
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "rand_pcg"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
-dependencies = [
- "rand_core 0.5.1",
-]
-
-[[package]]
-name = "raw-window-handle"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
-
-[[package]]
-name = "raw-window-handle"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
-
-[[package]]
-name = "redox_syscall"
-version = "0.5.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
-dependencies = [
- "bitflags 2.10.0",
-]
-
-[[package]]
-name = "redox_users"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
-dependencies = [
- "getrandom 0.2.16",
- "libredox",
- "thiserror 1.0.69",
-]
-
-[[package]]
-name = "redox_users"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
-dependencies = [
- "getrandom 0.2.16",
- "libredox",
- "thiserror 2.0.17",
-]
-
-[[package]]
-name = "ref-cast"
-version = "1.0.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
-dependencies = [
- "ref-cast-impl",
-]
-
-[[package]]
-name = "ref-cast-impl"
-version = "1.0.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "regex"
-version = "1.12.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-automata",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.4.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.8.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
-
-[[package]]
-name = "relay"
-version = "0.1.1"
-source = "git+https://github.com/CuriousCorrelation/relay.git#ed2329e4ebb71bb984c4705aa950cb9c3f9ff931"
-dependencies = [
- "bytes",
- "curl",
- "dashmap",
- "env_logger",
- "http",
- "http-serde",
- "infer 0.16.0",
- "lazy_static",
- "log",
- "mime",
- "openssl",
- "openssl-sys",
- "serde",
- "serde_json",
- "strum",
- "thiserror 1.0.69",
- "time",
- "tokio-util",
- "tracing",
- "url",
- "url-escape",
- "urlencoding",
-]
-
-[[package]]
-name = "reqwest"
-version = "0.12.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f"
-dependencies = [
- "async-compression",
- "base64 0.22.1",
- "bytes",
- "cookie",
- "cookie_store",
- "encoding_rs",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "http-body-util",
- "hyper",
- "hyper-rustls",
- "hyper-util",
- "js-sys",
- "log",
- "mime",
- "percent-encoding",
- "pin-project-lite",
- "quinn",
- "rustls",
- "rustls-pki-types",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sync_wrapper",
- "tokio",
- "tokio-rustls",
- "tokio-util",
- "tower",
- "tower-http",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "wasm-streams",
- "web-sys",
- "webpki-roots",
-]
-
-[[package]]
-name = "rfd"
-version = "0.15.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed"
-dependencies = [
- "ashpd",
- "block2 0.6.2",
- "dispatch2",
- "glib-sys",
- "gobject-sys",
- "gtk-sys",
- "js-sys",
- "log",
- "objc2 0.6.3",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-foundation 0.3.2",
- "raw-window-handle 0.6.2",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "ring"
-version = "0.17.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
-dependencies = [
- "cc",
- "cfg-if",
- "getrandom 0.2.16",
- "libc",
- "untrusted",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "rustc-hash"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
-
-[[package]]
-name = "rustc_version"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
-dependencies = [
- "semver",
-]
-
-[[package]]
-name = "rustix"
-version = "0.38.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
-dependencies = [
- "bitflags 2.10.0",
- "errno",
- "libc",
- "linux-raw-sys 0.4.15",
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "rustix"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
-dependencies = [
- "bitflags 2.10.0",
- "errno",
- "libc",
- "linux-raw-sys 0.11.0",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "rustls"
-version = "0.23.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7"
-dependencies = [
- "once_cell",
- "ring",
- "rustls-pki-types",
- "rustls-webpki",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "rustls-pki-types"
-version = "1.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a"
-dependencies = [
- "web-time",
- "zeroize",
-]
-
-[[package]]
-name = "rustls-webpki"
-version = "0.103.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52"
-dependencies = [
- "ring",
- "rustls-pki-types",
- "untrusted",
-]
-
-[[package]]
-name = "rustversion"
-version = "1.0.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
-
-[[package]]
-name = "ryu"
-version = "1.0.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
-
-[[package]]
-name = "same-file"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "schemars"
-version = "0.8.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615"
-dependencies = [
- "dyn-clone",
- "indexmap 1.9.3",
- "schemars_derive",
- "serde",
- "serde_json",
- "url",
- "uuid",
-]
-
-[[package]]
-name = "schemars"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f"
-dependencies = [
- "dyn-clone",
- "ref-cast",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "schemars"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0"
-dependencies = [
- "dyn-clone",
- "ref-cast",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "schemars_derive"
-version = "0.8.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d"
-dependencies = [
- "proc-macro2",
- "quote",
- "serde_derive_internals",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "scoped-tls"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
-
-[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
-[[package]]
-name = "selectors"
-version = "0.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416"
-dependencies = [
- "bitflags 1.3.2",
- "cssparser",
- "derive_more",
- "fxhash",
- "log",
- "phf 0.8.0",
- "phf_codegen 0.8.0",
- "precomputed-hash",
- "servo_arc",
- "smallvec",
-]
-
-[[package]]
-name = "semver"
-version = "1.0.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
-dependencies = [
- "serde",
- "serde_core",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.228"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
-dependencies = [
- "serde_core",
- "serde_derive",
-]
-
-[[package]]
-name = "serde-untagged"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058"
-dependencies = [
- "erased-serde",
- "serde",
- "serde_core",
- "typeid",
-]
-
-[[package]]
-name = "serde_core"
-version = "1.0.228"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.228"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "serde_derive_internals"
-version = "0.29.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.145"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
-dependencies = [
- "itoa",
- "memchr",
- "ryu",
- "serde",
- "serde_core",
-]
-
-[[package]]
-name = "serde_path_to_error"
-version = "0.1.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457"
-dependencies = [
- "itoa",
- "serde",
- "serde_core",
-]
-
-[[package]]
-name = "serde_repr"
-version = "0.1.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "serde_spanned"
-version = "0.6.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "serde_spanned"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "serde_urlencoded"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
-dependencies = [
- "form_urlencoded",
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "serde_with"
-version = "3.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa66c845eee442168b2c8134fec70ac50dc20e760769c8ba0ad1319ca1959b04"
-dependencies = [
- "base64 0.22.1",
- "chrono",
- "hex",
- "indexmap 1.9.3",
- "indexmap 2.12.0",
- "schemars 0.9.0",
- "schemars 1.0.4",
- "serde_core",
- "serde_json",
- "serde_with_macros",
- "time",
-]
-
-[[package]]
-name = "serde_with_macros"
-version = "3.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955"
-dependencies = [
- "darling",
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "serialize-to-javascript"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5"
-dependencies = [
- "serde",
- "serde_json",
- "serialize-to-javascript-impl",
-]
-
-[[package]]
-name = "serialize-to-javascript-impl"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "servo_arc"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741"
-dependencies = [
- "nodrop",
- "stable_deref_trait",
-]
-
-[[package]]
-name = "sha1"
-version = "0.10.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "digest",
-]
-
-[[package]]
-name = "sha2"
-version = "0.10.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "digest",
-]
-
-[[package]]
-name = "sharded-slab"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
-dependencies = [
- "lazy_static",
-]
-
-[[package]]
-name = "shared_child"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7"
-dependencies = [
- "libc",
- "sigchld",
- "windows-sys 0.60.2",
-]
-
-[[package]]
-name = "shlex"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
-
-[[package]]
-name = "sigchld"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1"
-dependencies = [
- "libc",
- "os_pipe",
- "signal-hook",
-]
-
-[[package]]
-name = "signal-hook"
-version = "0.3.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
-dependencies = [
- "libc",
- "signal-hook-registry",
-]
-
-[[package]]
-name = "signal-hook-registry"
-version = "1.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "simd-adler32"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
-
-[[package]]
-name = "siphasher"
-version = "0.3.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
-
-[[package]]
-name = "siphasher"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
-
-[[package]]
-name = "slab"
-version = "0.4.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
-
-[[package]]
-name = "smallvec"
-version = "1.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
-
-[[package]]
-name = "socket2"
-version = "0.5.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
-dependencies = [
- "libc",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "socket2"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
-dependencies = [
- "libc",
- "windows-sys 0.60.2",
-]
-
-[[package]]
-name = "softbuffer"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08"
-dependencies = [
- "bytemuck",
- "cfg_aliases",
- "core-graphics 0.24.0",
- "foreign-types 0.5.0",
- "js-sys",
- "log",
- "objc2 0.5.2",
- "objc2-foundation 0.2.2",
- "objc2-quartz-core 0.2.2",
- "raw-window-handle 0.6.2",
- "redox_syscall",
- "wasm-bindgen",
- "web-sys",
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "soup3"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f"
-dependencies = [
- "futures-channel",
- "gio",
- "glib",
- "libc",
- "soup3-sys",
-]
-
-[[package]]
-name = "soup3-sys"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27"
-dependencies = [
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "libc",
- "system-deps",
-]
-
-[[package]]
-name = "spin"
-version = "0.9.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
-
-[[package]]
-name = "stable_deref_trait"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
-
-[[package]]
-name = "static_assertions"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
-
-[[package]]
-name = "string_cache"
-version = "0.8.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f"
-dependencies = [
- "new_debug_unreachable",
- "parking_lot",
- "phf_shared 0.11.3",
- "precomputed-hash",
- "serde",
-]
-
-[[package]]
-name = "string_cache_codegen"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0"
-dependencies = [
- "phf_generator 0.11.3",
- "phf_shared 0.11.3",
- "proc-macro2",
- "quote",
-]
-
-[[package]]
-name = "strsim"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
-
-[[package]]
-name = "strum"
-version = "0.26.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
-dependencies = [
- "strum_macros",
-]
-
-[[package]]
-name = "strum_macros"
-version = "0.26.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
-dependencies = [
- "heck 0.5.0",
- "proc-macro2",
- "quote",
- "rustversion",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "subtle"
-version = "2.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
-
-[[package]]
-name = "swift-rs"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7"
-dependencies = [
- "base64 0.21.7",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "syn"
-version = "1.0.109"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "syn"
-version = "2.0.108"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "sync_wrapper"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
-dependencies = [
- "futures-core",
-]
-
-[[package]]
-name = "synstructure"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "system-configuration"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
-dependencies = [
- "bitflags 2.10.0",
- "core-foundation 0.9.4",
- "system-configuration-sys",
-]
-
-[[package]]
-name = "system-configuration-sys"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "system-deps"
-version = "6.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
-dependencies = [
- "cfg-expr",
- "heck 0.5.0",
- "pkg-config",
- "toml 0.8.2",
- "version-compare",
-]
-
-[[package]]
-name = "tao"
-version = "0.34.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3a753bdc39c07b192151523a3f77cd0394aa75413802c883a0f6f6a0e5ee2e7"
-dependencies = [
- "bitflags 2.10.0",
- "block2 0.6.2",
- "core-foundation 0.10.1",
- "core-graphics 0.24.0",
- "crossbeam-channel",
- "dispatch",
- "dlopen2",
- "dpi",
- "gdkwayland-sys",
- "gdkx11-sys",
- "gtk",
- "jni",
- "lazy_static",
- "libc",
- "log",
- "ndk",
- "ndk-context",
- "ndk-sys",
- "objc2 0.6.3",
- "objc2-app-kit",
- "objc2-foundation 0.3.2",
- "once_cell",
- "parking_lot",
- "raw-window-handle 0.6.2",
- "scopeguard",
- "tao-macros",
- "unicode-segmentation",
- "url",
- "windows",
- "windows-core 0.61.2",
- "windows-version",
- "x11-dl",
-]
-
-[[package]]
-name = "tao-macros"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "tar"
-version = "0.4.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a"
-dependencies = [
- "filetime",
- "libc",
- "xattr",
-]
-
-[[package]]
-name = "target-lexicon"
-version = "0.12.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
-
-[[package]]
-name = "tauri"
-version = "2.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e492485dd390b35f7497401f67694f46161a2a00ffd800938d5dd3c898fb9d8"
-dependencies = [
- "anyhow",
- "bytes",
- "cookie",
- "dirs 6.0.0",
- "dunce",
- "embed_plist",
- "getrandom 0.3.4",
- "glob",
- "gtk",
- "heck 0.5.0",
- "http",
- "image",
- "jni",
- "libc",
- "log",
- "mime",
- "muda",
- "objc2 0.6.3",
- "objc2-app-kit",
- "objc2-foundation 0.3.2",
- "objc2-ui-kit",
- "objc2-web-kit",
- "percent-encoding",
- "plist",
- "raw-window-handle 0.6.2",
- "reqwest",
- "serde",
- "serde_json",
- "serde_repr",
- "serialize-to-javascript",
- "swift-rs",
- "tauri-build",
- "tauri-macros",
- "tauri-runtime",
- "tauri-runtime-wry",
- "tauri-utils",
- "thiserror 2.0.17",
- "tokio",
- "tray-icon",
- "url",
- "webkit2gtk",
- "webview2-com",
- "window-vibrancy",
- "windows",
-]
-
-[[package]]
-name = "tauri-build"
-version = "2.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87d6f8cafe6a75514ce5333f115b7b1866e8e68d9672bf4ca89fc0f35697ea9d"
-dependencies = [
- "anyhow",
- "cargo_toml",
- "dirs 6.0.0",
- "glob",
- "heck 0.5.0",
- "json-patch",
- "schemars 0.8.22",
- "semver",
- "serde",
- "serde_json",
- "tauri-utils",
- "tauri-winres",
- "toml 0.9.8",
- "walkdir",
-]
-
-[[package]]
-name = "tauri-codegen"
-version = "2.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7ef707148f0755110ca54377560ab891d722de4d53297595380a748026f139f"
-dependencies = [
- "base64 0.22.1",
- "brotli",
- "ico",
- "json-patch",
- "plist",
- "png 0.17.16",
- "proc-macro2",
- "quote",
- "semver",
- "serde",
- "serde_json",
- "sha2",
- "syn 2.0.108",
- "tauri-utils",
- "thiserror 2.0.17",
- "time",
- "url",
- "uuid",
- "walkdir",
-]
-
-[[package]]
-name = "tauri-macros"
-version = "2.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71664fd715ee6e382c05345ad258d6d1d50f90cf1b58c0aa726638b33c2a075d"
-dependencies = [
- "heck 0.5.0",
- "proc-macro2",
- "quote",
- "syn 2.0.108",
- "tauri-codegen",
- "tauri-utils",
-]
-
-[[package]]
-name = "tauri-plugin"
-version = "2.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "076c78a474a7247c90cad0b6e87e593c4c620ed4efdb79cbe0214f0021f6c39d"
-dependencies = [
- "anyhow",
- "glob",
- "plist",
- "schemars 0.8.22",
- "serde",
- "serde_json",
- "tauri-utils",
- "toml 0.9.8",
- "walkdir",
-]
-
-[[package]]
-name = "tauri-plugin-autostart"
-version = "2.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "459383cebc193cdd03d1ba4acc40f2c408a7abce419d64bdcd2d745bc2886f70"
-dependencies = [
- "auto-launch",
- "serde",
- "serde_json",
- "tauri",
- "tauri-plugin",
- "thiserror 2.0.17",
-]
-
-[[package]]
-name = "tauri-plugin-dialog"
-version = "2.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "313f8138692ddc4a2127c4c9607d616a46f5c042e77b3722450866da0aad2f19"
-dependencies = [
- "log",
- "raw-window-handle 0.6.2",
- "rfd",
- "serde",
- "serde_json",
- "tauri",
- "tauri-plugin",
- "tauri-plugin-fs",
- "thiserror 2.0.17",
- "url",
-]
-
-[[package]]
-name = "tauri-plugin-fs"
-version = "2.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47df422695255ecbe7bac7012440eddaeefd026656171eac9559f5243d3230d9"
-dependencies = [
- "anyhow",
- "dunce",
- "glob",
- "percent-encoding",
- "schemars 0.8.22",
- "serde",
- "serde_json",
- "serde_repr",
- "tauri",
- "tauri-plugin",
- "tauri-utils",
- "thiserror 2.0.17",
- "toml 0.9.8",
- "url",
-]
-
-[[package]]
-name = "tauri-plugin-http"
-version = "2.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c00685aceab12643cf024f712ab0448ba8fcadf86f2391d49d2e5aa732aacc70"
-dependencies = [
- "bytes",
- "cookie_store",
- "data-url",
- "http",
- "regex",
- "reqwest",
- "schemars 0.8.22",
- "serde",
- "serde_json",
- "tauri",
- "tauri-plugin",
- "tauri-plugin-fs",
- "thiserror 2.0.17",
- "tokio",
- "url",
- "urlpattern",
-]
-
-[[package]]
-name = "tauri-plugin-shell"
-version = "2.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c374b6db45f2a8a304f0273a15080d98c70cde86178855fc24653ba657a1144c"
-dependencies = [
- "encoding_rs",
- "log",
- "open",
- "os_pipe",
- "regex",
- "schemars 0.8.22",
- "serde",
- "serde_json",
- "shared_child",
- "tauri",
- "tauri-plugin",
- "thiserror 2.0.17",
- "tokio",
-]
-
-[[package]]
-name = "tauri-plugin-single-instance"
-version = "2.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd707f8c86b4e3004e2c141fa24351f1909ba40ce1b8437e30d5ed5277dd3710"
-dependencies = [
- "serde",
- "serde_json",
- "tauri",
- "thiserror 2.0.17",
- "tracing",
- "windows-sys 0.60.2",
- "zbus",
-]
-
-[[package]]
-name = "tauri-plugin-store"
-version = "2.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59a77036340a97eb5bbe1b3209c31e5f27f75e6f92a52fd9dd4b211ef08bf310"
-dependencies = [
- "dunce",
- "serde",
- "serde_json",
- "tauri",
- "tauri-plugin",
- "thiserror 2.0.17",
- "tokio",
- "tracing",
-]
-
-[[package]]
-name = "tauri-plugin-updater"
-version = "2.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27cbc31740f4d507712550694749572ec0e43bdd66992db7599b89fbfd6b167b"
-dependencies = [
- "base64 0.22.1",
- "dirs 6.0.0",
- "flate2",
- "futures-util",
- "http",
- "infer 0.19.0",
- "log",
- "minisign-verify",
- "osakit",
- "percent-encoding",
- "reqwest",
- "semver",
- "serde",
- "serde_json",
- "tar",
- "tauri",
- "tauri-plugin",
- "tempfile",
- "thiserror 2.0.17",
- "time",
- "tokio",
- "url",
- "windows-sys 0.60.2",
- "zip",
-]
-
-[[package]]
-name = "tauri-runtime"
-version = "2.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9368f09358496f2229313fccb37682ad116b7f46fa76981efe116994a0628926"
-dependencies = [
- "cookie",
- "dpi",
- "gtk",
- "http",
- "jni",
- "objc2 0.6.3",
- "objc2-ui-kit",
- "objc2-web-kit",
- "raw-window-handle 0.6.2",
- "serde",
- "serde_json",
- "tauri-utils",
- "thiserror 2.0.17",
- "url",
- "webkit2gtk",
- "webview2-com",
- "windows",
-]
-
-[[package]]
-name = "tauri-runtime-wry"
-version = "2.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "929f5df216f5c02a9e894554401bcdab6eec3e39ec6a4a7731c7067fc8688a93"
-dependencies = [
- "gtk",
- "http",
- "jni",
- "log",
- "objc2 0.6.3",
- "objc2-app-kit",
- "objc2-foundation 0.3.2",
- "once_cell",
- "percent-encoding",
- "raw-window-handle 0.6.2",
- "softbuffer",
- "tao",
- "tauri-runtime",
- "tauri-utils",
- "url",
- "webkit2gtk",
- "webview2-com",
- "windows",
- "wry",
-]
-
-[[package]]
-name = "tauri-utils"
-version = "2.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6b8bbe426abdbf52d050e52ed693130dbd68375b9ad82a3fb17efb4c8d85673"
-dependencies = [
- "anyhow",
- "brotli",
- "cargo_metadata",
- "ctor",
- "dunce",
- "glob",
- "html5ever",
- "http",
- "infer 0.19.0",
- "json-patch",
- "kuchikiki",
- "log",
- "memchr",
- "phf 0.11.3",
- "proc-macro2",
- "quote",
- "regex",
- "schemars 0.8.22",
- "semver",
- "serde",
- "serde-untagged",
- "serde_json",
- "serde_with",
- "swift-rs",
- "thiserror 2.0.17",
- "toml 0.9.8",
- "url",
- "urlpattern",
- "uuid",
- "walkdir",
-]
-
-[[package]]
-name = "tauri-winres"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd21509dd1fa9bd355dc29894a6ff10635880732396aa38c0066c1e6c1ab8074"
-dependencies = [
- "embed-resource",
- "toml 0.9.8",
-]
-
-[[package]]
-name = "tempfile"
-version = "3.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
-dependencies = [
- "fastrand",
- "getrandom 0.3.4",
- "once_cell",
- "rustix 1.1.2",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "tendril"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0"
-dependencies = [
- "futf",
- "mac",
- "utf-8",
-]
-
-[[package]]
-name = "thiserror"
-version = "1.0.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
-dependencies = [
- "thiserror-impl 1.0.69",
-]
-
-[[package]]
-name = "thiserror"
-version = "2.0.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
-dependencies = [
- "thiserror-impl 2.0.17",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "2.0.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "thread_local"
-version = "1.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "time"
-version = "0.3.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
-dependencies = [
- "deranged",
- "itoa",
- "num-conv",
- "powerfmt",
- "serde",
- "time-core",
- "time-macros",
-]
-
-[[package]]
-name = "time-core"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
-
-[[package]]
-name = "time-macros"
-version = "0.2.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
-dependencies = [
- "num-conv",
- "time-core",
-]
-
-[[package]]
-name = "tinystr"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
-dependencies = [
- "displaydoc",
- "zerovec",
-]
-
-[[package]]
-name = "tinyvec"
-version = "1.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
-dependencies = [
- "tinyvec_macros",
-]
-
-[[package]]
-name = "tinyvec_macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
-
-[[package]]
-name = "tokio"
-version = "1.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
-dependencies = [
- "bytes",
- "libc",
- "mio",
- "parking_lot",
- "pin-project-lite",
- "signal-hook-registry",
- "socket2 0.6.1",
- "tokio-macros",
- "tracing",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "tokio-macros"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "tokio-rustls"
-version = "0.26.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
-dependencies = [
- "rustls",
- "tokio",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.7.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594"
-dependencies = [
- "bytes",
- "futures-core",
- "futures-sink",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "toml"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
-dependencies = [
- "serde",
- "serde_spanned 0.6.9",
- "toml_datetime 0.6.3",
- "toml_edit 0.20.2",
-]
-
-[[package]]
-name = "toml"
-version = "0.9.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8"
-dependencies = [
- "indexmap 2.12.0",
- "serde_core",
- "serde_spanned 1.0.3",
- "toml_datetime 0.7.3",
- "toml_parser",
- "toml_writer",
- "winnow 0.7.13",
-]
-
-[[package]]
-name = "toml_datetime"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "toml_datetime"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.19.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
-dependencies = [
- "indexmap 2.12.0",
- "toml_datetime 0.6.3",
- "winnow 0.5.40",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.20.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
-dependencies = [
- "indexmap 2.12.0",
- "serde",
- "serde_spanned 0.6.9",
- "toml_datetime 0.6.3",
- "winnow 0.5.40",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.23.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d"
-dependencies = [
- "indexmap 2.12.0",
- "toml_datetime 0.7.3",
- "toml_parser",
- "winnow 0.7.13",
-]
-
-[[package]]
-name = "toml_parser"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
-dependencies = [
- "winnow 0.7.13",
-]
-
-[[package]]
-name = "toml_writer"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
-
-[[package]]
-name = "tower"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
-dependencies = [
- "futures-core",
- "futures-util",
- "pin-project-lite",
- "sync_wrapper",
- "tokio",
- "tower-layer",
- "tower-service",
- "tracing",
-]
-
-[[package]]
-name = "tower-http"
-version = "0.6.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
-dependencies = [
- "bitflags 2.10.0",
- "bytes",
- "futures-util",
- "http",
- "http-body",
- "iri-string",
- "pin-project-lite",
- "tower",
- "tower-layer",
- "tower-service",
-]
-
-[[package]]
-name = "tower-layer"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
-
-[[package]]
-name = "tower-service"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
-
-[[package]]
-name = "tracing"
-version = "0.1.41"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
-dependencies = [
- "log",
- "pin-project-lite",
- "tracing-attributes",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-appender"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
-dependencies = [
- "crossbeam-channel",
- "thiserror 1.0.69",
- "time",
- "tracing-subscriber",
-]
-
-[[package]]
-name = "tracing-attributes"
-version = "0.1.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "tracing-core"
-version = "0.1.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
-dependencies = [
- "once_cell",
- "valuable",
-]
-
-[[package]]
-name = "tracing-log"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
-dependencies = [
- "log",
- "once_cell",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-serde"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1"
-dependencies = [
- "serde",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-subscriber"
-version = "0.3.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5"
-dependencies = [
- "matchers",
- "nu-ansi-term",
- "once_cell",
- "regex-automata",
- "serde",
- "serde_json",
- "sharded-slab",
- "smallvec",
- "thread_local",
- "time",
- "tracing",
- "tracing-core",
- "tracing-log",
- "tracing-serde",
-]
-
-[[package]]
-name = "tray-icon"
-version = "0.21.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3d5572781bee8e3f994d7467084e1b1fd7a93ce66bd480f8156ba89dee55a2b"
-dependencies = [
- "crossbeam-channel",
- "dirs 6.0.0",
- "libappindicator",
- "muda",
- "objc2 0.6.3",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-core-graphics",
- "objc2-foundation 0.3.2",
- "once_cell",
- "png 0.17.16",
- "serde",
- "thiserror 2.0.17",
- "windows-sys 0.60.2",
-]
-
-[[package]]
-name = "try-lock"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
-
-[[package]]
-name = "typeid"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
-
-[[package]]
-name = "typenum"
-version = "1.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
-
-[[package]]
-name = "uds_windows"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
-dependencies = [
- "memoffset",
- "tempfile",
- "winapi",
-]
-
-[[package]]
-name = "unic-char-property"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
-dependencies = [
- "unic-char-range",
-]
-
-[[package]]
-name = "unic-char-range"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
-
-[[package]]
-name = "unic-common"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
-
-[[package]]
-name = "unic-ucd-ident"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987"
-dependencies = [
- "unic-char-property",
- "unic-char-range",
- "unic-ucd-version",
-]
-
-[[package]]
-name = "unic-ucd-version"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
-dependencies = [
- "unic-common",
-]
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
-
-[[package]]
-name = "unicode-segmentation"
-version = "1.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
-
-[[package]]
-name = "universal-hash"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
-dependencies = [
- "crypto-common",
- "subtle",
-]
-
-[[package]]
-name = "untrusted"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
-
-[[package]]
-name = "url"
-version = "2.5.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b"
-dependencies = [
- "form_urlencoded",
- "idna",
- "percent-encoding",
- "serde",
-]
-
-[[package]]
-name = "url-escape"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44e0ce4d1246d075ca5abec4b41d33e87a6054d08e2366b63205665e950db218"
-dependencies = [
- "percent-encoding",
-]
-
-[[package]]
-name = "urlencoding"
-version = "2.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
-
-[[package]]
-name = "urlpattern"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d"
-dependencies = [
- "regex",
- "serde",
- "unic-ucd-ident",
- "url",
-]
-
-[[package]]
-name = "utf-8"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
-
-[[package]]
-name = "utf8_iter"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
-
-[[package]]
-name = "utf8parse"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
-
-[[package]]
-name = "uuid"
-version = "1.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
-dependencies = [
- "getrandom 0.3.4",
- "js-sys",
- "rand 0.9.2",
- "serde",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "valuable"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
-
-[[package]]
-name = "vcpkg"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
-
-[[package]]
-name = "version-compare"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
-
-[[package]]
-name = "version_check"
-version = "0.9.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
-
-[[package]]
-name = "versions"
-version = "5.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c73a36bc44e3039f51fbee93e39f41225f6b17b380eb70cc2aab942df06b34dd"
-dependencies = [
- "itertools",
- "nom",
-]
-
-[[package]]
-name = "vswhom"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b"
-dependencies = [
- "libc",
- "vswhom-sys",
-]
-
-[[package]]
-name = "vswhom-sys"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150"
-dependencies = [
- "cc",
- "libc",
-]
-
-[[package]]
-name = "walkdir"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
-dependencies = [
- "same-file",
- "winapi-util",
-]
-
-[[package]]
-name = "want"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
-dependencies = [
- "try-lock",
-]
-
-[[package]]
-name = "wasi"
-version = "0.9.0+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
-
-[[package]]
-name = "wasi"
-version = "0.11.1+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
-
-[[package]]
-name = "wasip2"
-version = "1.0.1+wasi-0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
-dependencies = [
- "wit-bindgen",
-]
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.105"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60"
-dependencies = [
- "cfg-if",
- "once_cell",
- "rustversion",
- "wasm-bindgen-macro",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-futures"
-version = "0.4.55"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0"
-dependencies = [
- "cfg-if",
- "js-sys",
- "once_cell",
- "wasm-bindgen",
- "web-sys",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.105"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.105"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc"
-dependencies = [
- "bumpalo",
- "proc-macro2",
- "quote",
- "syn 2.0.108",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.105"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "wasm-streams"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
-dependencies = [
- "futures-util",
- "js-sys",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
-]
-
-[[package]]
-name = "wayland-backend"
-version = "0.3.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35"
-dependencies = [
- "cc",
- "downcast-rs",
- "rustix 1.1.2",
- "scoped-tls",
- "smallvec",
- "wayland-sys",
-]
-
-[[package]]
-name = "wayland-client"
-version = "0.31.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d"
-dependencies = [
- "bitflags 2.10.0",
- "rustix 1.1.2",
- "wayland-backend",
- "wayland-scanner",
-]
-
-[[package]]
-name = "wayland-protocols"
-version = "0.32.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901"
-dependencies = [
- "bitflags 2.10.0",
- "wayland-backend",
- "wayland-client",
- "wayland-scanner",
-]
-
-[[package]]
-name = "wayland-scanner"
-version = "0.31.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3"
-dependencies = [
- "proc-macro2",
- "quick-xml 0.37.5",
- "quote",
-]
-
-[[package]]
-name = "wayland-sys"
-version = "0.31.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142"
-dependencies = [
- "dlib",
- "log",
- "pkg-config",
-]
-
-[[package]]
-name = "web-sys"
-version = "0.3.82"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "web-time"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "webkit2gtk"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a"
-dependencies = [
- "bitflags 1.3.2",
- "cairo-rs",
- "gdk",
- "gdk-sys",
- "gio",
- "gio-sys",
- "glib",
- "glib-sys",
- "gobject-sys",
- "gtk",
- "gtk-sys",
- "javascriptcore-rs",
- "libc",
- "once_cell",
- "soup3",
- "webkit2gtk-sys",
-]
-
-[[package]]
-name = "webkit2gtk-sys"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c"
-dependencies = [
- "bitflags 1.3.2",
- "cairo-sys-rs",
- "gdk-sys",
- "gio-sys",
- "glib-sys",
- "gobject-sys",
- "gtk-sys",
- "javascriptcore-rs-sys",
- "libc",
- "pkg-config",
- "soup3-sys",
- "system-deps",
-]
-
-[[package]]
-name = "webpki-roots"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8"
-dependencies = [
- "rustls-pki-types",
-]
-
-[[package]]
-name = "webview2-com"
-version = "0.38.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4ba622a989277ef3886dd5afb3e280e3dd6d974b766118950a08f8f678ad6a4"
-dependencies = [
- "webview2-com-macros",
- "webview2-com-sys",
- "windows",
- "windows-core 0.61.2",
- "windows-implement",
- "windows-interface",
-]
-
-[[package]]
-name = "webview2-com-macros"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "webview2-com-sys"
-version = "0.38.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36695906a1b53a3bf5c4289621efedac12b73eeb0b89e7e1a89b517302d5d75c"
-dependencies = [
- "thiserror 2.0.17",
- "windows",
- "windows-core 0.61.2",
-]
-
-[[package]]
-name = "wfd"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c17bbfb155305bcb79144f568c3b796275ba4db5d5856597bc85acefe29b819"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "which"
-version = "4.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
-dependencies = [
- "either",
- "home",
- "once_cell",
- "rustix 0.38.44",
-]
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-util"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
-dependencies = [
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "window-vibrancy"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c"
-dependencies = [
- "objc2 0.6.3",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-foundation 0.3.2",
- "raw-window-handle 0.6.2",
- "windows-sys 0.59.0",
- "windows-version",
-]
-
-[[package]]
-name = "windows"
-version = "0.61.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
-dependencies = [
- "windows-collections",
- "windows-core 0.61.2",
- "windows-future",
- "windows-link 0.1.3",
- "windows-numerics",
-]
-
-[[package]]
-name = "windows-collections"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
-dependencies = [
- "windows-core 0.61.2",
-]
-
-[[package]]
-name = "windows-core"
-version = "0.61.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
-dependencies = [
- "windows-implement",
- "windows-interface",
- "windows-link 0.1.3",
- "windows-result 0.3.4",
- "windows-strings 0.4.2",
-]
-
-[[package]]
-name = "windows-core"
-version = "0.62.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
-dependencies = [
- "windows-implement",
- "windows-interface",
- "windows-link 0.2.1",
- "windows-result 0.4.1",
- "windows-strings 0.5.1",
-]
-
-[[package]]
-name = "windows-future"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
-dependencies = [
- "windows-core 0.61.2",
- "windows-link 0.1.3",
- "windows-threading",
-]
-
-[[package]]
-name = "windows-implement"
-version = "0.60.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "windows-interface"
-version = "0.59.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "windows-link"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
-
-[[package]]
-name = "windows-link"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
-
-[[package]]
-name = "windows-numerics"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
-dependencies = [
- "windows-core 0.61.2",
- "windows-link 0.1.3",
-]
-
-[[package]]
-name = "windows-registry"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
-dependencies = [
- "windows-link 0.1.3",
- "windows-result 0.3.4",
- "windows-strings 0.4.2",
-]
-
-[[package]]
-name = "windows-result"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
-dependencies = [
- "windows-link 0.1.3",
-]
-
-[[package]]
-name = "windows-result"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
-dependencies = [
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "windows-strings"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
-dependencies = [
- "windows-link 0.1.3",
-]
-
-[[package]]
-name = "windows-strings"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
-dependencies = [
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets 0.42.2",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets 0.48.5",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.59.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.60.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
-dependencies = [
- "windows-targets 0.53.5",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.61.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
-dependencies = [
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
-dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
-dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
- "windows_i686_gnullvm 0.52.6",
- "windows_i686_msvc 0.52.6",
- "windows_x86_64_gnu 0.52.6",
- "windows_x86_64_gnullvm 0.52.6",
- "windows_x86_64_msvc 0.52.6",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.53.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
-dependencies = [
- "windows-link 0.2.1",
- "windows_aarch64_gnullvm 0.53.1",
- "windows_aarch64_msvc 0.53.1",
- "windows_i686_gnu 0.53.1",
- "windows_i686_gnullvm 0.53.1",
- "windows_i686_msvc 0.53.1",
- "windows_x86_64_gnu 0.53.1",
- "windows_x86_64_gnullvm 0.53.1",
- "windows_x86_64_msvc 0.53.1",
-]
-
-[[package]]
-name = "windows-threading"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
-dependencies = [
- "windows-link 0.1.3",
-]
-
-[[package]]
-name = "windows-version"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631"
-dependencies = [
- "windows-link 0.2.1",
-]
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
-
-[[package]]
-name = "windows_i686_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
-
-[[package]]
-name = "windows_i686_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
-
-[[package]]
-name = "winnow"
-version = "0.5.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "winnow"
-version = "0.7.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "winreg"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "winreg"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
-dependencies = [
- "cfg-if",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "winreg"
-version = "0.55.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97"
-dependencies = [
- "cfg-if",
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "wit-bindgen"
-version = "0.46.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
-
-[[package]]
-name = "writeable"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
-
-[[package]]
-name = "wry"
-version = "0.53.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "728b7d4c8ec8d81cab295e0b5b8a4c263c0d41a785fb8f8c4df284e5411140a2"
-dependencies = [
- "base64 0.22.1",
- "block2 0.6.2",
- "cookie",
- "crossbeam-channel",
- "dirs 6.0.0",
- "dpi",
- "dunce",
- "gdkx11",
- "gtk",
- "html5ever",
- "http",
- "javascriptcore-rs",
- "jni",
- "kuchikiki",
- "libc",
- "ndk",
- "objc2 0.6.3",
- "objc2-app-kit",
- "objc2-core-foundation",
- "objc2-foundation 0.3.2",
- "objc2-ui-kit",
- "objc2-web-kit",
- "once_cell",
- "percent-encoding",
- "raw-window-handle 0.6.2",
- "sha2",
- "soup3",
- "tao-macros",
- "thiserror 2.0.17",
- "url",
- "webkit2gtk",
- "webkit2gtk-sys",
- "webview2-com",
- "windows",
- "windows-core 0.61.2",
- "windows-version",
- "x11-dl",
-]
-
-[[package]]
-name = "x11"
-version = "2.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e"
-dependencies = [
- "libc",
- "pkg-config",
-]
-
-[[package]]
-name = "x11-dl"
-version = "2.21.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f"
-dependencies = [
- "libc",
- "once_cell",
- "pkg-config",
-]
-
-[[package]]
-name = "x25519-dalek"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
-dependencies = [
- "curve25519-dalek",
- "rand_core 0.6.4",
- "serde",
- "zeroize",
-]
-
-[[package]]
-name = "xattr"
-version = "1.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156"
-dependencies = [
- "libc",
- "rustix 1.1.2",
-]
-
-[[package]]
-name = "yoke"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954"
-dependencies = [
- "stable_deref_trait",
- "yoke-derive",
- "zerofrom",
-]
-
-[[package]]
-name = "yoke-derive"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
- "synstructure",
-]
-
-[[package]]
-name = "zbus"
-version = "5.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b622b18155f7a93d1cd2dc8c01d2d6a44e08fb9ebb7b3f9e6ed101488bad6c91"
-dependencies = [
- "async-broadcast",
- "async-executor",
- "async-io",
- "async-lock",
- "async-process",
- "async-recursion",
- "async-task",
- "async-trait",
- "blocking",
- "enumflags2",
- "event-listener",
- "futures-core",
- "futures-lite",
- "hex",
- "nix",
- "ordered-stream",
- "serde",
- "serde_repr",
- "tokio",
- "tracing",
- "uds_windows",
- "uuid",
- "windows-sys 0.61.2",
- "winnow 0.7.13",
- "zbus_macros",
- "zbus_names",
- "zvariant",
-]
-
-[[package]]
-name = "zbus_macros"
-version = "5.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cdb94821ca8a87ca9c298b5d1cbd80e2a8b67115d99f6e4551ac49e42b6a314"
-dependencies = [
- "proc-macro-crate 3.4.0",
- "proc-macro2",
- "quote",
- "syn 2.0.108",
- "zbus_names",
- "zvariant",
- "zvariant_utils",
-]
-
-[[package]]
-name = "zbus_names"
-version = "4.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97"
-dependencies = [
- "serde",
- "static_assertions",
- "winnow 0.7.13",
- "zvariant",
-]
-
-[[package]]
-name = "zerocopy"
-version = "0.8.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
-dependencies = [
- "zerocopy-derive",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.8.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "zerofrom"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
-dependencies = [
- "zerofrom-derive",
-]
-
-[[package]]
-name = "zerofrom-derive"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
- "synstructure",
-]
-
-[[package]]
-name = "zeroize"
-version = "1.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
-dependencies = [
- "zeroize_derive",
-]
-
-[[package]]
-name = "zeroize_derive"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "zerotrie"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851"
-dependencies = [
- "displaydoc",
- "yoke",
- "zerofrom",
-]
-
-[[package]]
-name = "zerovec"
-version = "0.11.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
-dependencies = [
- "yoke",
- "zerofrom",
- "zerovec-derive",
-]
-
-[[package]]
-name = "zerovec-derive"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.108",
-]
-
-[[package]]
-name = "zip"
-version = "4.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1"
-dependencies = [
- "arbitrary",
- "crc32fast",
- "indexmap 2.12.0",
- "memchr",
-]
-
-[[package]]
-name = "zvariant"
-version = "5.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2be61892e4f2b1772727be11630a62664a1826b62efa43a6fe7449521cb8744c"
-dependencies = [
- "endi",
- "enumflags2",
- "serde",
- "url",
- "winnow 0.7.13",
- "zvariant_derive",
- "zvariant_utils",
-]
-
-[[package]]
-name = "zvariant_derive"
-version = "5.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da58575a1b2b20766513b1ec59d8e2e68db2745379f961f86650655e862d2006"
-dependencies = [
- "proc-macro-crate 3.4.0",
- "proc-macro2",
- "quote",
- "syn 2.0.108",
- "zvariant_utils",
-]
-
-[[package]]
-name = "zvariant_utils"
-version = "3.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6949d142f89f6916deca2232cf26a8afacf2b9fdc35ce766105e104478be599"
-dependencies = [
- "proc-macro2",
- "quote",
- "serde",
- "syn 2.0.108",
- "winnow 0.7.13",
-]
diff --git a/packages/hoppscotch-agent/src-tauri/Cargo.toml b/packages/hoppscotch-agent/src-tauri/Cargo.toml
deleted file mode 100644
index c8809b0c..00000000
--- a/packages/hoppscotch-agent/src-tauri/Cargo.toml
+++ /dev/null
@@ -1,57 +0,0 @@
-[package]
-name = "hoppscotch-agent"
-version = "0.1.17"
-description = "A cross-platform HTTP request agent for Hoppscotch for advanced request handling including custom headers, certificates, proxies, and local system integration."
-authors = ["AndrewBastin", "CuriousCorrelation"]
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[lib]
-name = "hoppscotch_agent_lib"
-crate-type = ["staticlib", "cdylib", "rlib"]
-
-[build-dependencies]
-tauri-build = { version = "2.5.2", features = [] }
-
-[dependencies]
-tauri = { version = "2.9.3", features = ["tray-icon", "image-png"] }
-tauri-plugin-shell = "2.3.3"
-tauri-plugin-autostart = { version = "2.5.1", optional = true }
-serde = { version = "1", features = ["derive"] }
-serde_json = "1"
-tokio = { version = "1.48.0", features = ["full"] }
-dashmap = { version = "6.1.0", features = ["serde"] }
-axum = { version = "0.7.9" }
-axum-extra = { version = "0.9.6", features = ["typed-header"] }
-tower-http = { version = "0.6.6", features = ["cors"] }
-tokio-util = "0.7.17"
-uuid = { version = "1.18.1", features = [ "v4", "fast-rng" ] }
-chrono = { version = "0.4", features = ["serde"] }
-rand = "0.8.5"
-tracing = "0.1.41"
-tracing-subscriber = { version = "0.3.20", features = ["env-filter", "json", "fmt", "std", "time"] }
-tracing-appender = "0.2.3"
-relay = { git = "https://github.com/CuriousCorrelation/relay.git" }
-thiserror = "1.0.69"
-tauri-plugin-store = "2.4.1"
-x25519-dalek = { version = "2.0.1", features = ["getrandom"] }
-base16 = "0.2.1"
-aes-gcm = { version = "0.10.3", features = ["aes"] }
-tauri-plugin-updater = "2.9.0"
-tauri-plugin-dialog = "2.4.2"
-lazy_static = "1.5.0"
-tauri-plugin-single-instance = "2.3.6"
-tauri-plugin-http = { version = "2.5.4", features = ["gzip"] }
-native-dialog = "0.7.0"
-sha2 = "0.10.9"
-file-rotate = "0.8.0"
-dirs = "6.0.0"
-
-[target.'cfg(windows)'.dependencies]
-tempfile = { version = "3.23.0" }
-winreg = { version = "0.52.0" }
-
-[features]
-default = ["tauri-plugin-autostart"]
-portable = []
diff --git a/packages/hoppscotch-agent/src-tauri/build.rs b/packages/hoppscotch-agent/src-tauri/build.rs
deleted file mode 100644
index 65c5c67e..00000000
--- a/packages/hoppscotch-agent/src-tauri/build.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
- tauri_build::build();
- println!("cargo::rerun-if-env-changed=UPDATER_PUB_KEY");
- println!("cargo::rerun-if-env-changed=UPDATER_URL");
-}
diff --git a/packages/hoppscotch-agent/src-tauri/capabilities/default.json b/packages/hoppscotch-agent/src-tauri/capabilities/default.json
deleted file mode 100644
index 70c49c1c..00000000
--- a/packages/hoppscotch-agent/src-tauri/capabilities/default.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "$schema": "../gen/schemas/desktop-schema.json",
- "identifier": "default",
- "description": "Capability for the main window",
- "windows": ["main", "test"],
- "permissions": [
- {
- "identifier": "http:default",
- "allow": [
- {
- "url": "https://*.tauri.app"
- },
- {
- "url": "https://*.microsoft.*"
- }
- ]
- },
- "core:default",
- "shell:allow-open",
- "core:window:allow-close",
- "core:window:allow-hide",
- "core:window:allow-set-focus",
- "core:window:allow-set-always-on-top"
- ]
-}
diff --git a/packages/hoppscotch-agent/src-tauri/icons/128x128.png b/packages/hoppscotch-agent/src-tauri/icons/128x128.png
deleted file mode 100644
index 3778416d..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/128x128.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/128x128@2x.png b/packages/hoppscotch-agent/src-tauri/icons/128x128@2x.png
deleted file mode 100644
index e5b88465..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/128x128@2x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/32x32.png b/packages/hoppscotch-agent/src-tauri/icons/32x32.png
deleted file mode 100644
index e553d90f..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/32x32.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/Square107x107Logo.png b/packages/hoppscotch-agent/src-tauri/icons/Square107x107Logo.png
deleted file mode 100644
index e8e31c23..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/Square107x107Logo.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/Square142x142Logo.png b/packages/hoppscotch-agent/src-tauri/icons/Square142x142Logo.png
deleted file mode 100644
index 938bf8dc..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/Square142x142Logo.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/Square150x150Logo.png b/packages/hoppscotch-agent/src-tauri/icons/Square150x150Logo.png
deleted file mode 100644
index 647408c5..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/Square150x150Logo.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/Square284x284Logo.png b/packages/hoppscotch-agent/src-tauri/icons/Square284x284Logo.png
deleted file mode 100644
index a898743c..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/Square284x284Logo.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/Square30x30Logo.png b/packages/hoppscotch-agent/src-tauri/icons/Square30x30Logo.png
deleted file mode 100644
index e1a1f772..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/Square30x30Logo.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/Square310x310Logo.png b/packages/hoppscotch-agent/src-tauri/icons/Square310x310Logo.png
deleted file mode 100644
index 69bf56b1..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/Square310x310Logo.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/Square44x44Logo.png b/packages/hoppscotch-agent/src-tauri/icons/Square44x44Logo.png
deleted file mode 100644
index bb5b8951..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/Square44x44Logo.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/Square71x71Logo.png b/packages/hoppscotch-agent/src-tauri/icons/Square71x71Logo.png
deleted file mode 100644
index 68541683..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/Square71x71Logo.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/Square89x89Logo.png b/packages/hoppscotch-agent/src-tauri/icons/Square89x89Logo.png
deleted file mode 100644
index 94a65e2a..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/Square89x89Logo.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/StoreLogo.png b/packages/hoppscotch-agent/src-tauri/icons/StoreLogo.png
deleted file mode 100644
index db4b61ba..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/StoreLogo.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index b334e000..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png
deleted file mode 100644
index ea31185c..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index b334e000..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index ee4bfd7d..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png
deleted file mode 100644
index 794a5c62..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index ee4bfd7d..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index fbef3290..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png
deleted file mode 100644
index 9aee0bf9..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index fbef3290..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index d63d25bc..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png
deleted file mode 100644
index 1443a0c1..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index d63d25bc..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 3e0f1c39..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png
deleted file mode 100644
index 5f449d41..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index 3e0f1c39..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/icon.icns b/packages/hoppscotch-agent/src-tauri/icons/icon.icns
deleted file mode 100644
index 293556d7..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/icon.icns and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/icon.ico b/packages/hoppscotch-agent/src-tauri/icons/icon.ico
deleted file mode 100644
index 3e3249c9..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/icon.ico and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/icon.png b/packages/hoppscotch-agent/src-tauri/icons/icon.png
deleted file mode 100644
index a91230bb..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/icon.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@1x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@1x.png
deleted file mode 100644
index e63a928c..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@1x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@2x-1.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@2x-1.png
deleted file mode 100644
index 8caffb7b..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@2x-1.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@2x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@2x.png
deleted file mode 100644
index 8caffb7b..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@2x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@3x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@3x.png
deleted file mode 100644
index c51270a0..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-20x20@3x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@1x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@1x.png
deleted file mode 100644
index c89515b2..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@1x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@2x-1.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@2x-1.png
deleted file mode 100644
index 4c23c687..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@2x-1.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@2x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@2x.png
deleted file mode 100644
index 4c23c687..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@2x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@3x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@3x.png
deleted file mode 100644
index cd117af2..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-29x29@3x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@1x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@1x.png
deleted file mode 100644
index 8caffb7b..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@1x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@2x-1.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@2x-1.png
deleted file mode 100644
index 9f5c51d7..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@2x-1.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@2x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@2x.png
deleted file mode 100644
index 9f5c51d7..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@2x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@3x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@3x.png
deleted file mode 100644
index 97738c12..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-40x40@3x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-512@2x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-512@2x.png
deleted file mode 100644
index ed29af68..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-512@2x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-60x60@2x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-60x60@2x.png
deleted file mode 100644
index 97738c12..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-60x60@2x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-60x60@3x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-60x60@3x.png
deleted file mode 100644
index 6eb83336..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-60x60@3x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-76x76@1x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-76x76@1x.png
deleted file mode 100644
index 38d7d795..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-76x76@1x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-76x76@2x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-76x76@2x.png
deleted file mode 100644
index 4dbf0d79..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-76x76@2x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png b/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png
deleted file mode 100644
index aed36133..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/icons/tray_icon.png b/packages/hoppscotch-agent/src-tauri/icons/tray_icon.png
deleted file mode 100644
index b29857f4..00000000
Binary files a/packages/hoppscotch-agent/src-tauri/icons/tray_icon.png and /dev/null differ
diff --git a/packages/hoppscotch-agent/src-tauri/src/command.rs b/packages/hoppscotch-agent/src-tauri/src/command.rs
deleted file mode 100644
index 40de8c5b..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/command.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use std::sync::Arc;
-
-use crate::{
- model::{MaskedRegistration, RegistrationsList},
- state::AppState,
- util::generate_auth_key_hash,
-};
-
-#[tauri::command]
-#[tracing::instrument(skip(state))]
-pub async fn get_otp(state: tauri::State<'_, Arc>) -> Result, ()> {
- tracing::debug!("Retrieving current OTP");
- let otp = state.active_registration_code.read().await.clone();
- if otp.is_some() {
- tracing::debug!("OTP found");
- } else {
- tracing::debug!("No active OTP");
- }
- Ok(otp)
-}
-
-#[tauri::command]
-#[tracing::instrument(skip(state))]
-pub fn list_registrations(state: tauri::State<'_, Arc>) -> Result {
- tracing::debug!("Retrieving registrations list");
-
- let masked_registrations = state
- .get_registrations()
- .iter()
- .map(|entry| MaskedRegistration {
- registered_at: entry.value().registered_at,
- auth_key_hash: generate_auth_key_hash(entry.key()),
- })
- .collect();
-
- Ok(RegistrationsList {
- registrations: masked_registrations,
- total: state.get_registrations().len(),
- })
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/controller.rs b/packages/hoppscotch-agent/src-tauri/src/controller.rs
deleted file mode 100644
index 42f26217..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/controller.rs
+++ /dev/null
@@ -1,399 +0,0 @@
-use std::sync::Arc;
-
-use axum::{
- body::Bytes,
- extract::{Path, State},
- http::HeaderMap,
- Json,
-};
-use axum_extra::{
- headers::{authorization::Bearer, Authorization},
- TypedHeader,
-};
-use chrono::Utc;
-use rand::Rng;
-use serde_json::json;
-use tauri::{AppHandle, Emitter};
-use uuid::Uuid;
-use x25519_dalek::{EphemeralSecret, PublicKey};
-
-use crate::{
- error::{AgentError, AgentResult},
- global::NONCE,
- model::{
- AuthKeyResponse, ConfirmedRegistrationRequest, HandshakeResponse, LogEntry, LogLevel,
- MaskedRegistration, Registration,
- },
- state::AppState,
- util::{generate_auth_key_hash, EncryptedJson},
-};
-
-#[tracing::instrument]
-fn generate_otp() -> String {
- let otp: u32 = rand::thread_rng().gen_range(0..1_000_000);
- let formatted = format!("{:06}", otp);
- tracing::debug!("Generated OTP: {}", formatted);
- formatted
-}
-
-#[tracing::instrument(skip(app_handle))]
-pub async fn handshake(
- State((_, app_handle)): State<(Arc, AppHandle)>,
-) -> AgentResult> {
- tracing::info!("Processing handshake request");
- let response = HandshakeResponse {
- status: "success".to_string(),
- __hoppscotch__agent__: true,
- agent_version: app_handle.package_info().version.to_string(),
- };
- tracing::info!("Handshake successful");
- Ok(Json(response))
-}
-
-#[tracing::instrument(skip(state, app_handle))]
-pub async fn receive_registration(
- State((state, app_handle)): State<(Arc, AppHandle)>,
-) -> AgentResult> {
- let otp = generate_otp();
- tracing::info!("Generated new registration OTP");
-
- let mut active_registration_code = state.active_registration_code.write().await;
-
- if !active_registration_code.is_none() {
- tracing::warn!("Registration attempt while another registration is active");
- return Ok(Json(
- json!({ "message": "There is already an existing registration happening" }),
- ));
- }
-
- *active_registration_code = Some(otp.clone());
-
- match app_handle.emit("registration-received", otp) {
- Ok(_) => {
- tracing::info!("Registration event emitted successfully");
- Ok(Json(
- json!({ "message": "Registration received and stored" }),
- ))
- }
- Err(e) => {
- tracing::error!("Failed to emit registration event: {}", e);
- Err(AgentError::InternalServerError)
- }
- }
-}
-
-#[tracing::instrument(skip(state, _app_handle))]
-pub async fn registration(
- State((state, _app_handle)): State<(Arc, AppHandle)>,
- TypedHeader(auth_header): TypedHeader>,
-) -> AgentResult> {
- let token = auth_header.token();
-
- if !state.validate_access(token) {
- tracing::warn!("Unauthorized attempt to list registrations");
- return Err(AgentError::Unauthorized);
- }
-
- let registration = state
- .get_registration(token)
- .ok_or(AgentError::Unauthorized)?;
-
- let key_b16 = registration.shared_secret_b16;
-
- let registration = MaskedRegistration {
- registered_at: registration.registered_at,
- auth_key_hash: generate_auth_key_hash(token),
- };
-
- tracing::info!("Successfully retrieved registrations list");
- Ok(EncryptedJson {
- key_b16,
- data: registration,
- })
-}
-
-#[tracing::instrument(skip(state, app_handle), fields(auth_key))]
-pub async fn verify_registration(
- State((state, app_handle)): State<(Arc, AppHandle)>,
- Json(confirmed_registration): Json,
-) -> AgentResult> {
- tracing::info!("Verifying registration request");
-
- if !state
- .validate_registration(&confirmed_registration.registration)
- .await
- {
- tracing::warn!("Invalid registration attempt");
- return Err(AgentError::InvalidRegistration);
- }
-
- let auth_key = Uuid::new_v4().to_string();
- let created_at = Utc::now();
-
- tracing::Span::current().record("auth_key", &auth_key.as_str());
-
- let auth_key_copy = auth_key.clone();
- let secret_key = EphemeralSecret::random();
- let public_key = PublicKey::from(&secret_key);
-
- let their_public_key = {
- let public_key_slice: &[u8; 32] =
- &base16::decode(&confirmed_registration.client_public_key_b16)
- .map_err(|_| AgentError::InvalidClientPublicKey)?[0..32]
- .try_into()
- .map_err(|_| AgentError::InvalidClientPublicKey)?;
-
- PublicKey::from(public_key_slice.to_owned())
- };
-
- let shared_secret = secret_key.diffie_hellman(&their_public_key);
-
- if let Err(e) = state.update_registrations(app_handle.clone(), |regs| {
- regs.insert(
- auth_key_copy,
- Registration {
- registered_at: created_at,
- shared_secret_b16: base16::encode_lower(shared_secret.as_bytes()),
- },
- );
- }) {
- tracing::error!("Failed to update registrations: {:?}", e);
- return Err(e);
- }
-
- let auth_payload = json!({
- "auth_key": auth_key,
- "created_at": created_at
- });
-
- if let Err(e) = app_handle.emit("authenticated", &auth_payload) {
- tracing::error!("Failed to emit authenticated event: {:?}", e);
- return Err(AgentError::InternalServerError);
- }
-
- let _ = state.clear_active_registration().await;
-
- tracing::info!("Registration verified successfully");
- Ok(Json(AuthKeyResponse {
- auth_key,
- created_at,
- agent_public_key_b16: base16::encode_lower(public_key.as_bytes()),
- }))
-}
-
-#[tracing::instrument(skip(state, app_handle), fields(auth_key = %auth_key))]
-pub async fn delete_registration(
- State((state, app_handle)): State<(Arc, AppHandle)>,
- TypedHeader(auth_header): TypedHeader>,
- Path(auth_key): Path,
-) -> AgentResult> {
- if !state.validate_access(auth_header.token()) {
- tracing::warn!("Unauthorized deletion attempt");
- return Err(AgentError::Unauthorized);
- }
-
- let _removed = state.update_registrations(app_handle.clone(), |regs| {
- regs.remove(&auth_key);
- })?;
-
- tracing::info!("Registration deleted successfully");
- let message = format!("{} registration deleted successfully", auth_key);
- Ok(Json(json!({ "message": message })))
-}
-
-#[tracing::instrument(skip(state, body, _app_handle), fields(req_id))]
-pub async fn execute(
- State((state, _app_handle)): State<(Arc, AppHandle)>,
- TypedHeader(auth_header): TypedHeader>,
- headers: HeaderMap,
- body: Bytes,
-) -> AgentResult> {
- let nonce = match headers.get(NONCE) {
- Some(n) => match n.to_str() {
- Ok(n) => n,
- Err(_) => {
- tracing::warn!("Invalid nonce header");
- return Err(AgentError::Unauthorized);
- }
- },
- None => {
- tracing::warn!("Missing nonce header");
- return Err(AgentError::Unauthorized);
- }
- };
-
- let request = match state.validate_access_and_get_data::(
- auth_header.token(),
- nonce,
- &body,
- ) {
- Some(r) => r,
- None => {
- tracing::warn!("Invalid access or data");
- return Err(AgentError::Unauthorized);
- }
- };
-
- let request_id = request.id;
-
- tracing::Span::current().record("request_id", &request_id);
-
- let reg_info = match state.get_registration(auth_header.token()) {
- Some(r) => r,
- None => {
- tracing::warn!("Registration info not found");
- return Err(AgentError::Unauthorized);
- }
- };
-
- Ok(relay::execute(request)
- .await
- .map(|response| EncryptedJson {
- key_b16: reg_info.shared_secret_b16,
- data: response,
- })?)
-}
-
-/// Provides a way for registered clients to check if their
-/// registration still holds, this route is supposed to return
-/// an encrypted `true` value if the given auth_key is good.
-/// Since its encrypted with the shared secret established during
-/// registration, the client also needs the shared secret to verify
-/// if the read fails, or the auth_key didn't validate and this route returns
-/// undefined, we can count on the registration not being valid anymore.
-#[tracing::instrument(skip(state, _app_handle))]
-pub async fn registered_handshake(
- State((state, _app_handle)): State<(Arc, AppHandle)>,
- TypedHeader(auth_header): TypedHeader>,
-) -> AgentResult> {
- let reg_info = state.get_registration(auth_header.token());
-
- match reg_info {
- Some(reg) => {
- tracing::info!("Handshake successful");
- Ok(EncryptedJson {
- key_b16: reg.shared_secret_b16,
- data: json!(true),
- })
- }
- None => {
- tracing::warn!("Unauthorized handshake attempt");
- Err(AgentError::Unauthorized)
- }
- }
-}
-
-#[tracing::instrument(skip(state, _app_handle), fields(request_id = %request_id))]
-pub async fn cancel(
- State((state, _app_handle)): State<(Arc, AppHandle)>,
- TypedHeader(auth_header): TypedHeader>,
- Path(request_id): Path,
-) -> AgentResult> {
- if !state.validate_access(auth_header.token()) {
- tracing::warn!("Unauthorized cancellation attempt");
- return Err(AgentError::Unauthorized);
- }
-
- if let Ok(()) = relay::cancel(request_id.try_into().unwrap()).await {
- tracing::info!("Request cancelled successfully");
- Ok(Json(json!({"message": "Request cancelled successfully"})))
- } else {
- tracing::warn!("Request not found");
- Err(AgentError::RequestNotFound)
- }
-}
-
-#[tracing::instrument(skip_all)]
-pub async fn log_sink(
- State((state, _app_handle)): State<(Arc, AppHandle)>,
- TypedHeader(auth_header): TypedHeader>,
- headers: HeaderMap,
- body: Bytes,
-) -> AgentResult> {
- if !state.validate_access(auth_header.token()) {
- tracing::warn!("Unauthorized log sink access attempt");
- return Err(AgentError::Unauthorized);
- }
-
- let nonce = match headers.get(NONCE) {
- Some(n) => match n.to_str() {
- Ok(n) => n,
- Err(_) => {
- tracing::warn!("Invalid nonce header");
- return Err(AgentError::Unauthorized);
- }
- },
- None => {
- tracing::warn!("Missing nonce header");
- return Err(AgentError::Unauthorized);
- }
- };
-
- let log_entry: LogEntry =
- match state.validate_access_and_get_data(auth_header.token(), nonce, &body) {
- Some(entry) => entry,
- None => {
- tracing::warn!("Failed to decrypt or parse log entry");
- return Err(AgentError::BadRequest("Invalid log entry format".into()));
- }
- };
-
- let metadata_str = log_entry
- .metadata
- .map(|m| m.to_string())
- .unwrap_or_default();
-
- let correlation = log_entry.correlation_id.unwrap_or_default();
-
- match log_entry.level {
- LogLevel::Debug => {
- tracing::debug!(
- timestamp = %log_entry.timestamp,
- context = %log_entry.context,
- source = %log_entry.source,
- metadata = %metadata_str,
- correlation_id = %correlation,
- "{}",
- log_entry.message
- );
- }
- LogLevel::Info => {
- tracing::info!(
- timestamp = %log_entry.timestamp,
- context = %log_entry.context,
- source = %log_entry.source,
- metadata = %metadata_str,
- correlation_id = %correlation,
- "{}",
- log_entry.message
- );
- }
- LogLevel::Warn => {
- tracing::warn!(
- timestamp = %log_entry.timestamp,
- context = %log_entry.context,
- source = %log_entry.source,
- metadata = %metadata_str,
- correlation_id = %correlation,
- "{}",
- log_entry.message
- );
- }
- LogLevel::Error => {
- tracing::error!(
- timestamp = %log_entry.timestamp,
- context = %log_entry.context,
- source = %log_entry.source,
- metadata = %metadata_str,
- correlation_id = %correlation,
- "{}",
- log_entry.message
- );
- }
- }
-
- Ok(Json(json!({
- "status": "success",
- "message": "Log entry processed"
- })))
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/dialog.rs b/packages/hoppscotch-agent/src-tauri/src/dialog.rs
deleted file mode 100644
index e4967b43..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/dialog.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-use native_dialog::{MessageDialog, MessageType};
-
-pub fn panic(msg: &str) {
- const FATAL_ERROR: &str = "Fatal error";
-
- MessageDialog::new()
- .set_type(MessageType::Error)
- .set_title(FATAL_ERROR)
- .set_text(msg)
- .show_alert()
- .unwrap_or_default();
-
- tracing::error!("{}: {}", FATAL_ERROR, msg);
-
- panic!("{}: {}", FATAL_ERROR, msg);
-}
-
-pub fn info(msg: &str) {
- tracing::info!("{}", msg);
-
- MessageDialog::new()
- .set_type(MessageType::Info)
- .set_title("Info")
- .set_text(msg)
- .show_alert()
- .unwrap_or_default();
-}
-
-pub fn warn(msg: &str) {
- tracing::warn!("{}", msg);
-
- MessageDialog::new()
- .set_type(MessageType::Warning)
- .set_title("Warning")
- .set_text(msg)
- .show_alert()
- .unwrap_or_default();
-}
-
-pub fn error(msg: &str) {
- tracing::error!("{}", msg);
-
- MessageDialog::new()
- .set_type(MessageType::Error)
- .set_title("Error")
- .set_text(msg)
- .show_alert()
- .unwrap_or_default();
-}
-
-pub fn confirm(title: &str, msg: &str, icon: MessageType) -> bool {
- MessageDialog::new()
- .set_type(icon)
- .set_title(title)
- .set_text(msg)
- .show_confirm()
- .unwrap_or_default()
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/error.rs b/packages/hoppscotch-agent/src-tauri/src/error.rs
deleted file mode 100644
index b7ef4528..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/error.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use axum::{
- http::StatusCode,
- response::{IntoResponse, Response},
- Json,
-};
-use serde_json::json;
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-pub enum AgentError {
- #[error("FATAL: No `main` window found")]
- NoMainWindow,
- #[error("Tauri error: {0}")]
- Tauri(#[from] tauri::Error),
- #[error("Invalid Registration")]
- InvalidRegistration,
- #[error("Invalid Client Public Key")]
- InvalidClientPublicKey,
- #[error("Unauthorized")]
- Unauthorized,
- #[error("Request not found or already completed")]
- RequestNotFound,
- #[error("Internal server error")]
- InternalServerError,
- #[error("Invalid request: {0}")]
- BadRequest(String),
- #[error("Client certificate error")]
- ClientCertError,
- #[error("Root certificate error")]
- RootCertError,
- #[error("Invalid method")]
- InvalidMethod,
- #[error("Invalid URL")]
- InvalidUrl,
- #[error("Invalid headers")]
- InvalidHeaders,
- #[error("Request run error: {0}")]
- RequestRunError(String),
- #[error("Request cancelled")]
- RequestCancelled,
- #[error("Failed to clear registrations")]
- RegistrationClearError,
- #[error("Failed to insert registrations")]
- RegistrationInsertError,
- #[error("Failed to save registrations to store")]
- RegistrationSaveError,
- #[error("Serde error: {0}")]
- Serde(#[from] serde_json::Error),
- #[error("Store error: {0}")]
- TauriPluginStore(#[from] tauri_plugin_store::Error),
- #[error("Relay error: {0}")]
- Relay(#[from] relay::error::RelayError),
- #[error("IO error: {0}")]
- Io(#[from] std::io::Error),
- #[error("Log init error: {0}")]
- LogInit(String),
- #[error("Log init global error: {0}")]
- LogInitGlobal(#[from] tracing::subscriber::SetGlobalDefaultError),
-}
-
-impl From for AgentError {
- fn from(err: tracing_appender::rolling::InitError) -> Self {
- AgentError::LogInit(err.to_string())
- }
-}
-
-impl IntoResponse for AgentError {
- fn into_response(self) -> Response {
- let (status, error_message) = match self {
- AgentError::InvalidRegistration => (StatusCode::BAD_REQUEST, self.to_string()),
- AgentError::InvalidClientPublicKey => (StatusCode::BAD_REQUEST, self.to_string()),
- AgentError::Unauthorized => (StatusCode::UNAUTHORIZED, self.to_string()),
- AgentError::RequestNotFound => (StatusCode::NOT_FOUND, self.to_string()),
- AgentError::InternalServerError => {
- (StatusCode::INTERNAL_SERVER_ERROR, self.to_string())
- }
- AgentError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg),
- AgentError::ClientCertError => (StatusCode::BAD_REQUEST, self.to_string()),
- AgentError::RootCertError => (StatusCode::BAD_REQUEST, self.to_string()),
- AgentError::InvalidMethod => (StatusCode::BAD_REQUEST, self.to_string()),
- AgentError::InvalidUrl => (StatusCode::BAD_REQUEST, self.to_string()),
- AgentError::InvalidHeaders => (StatusCode::BAD_REQUEST, self.to_string()),
- AgentError::RequestRunError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),
- AgentError::RequestCancelled => (StatusCode::BAD_REQUEST, self.to_string()),
- _ => (
- StatusCode::INTERNAL_SERVER_ERROR,
- "Internal Server Error".to_string(),
- ),
- };
-
- let body = Json(json!({
- "error": error_message,
- }));
-
- (status, body).into_response()
- }
-}
-
-pub type AgentResult = std::result::Result;
diff --git a/packages/hoppscotch-agent/src-tauri/src/global.rs b/packages/hoppscotch-agent/src-tauri/src/global.rs
deleted file mode 100644
index 002729db..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/global.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-pub const AGENT_STORE: &str = "app_data.bin";
-pub const REGISTRATIONS: &str = "registrations";
-pub const NONCE: &str = "X-Hopp-Nonce";
diff --git a/packages/hoppscotch-agent/src-tauri/src/lib.rs b/packages/hoppscotch-agent/src-tauri/src/lib.rs
deleted file mode 100644
index 145d39d7..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/lib.rs
+++ /dev/null
@@ -1,260 +0,0 @@
-pub mod command;
-pub mod controller;
-pub mod dialog;
-pub mod error;
-pub mod global;
-pub mod logger;
-pub mod model;
-pub mod route;
-pub mod server;
-pub mod state;
-pub mod tray;
-pub mod updater;
-pub mod util;
-pub mod webview;
-
-use std::sync::Arc;
-use tauri::{AppHandle, Emitter, Listener, Manager, WebviewWindowBuilder};
-use tauri_plugin_updater::UpdaterExt;
-use tokio_util::sync::CancellationToken;
-
-use error::{AgentError, AgentResult};
-use model::Payload;
-use state::AppState;
-
-pub const HOPPSCOTCH_AGENT_IDENTIFIER: &str = "io.hoppscotch.agent";
-
-#[tracing::instrument(skip(app_handle))]
-fn create_main_window(app_handle: &AppHandle) -> AgentResult<()> {
- tracing::info!("Creating main application window");
-
- let main = &app_handle
- .config()
- .app
- .windows
- .first()
- .ok_or(AgentError::NoMainWindow)?;
-
- tracing::debug!("Building webview window from config");
- let window = WebviewWindowBuilder::from_config(app_handle, main)?.build()?;
-
- window.hide()?;
-
- tracing::info!("Main window created successfully");
- Ok(())
-}
-
-#[tracing::instrument(skip(app_handle))]
-pub fn show_main_window(app_handle: &AppHandle) -> AgentResult<()> {
- tracing::debug!("Attempting to show main window");
- if let Some(window) = app_handle.get_webview_window("main") {
- window.show()?;
- window.set_focus()?;
- tracing::info!("Main window shown and focused");
- }
- Ok(())
-}
-
-#[tracing::instrument(skip(app_handle))]
-pub fn hide_main_window(app_handle: &AppHandle) -> AgentResult<()> {
- tracing::debug!("Attempting to hide main window");
- if let Some(window) = app_handle.get_webview_window("main") {
- window.hide()?;
- tracing::info!("Main window hidden");
- }
- Ok(())
-}
-
-#[cfg_attr(mobile, tauri::mobile_entry_point)]
-pub fn run() {
- tracing::info!("Initializing Hoppscotch Agent");
-
- // The installer takes care of installing `WebView`,
- // this check is only required for portable variant.
- #[cfg(all(feature = "portable", windows))]
- {
- tracing::debug!("Checking WebView initialization for portable Windows variant");
- webview::init_webview();
- }
-
- let cancellation_token = CancellationToken::new();
- let server_cancellation_token = cancellation_token.clone();
-
- tracing::debug!("Building Tauri application");
- let builder = tauri::Builder::default()
- // NOTE: Currently, plugins run in the order they were added in to the builder,
- // so `tauri_plugin_single_instance` needs to be registered first.
- // See: https://github.com/tauri-apps/plugins-workspace/tree/v2/plugins/single-instance
- .plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
- tracing::info!(
- app_name = %app.package_info().name,
- "Single instance handler triggered"
- );
-
- if let Err(e) = app.emit("single-instance", Payload::new(args, cwd)) {
- tracing::error!(error = %e, "Failed to emit single-instance event");
- }
-
- // Application is already running, bring it to foreground.
- if let Err(e) = show_main_window(&app) {
- tracing::error!(error = %e, "Failed to show window");
- }
- }))
- .plugin(tauri_plugin_store::Builder::new().build())
- .setup(move |app| {
- tracing::info!("Setting up application");
- let app_handle = app.handle();
-
- #[cfg(all(desktop, not(feature = "portable")))]
- {
- use tauri_plugin_autostart::MacosLauncher;
- use tauri_plugin_autostart::ManagerExt;
-
- tracing::debug!("Configuring autostart for desktop variant");
- let _ = app.handle().plugin(tauri_plugin_autostart::init(
- MacosLauncher::LaunchAgent,
- None,
- ));
-
- let autostart_manager = app.autolaunch();
-
- tracing::info!(
- enabled = autostart_manager.is_enabled().unwrap_or(false),
- "Checking autostart status"
- );
-
- if !autostart_manager.is_enabled().unwrap_or(false) {
- if let Err(e) = autostart_manager.enable() {
- tracing::error!(error = %e, "Failed to enable autostart");
- } else {
- tracing::info!("Autostart enabled successfully");
- }
- }
- };
-
- #[cfg(desktop)]
- {
- tracing::debug!("Initializing desktop-specific features");
- let _ = app
- .handle()
- .plugin(tauri_plugin_updater::Builder::new().build());
- let _ = app.handle().plugin(tauri_plugin_dialog::init());
-
- let updater = app.updater_builder().build().unwrap();
- let app_handle_ref = app_handle.clone();
-
- tauri::async_runtime::spawn_blocking(|| {
- tauri::async_runtime::block_on(async {
- updater::check_and_install_updates(app_handle_ref, updater).await;
- })
- });
- };
-
- // Create and hide the main window during setup.
- create_main_window(&app_handle)?;
-
- tracing::debug!("Initializing application state");
- let app_state = Arc::new(AppState::new(app_handle.clone())?);
- app.manage(app_state.clone());
-
- let server_cancellation_token = server_cancellation_token.clone();
- let server_app_handle = app_handle.clone();
-
- tracing::debug!("Spawning server process");
- tauri::async_runtime::spawn(async move {
- server::run_server(app_state, server_cancellation_token, server_app_handle).await;
- });
-
- #[cfg(all(desktop))]
- {
- tracing::debug!("Creating system tray");
- let handle = app.handle();
- tray::create_tray(handle)?;
- }
-
- // Blocks the app from populating the macOS dock
- #[cfg(target_os = "macos")]
- {
- tracing::debug!("Setting macOS activation policy");
- app_handle
- .set_activation_policy(tauri::ActivationPolicy::Accessory)
- .unwrap();
- };
-
- let app_handle_ref = app_handle.clone();
- app_handle.listen("maximize-window", move |_| {
- tracing::info!("Maximize window event triggered");
- if let Some(window) = app_handle_ref.get_webview_window("main") {
- if let Err(e) = window.emit("show-otp-view", ()) {
- tracing::error!("Failed to emit show-otp-view event: {}", e);
- }
-
- if let Err(e) = show_main_window(&app_handle_ref) {
- tracing::error!("Failed to maximize window: {}", e);
- }
- }
- });
-
- let app_handle_ref = app_handle.clone();
- app_handle.listen("registration-received", move |_| {
- tracing::info!("Registration received event triggered");
- if let Err(e) = show_main_window(&app_handle_ref) {
- tracing::error!(error = %e, "Failed to show window");
- }
- });
-
- tracing::info!("Application setup completed successfully");
- Ok(())
- })
- .manage(cancellation_token)
- .on_window_event(|window, event| {
- match &event {
- tauri::WindowEvent::CloseRequested { api, .. } => {
- tracing::info!("Window close requested");
- api.prevent_close();
-
- if let Err(e) = window.hide() {
- tracing::error!(error = %e, "Failed to hide window");
- }
-
- let app_state = window.state::>();
- let mut current_code = app_state.active_registration_code.blocking_write();
- if current_code.is_some() {
- tracing::debug!("Clearing active registration code");
- *current_code = None;
- }
-
- if let Err(e) = window.emit("window-hidden", ()) {
- tracing::error!(error = %e, "Failed to emit window-hidden event");
- }
- }
- _ => {
- tracing::debug!(event = ?event, "Window event received");
- }
- };
- })
- .invoke_handler(tauri::generate_handler![
- command::get_otp,
- command::list_registrations
- ]);
-
- tracing::info!("Building Tauri application with context");
- let app = builder
- .build(tauri::generate_context!())
- .expect("error while building tauri application");
-
- tracing::info!("Running application");
- app.run(|app_handle, event| match event {
- tauri::RunEvent::ExitRequested { api, code, .. } => {
- if code.is_none() || matches!(code, Some(0)) {
- tracing::info!("Exit requested, preventing immediate exit");
- api.prevent_exit();
- } else if code.is_some() {
- tracing::info!("Exit with non-zero code requested, initiating shutdown");
- let state = app_handle.state::();
- state.cancel();
- }
- }
- _ => {}
- });
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/logger.rs b/packages/hoppscotch-agent/src-tauri/src/logger.rs
deleted file mode 100644
index 610b6744..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/logger.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-use std::path::PathBuf;
-
-use file_rotate::{compression::Compression, suffix::AppendCount, ContentLimit, FileRotate};
-use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
-
-use crate::HOPPSCOTCH_AGENT_IDENTIFIER;
-
-pub struct LogGuard(pub tracing_appender::non_blocking::WorkerGuard);
-
-pub fn setup(log_dir: &PathBuf) -> Result> {
- std::fs::create_dir_all(log_dir)?;
-
- let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| "debug".into());
-
- let log_file_path = log_dir.join(&format!("{}.log", HOPPSCOTCH_AGENT_IDENTIFIER));
- tracing::info!(log_file_path =? &log_file_path);
-
- let file = FileRotate::new(
- &log_file_path,
- AppendCount::new(5),
- ContentLimit::Bytes(10 * 1024 * 1024),
- Compression::None,
- None,
- );
-
- let (non_blocking, guard) = tracing_appender::non_blocking(file);
-
- let console_layer = fmt::layer()
- .with_writer(std::io::stdout)
- .with_thread_ids(true)
- .with_thread_names(true)
- .with_ansi(!cfg!(target_os = "windows"));
-
- let file_layer = fmt::layer()
- .with_writer(non_blocking)
- .with_ansi(false)
- .with_thread_ids(true)
- .with_thread_names(true)
- .with_timer(tracing_subscriber::fmt::time::UtcTime::rfc_3339());
-
- tracing_subscriber::registry()
- .with(env_filter)
- .with(file_layer)
- .with(console_layer)
- .init();
-
- tracing::info!(
- log_file = %log_file_path.display(),
- "Logging initialized with rotating file"
- );
-
- Ok(LogGuard(guard))
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/main.rs b/packages/hoppscotch-agent/src-tauri/src/main.rs
deleted file mode 100644
index 146be728..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/main.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-// Prevents additional console window on Windows in release, DO NOT REMOVE!!
-#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
-
-use hoppscotch_agent_lib::{
- logger::{self, LogGuard},
- HOPPSCOTCH_AGENT_IDENTIFIER,
-};
-
-fn main() {
- // Follows how `tauri` does this and exactly matches desktop's approach
- // see: https://github.com/tauri-apps/tauri/blob/dev/crates/tauri/src/path/desktop.rs
- let path = {
- #[cfg(target_os = "macos")]
- let path =
- dirs::home_dir().map(|dir| dir.join("Library/Logs").join(HOPPSCOTCH_AGENT_IDENTIFIER));
-
- #[cfg(not(target_os = "macos"))]
- let path =
- dirs::data_local_dir().map(|dir| dir.join(HOPPSCOTCH_AGENT_IDENTIFIER).join("logs"));
-
- path
- };
-
- let Some(log_file_path) = path else {
- eprint!("Failed to setup logging!");
-
- println!("Starting Hoppscotch Agent...");
-
- return hoppscotch_agent_lib::run();
- };
-
- let Ok(LogGuard(guard)) = logger::setup(&log_file_path) else {
- eprint!("Failed to setup logging!");
-
- println!("Starting Hoppscotch Agent...");
-
- return hoppscotch_agent_lib::run();
- };
-
- // This keeps the guard alive, this is scoped to `main`
- // so it can only drop when the entire app exits,
- // so safe to have it like this.
- let _guard = guard;
-
- tracing::info!("Starting Hoppscotch Agent...");
-
- hoppscotch_agent_lib::run()
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/model.rs b/packages/hoppscotch-agent/src-tauri/src/model.rs
deleted file mode 100644
index 718422e9..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/model.rs
+++ /dev/null
@@ -1,110 +0,0 @@
-use chrono::{DateTime, Utc};
-use serde::{Deserialize, Serialize};
-use serde_json::Value;
-use sha2::{Digest, Sha256};
-
-/// Describes one registered app instance
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct Registration {
- pub registered_at: DateTime,
-
- /// base16 (lowercase) encoded shared secret that the client
- /// and agent established during registration that is used
- /// to encrypt traffic between them
- pub shared_secret_b16: String,
-}
-
-#[derive(Debug, Serialize, Deserialize)]
-pub struct MaskedRegistration {
- pub registered_at: DateTime,
- pub auth_key_hash: String,
-}
-
-impl From<(&String, &Registration)> for MaskedRegistration {
- fn from((key, registration): (&String, &Registration)) -> Self {
- let hash = Sha256::digest(key.as_bytes());
- let short_hash = base16::encode_lower(&hash[..3]);
-
- Self {
- registered_at: registration.registered_at,
- auth_key_hash: short_hash,
- }
- }
-}
-
-#[derive(Debug, Serialize)]
-pub struct RegistrationsList {
- pub registrations: Vec,
- pub total: usize,
-}
-
-/// Single instance payload.
-#[derive(Clone, Serialize)]
-pub struct Payload {
- args: Vec,
- cwd: String,
-}
-
-impl Payload {
- pub fn new(args: Vec, cwd: String) -> Self {
- Self { args, cwd }
- }
-}
-
-#[derive(Debug, Serialize, Deserialize)]
-pub struct HandshakeResponse {
- #[allow(non_snake_case)]
- pub __hoppscotch__agent__: bool,
-
- pub status: String,
- pub agent_version: String,
-}
-
-#[derive(Debug, Serialize, Deserialize)]
-pub struct ConfirmedRegistrationRequest {
- pub registration: String,
-
- /// base16 (lowercase) encoded public key shared by the client
- /// to the agent so that the agent can establish a shared secret
- /// which will be used to encrypt traffic between agent
- /// and client after registration
- pub client_public_key_b16: String,
-}
-
-#[derive(Debug, Serialize, Deserialize)]
-pub struct AuthKeyResponse {
- pub auth_key: String,
- pub created_at: DateTime,
-
- /// base16 (lowercase) encoded public key shared by the
- /// agent so that the client can establish a shared secret
- /// which will be used to encrypt traffic between agent
- /// and client after registration
- pub agent_public_key_b16: String,
-}
-
-/// A logger guard, managed by tauri runtime to make sure
-/// logger doesn't get cleaned up or dropped during app's run time.
-pub struct LogGuard(pub tracing_appender::non_blocking::WorkerGuard);
-
-#[derive(Debug, Deserialize)]
-pub struct LogEntry {
- pub timestamp: String,
- pub level: LogLevel,
- pub context: String,
- pub message: String,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub metadata: Option,
- pub source: String,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub correlation_id: Option,
-}
-
-#[derive(Debug, Deserialize, Clone, Copy)]
-#[serde(rename_all = "UPPERCASE")]
-pub enum LogLevel {
- Debug,
- Info,
- Warn,
- Error,
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/route.rs b/packages/hoppscotch-agent/src-tauri/src/route.rs
deleted file mode 100644
index e6362565..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/route.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-use axum::{
- routing::{delete, get, post},
- Router,
-};
-use std::sync::Arc;
-use tauri::AppHandle;
-
-use crate::{controller, state::AppState};
-
-pub fn route(state: Arc, app_handle: AppHandle) -> Router {
- Router::new()
- .route("/handshake", get(controller::handshake))
- .route(
- "/receive-registration",
- post(controller::receive_registration),
- )
- .route(
- "/verify-registration",
- post(controller::verify_registration),
- )
- .route(
- "/registered-handshake",
- get(controller::registered_handshake),
- )
- .route("/registration", get(controller::registration))
- .route(
- "/registrations/:auth_key",
- delete(controller::delete_registration),
- )
- .route("/execute", post(controller::execute))
- .route("/cancel/:req_id", post(controller::cancel))
- .route("/log-sink", post(controller::log_sink))
- .with_state((state, app_handle))
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/server.rs b/packages/hoppscotch-agent/src-tauri/src/server.rs
deleted file mode 100644
index 33818477..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/server.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-use axum::Router;
-use std::sync::Arc;
-use tokio_util::sync::CancellationToken;
-use tower_http::cors::CorsLayer;
-
-use crate::route;
-use crate::state::AppState;
-
-#[tracing::instrument(skip(state, cancellation_token, app_handle))]
-pub async fn run_server(
- state: Arc,
- cancellation_token: CancellationToken,
- app_handle: tauri::AppHandle,
-) {
- tracing::info!("Initializing server");
- let cors = CorsLayer::permissive();
-
- let app = Router::new()
- .merge(route::route(state, app_handle))
- .layer(cors);
-
- let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 9119));
- tracing::info!(address = %addr, "Starting server");
-
- match tokio::net::TcpListener::bind(&addr).await {
- Ok(listener) => {
- tracing::info!(address = %addr, "Server bound successfully");
-
- if let Err(e) = axum::serve(listener, app.into_make_service())
- .with_graceful_shutdown(async move {
- cancellation_token.cancelled().await;
- tracing::info!("Graceful shutdown initiated");
- })
- .await
- {
- tracing::error!(error = %e, "Server error occurred");
- return;
- }
-
- tracing::info!("Server shut down successfully");
- }
- Err(e) => {
- tracing::error!(
- error = %e,
- address = %addr,
- "Failed to bind server to address"
- );
- }
- }
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/state.rs b/packages/hoppscotch-agent/src-tauri/src/state.rs
deleted file mode 100644
index 4bd211fb..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/state.rs
+++ /dev/null
@@ -1,277 +0,0 @@
-use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit};
-use axum::body::Bytes;
-use dashmap::DashMap;
-use serde::de::DeserializeOwned;
-use tauri_plugin_store::StoreExt;
-use tokio::sync::RwLock;
-use tokio_util::sync::CancellationToken;
-
-use crate::{
- error::{AgentError, AgentResult},
- global::{AGENT_STORE, REGISTRATIONS},
- model::Registration,
-};
-
-#[derive(Debug, Default)]
-pub struct AppState {
- /// The active registration code that is being registered.
- pub active_registration_code: RwLock>,
-
- /// Cancellation Tokens for the running requests
- pub cancellation_tokens: DashMap,
-
- /// Registrations against the agent, the key is the auth
- /// token associated to the registration
- registrations: DashMap,
-}
-
-impl AppState {
- #[tracing::instrument(skip(app_handle))]
- pub fn new(app_handle: tauri::AppHandle) -> AgentResult {
- tracing::info!("Initializing application state");
- let store = match app_handle.store(AGENT_STORE) {
- Ok(store) => store,
- Err(e) => {
- tracing::error!("Failed to access app store: {}", e);
- return Err(e.into());
- }
- };
-
- // Try loading and parsing registrations from the store, if that failed,
- // load the default list
- let registrations = store
- .get(REGISTRATIONS)
- .and_then(|val| serde_json::from_value(val.clone()).ok())
- .unwrap_or_else(|| {
- tracing::debug!("No existing registrations found, initializing empty map");
- DashMap::new()
- });
-
- // Try to save the latest registrations list
- let _ = store.set(REGISTRATIONS, serde_json::to_value(®istrations)?);
-
- if let Err(e) = store.save() {
- tracing::error!("Failed to persist store changes: {}", e);
- return Err(e.into());
- }
-
- tracing::info!("Application state initialized successfully");
-
- Ok(Self {
- active_registration_code: RwLock::new(None),
- cancellation_tokens: DashMap::new(),
- registrations,
- })
- }
-
- /// Gets you a readonly reference to the registrations list
- /// NOTE: Although DashMap API allows you to update the list from an immutable
- /// reference, you shouldn't do it for registrations as `update_registrations`
- /// performs save operation that needs to be done and should be used instead
- #[tracing::instrument]
- pub fn get_registrations(&self) -> &DashMap {
- tracing::debug!("Retrieving registrations list");
- &self.registrations
- }
-
- /// Provides you an opportunity to update the registrations list
- /// and also persists the data to the disk.
- /// This function bypasses `store.reload()` to avoid issues from stale or inconsistent
- /// data on disk. By relying solely on the in-memory `self.registrations`,
- /// we make sure that updates are applied based on the most recent changes in memory.
- #[tracing::instrument(skip(self, app_handle, update_func))]
- pub fn update_registrations(
- &self,
- app_handle: tauri::AppHandle,
- update_func: impl FnOnce(&DashMap),
- ) -> Result<(), AgentError> {
- tracing::info!("Updating registrations");
- update_func(&self.registrations);
-
- let store = match app_handle.store(AGENT_STORE) {
- Ok(store) => store,
- Err(e) => {
- tracing::error!("Failed to access app store: {}", e);
- return Err(e.into());
- }
- };
-
- if store.has(REGISTRATIONS) {
- tracing::debug!("Clearing existing registrations from store");
- // We've confirmed `REGISTRATIONS` exists in the store
- if !store.delete(REGISTRATIONS) {
- tracing::error!("Failed to clear existing registrations");
- return Err(AgentError::RegistrationClearError);
- }
- } else {
- tracing::debug!("`REGISTRATIONS` key not found in store; continuing with update.");
- }
-
- // Since we've established `self.registrations` as the source of truth,
- // we avoid reloading the store from disk and instead choose to override it.
- match serde_json::to_value(self.registrations.clone()) {
- Ok(value) => {
- let _ = store.set(REGISTRATIONS, value);
- }
- Err(e) => {
- tracing::error!("Failed to serialize registrations: {}", e);
- return Err(e.into());
- }
- }
-
- // Explicitly save the changes
- if let Err(e) = store.save() {
- tracing::error!("Failed to persist store changes: {}", e);
- return Err(e.into());
- }
-
- tracing::info!("Registrations updated successfully");
- Ok(())
- }
-
- /// Clear all the registrations
- #[tracing::instrument(skip(self, app_handle))]
- pub fn clear_registrations(&self, app_handle: tauri::AppHandle) -> Result<(), AgentError> {
- tracing::info!("Clearing all registrations");
- self.update_registrations(app_handle, |registrations| registrations.clear())?;
- tracing::info!("All registrations cleared successfully");
- Ok(())
- }
-
- #[tracing::instrument(skip(self))]
- pub async fn clear_active_registration(&self) {
- tracing::debug!("Clearing active registration code");
- let mut active_registration_code = self.active_registration_code.write().await;
- *active_registration_code = None;
- tracing::debug!("Active registration code cleared");
- }
-
- #[tracing::instrument(skip(self))]
- pub async fn validate_registration(&self, registration: &str) -> bool {
- tracing::debug!("Validating registration code");
- let is_valid = self.active_registration_code.read().await.as_deref() == Some(registration);
- if is_valid {
- tracing::info!("Registration code validated successfully");
- } else {
- tracing::warn!("Invalid registration code provided");
- }
- is_valid
- }
-
- #[tracing::instrument(skip(self))]
- pub fn remove_cancellation_token(&self, req_id: usize) -> Option<(usize, CancellationToken)> {
- tracing::debug!(req_id, "Removing cancellation token");
- let result = self.cancellation_tokens.remove(&req_id);
- if result.is_some() {
- tracing::info!(req_id, "Cancellation token removed successfully");
- } else {
- tracing::debug!(req_id, "No cancellation token found to remove");
- }
- result
- }
-
- #[tracing::instrument(skip(self))]
- pub fn add_cancellation_token(&self, req_id: usize, cancellation_token: CancellationToken) {
- tracing::debug!(req_id, "Adding new cancellation token");
- self.cancellation_tokens.insert(req_id, cancellation_token);
- tracing::debug!(req_id, "Cancellation token added successfully");
- }
-
- #[tracing::instrument(skip(self))]
- pub fn validate_access(&self, auth_key: &str) -> bool {
- tracing::debug!(auth_key, "Validating access");
- let is_valid = self.registrations.get(auth_key).is_some();
- if is_valid {
- tracing::info!(auth_key, "Access validated successfully");
- } else {
- tracing::warn!(auth_key, "Invalid access attempt");
- }
- is_valid
- }
-
- #[tracing::instrument(skip(self, data))]
- pub fn validate_access_and_get_data(
- &self,
- auth_key: &str,
- nonce: &str,
- data: &Bytes,
- ) -> Option
- where
- T: DeserializeOwned,
- {
- tracing::debug!(
- auth_key,
- nonce_len = nonce.len(),
- "Validating access and decrypting data"
- );
-
- let registration = match self.registrations.get(auth_key) {
- Some(reg) => reg,
- None => {
- tracing::warn!(auth_key, "Registration not found");
- return None;
- }
- };
-
- let key: [u8; 32] = match base16::decode(®istration.shared_secret_b16).ok()?[0..32]
- .try_into()
- .ok()
- {
- Some(k) => k,
- None => {
- tracing::error!(auth_key, "Failed to decode shared secret");
- return None;
- }
- };
-
- let nonce: [u8; 12] = match base16::decode(nonce).ok()?[0..12].try_into().ok() {
- Some(n) => n,
- None => {
- tracing::error!(auth_key, "Failed to decode nonce");
- return None;
- }
- };
-
- let cipher = Aes256Gcm::new(&key.into());
- let data = data.iter().cloned().collect::>();
-
- let plain_data = match cipher.decrypt(&nonce.into(), data.as_slice()) {
- Ok(d) => d,
- Err(e) => {
- tracing::error!(auth_key, error = ?e, "Decryption failed");
- return None;
- }
- };
-
- match serde_json::from_reader(plain_data.as_slice()) {
- Ok(result) => {
- tracing::info!(auth_key, "Data successfully decrypted and parsed");
- Some(result)
- }
- Err(e) => {
- tracing::error!(auth_key, error = ?e, "Failed to parse decrypted data");
- None
- }
- }
- }
-
- #[tracing::instrument(skip(self))]
- pub fn get_registration(&self, auth_key: &str) -> Option {
- tracing::debug!(auth_key, "Retrieving registration tracing::info");
- let result = self
- .registrations
- .get(auth_key)
- .map(|reference| reference.value().clone());
-
- if result.is_some() {
- tracing::info!(
- auth_key,
- "Registration tracing::info retrieved successfully"
- );
- } else {
- tracing::debug!(auth_key, "No registration tracing::info found");
- }
-
- result
- }
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/tray.rs b/packages/hoppscotch-agent/src-tauri/src/tray.rs
deleted file mode 100644
index 5ae79009..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/tray.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-use crate::{show_main_window, state::AppState};
-use lazy_static::lazy_static;
-use std::sync::Arc;
-use tauri::{
- image::Image,
- menu::{MenuBuilder, MenuItem},
- tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
- AppHandle, Emitter, Manager,
-};
-
-const TRAY_ICON_DATA: &'static [u8] = include_bytes!("../icons/tray_icon.png");
-
-lazy_static! {
- static ref TRAY_ICON: Image<'static> = Image::from_bytes(TRAY_ICON_DATA).unwrap();
-}
-
-pub fn create_tray(app: &AppHandle) -> tauri::Result<()> {
- let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
- let clear_registrations = MenuItem::with_id(
- app,
- "clear_registrations",
- "Clear Registrations",
- true,
- None::<&str>,
- )?;
- let maximize_window = MenuItem::with_id(
- app,
- "maximize_window",
- "Maximize Window",
- true,
- None::<&str>,
- )?;
- let show_registrations = MenuItem::with_id(
- app,
- "show_registrations",
- "Show Registrations",
- true,
- None::<&str>,
- )?;
-
- let pkg_info = app.package_info();
- let app_name = pkg_info.name.clone();
- let app_version = pkg_info.version.clone();
-
- let app_name_item = MenuItem::with_id(app, "app_name", app_name, false, None::<&str>)?;
- let app_version_item = MenuItem::with_id(
- app,
- "app_version",
- format!("Version: {}", app_version),
- false,
- None::<&str>,
- )?;
-
- let menu = MenuBuilder::new(app)
- .item(&app_name_item)
- .item(&app_version_item)
- .separator()
- .item(&maximize_window)
- .separator()
- .item(&clear_registrations)
- .item(&show_registrations)
- .separator()
- .separator()
- .item(&quit_i)
- .build()?;
-
- let _ = TrayIconBuilder::with_id("hopp-tray")
- .tooltip("Hoppscotch Agent")
- .icon(if cfg!(target_os = "macos") {
- TRAY_ICON.clone()
- } else {
- app.default_window_icon().unwrap().clone()
- })
- .icon_as_template(cfg!(target_os = "macos"))
- .menu(&menu)
- .show_menu_on_left_click(true)
- .on_menu_event(move |app, event| match event.id.as_ref() {
- "quit" => {
- tracing::info!("Exiting the agent...");
- // Exit with a specific code to allow actual exit.
- app.exit(1);
- }
- "clear_registrations" => {
- let app_state = app.state::>();
-
- app_state
- .clear_registrations(app.clone())
- .expect("Invariant violation: Failed to clear registrations");
- }
- "show_registrations" => {
- app.emit("show-registrations", ()).unwrap_or_else(|e| {
- tracing::error!("Failed to emit show-registrations event: {}", e);
- });
- if let Err(e) = show_main_window(&app) {
- tracing::error!("Failed to show window: {}", e);
- }
- }
- "maximize_window" => {
- app.emit("maximize-window", ()).unwrap_or_else(|e| {
- tracing::error!("Failed to emit maximize-window event: {}", e);
- });
- if let Err(e) = show_main_window(&app) {
- tracing::error!("Failed to maximize window: {}", e);
- }
- }
- _ => {
- tracing::warn!("Unhandled menu event: {:?}", event.id);
- }
- })
- .on_tray_icon_event(|tray, event| {
- if let TrayIconEvent::Click {
- button: MouseButton::Left,
- button_state: MouseButtonState::Up,
- ..
- } = event
- {
- let app = tray.app_handle();
- if let Err(e) = show_main_window(&app) {
- tracing::error!("Failed to show window from tray: {}", e);
- }
- }
- })
- .build(app);
-
- Ok(())
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/updater.rs b/packages/hoppscotch-agent/src-tauri/src/updater.rs
deleted file mode 100644
index 48c6d2ad..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/updater.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-use tauri::Manager;
-use tauri_plugin_dialog::DialogExt;
-use tauri_plugin_dialog::MessageDialogButtons;
-use tauri_plugin_dialog::MessageDialogKind;
-
-#[cfg(feature = "portable")]
-use {crate::dialog, crate::util, native_dialog::MessageType};
-
-pub async fn check_and_install_updates(
- app: tauri::AppHandle,
- updater: tauri_plugin_updater::Updater,
-) {
- let update = updater.check().await;
-
- if let Ok(Some(update)) = update {
- #[cfg(not(feature = "portable"))]
- {
- let do_update = app
- .dialog()
- .message(format!(
- "Update to {} is available!{}",
- update.version,
- update
- .body
- .clone()
- .map(|body| format!("\n\nRelease Notes: {}", body))
- .unwrap_or("".into())
- ))
- .title("Hoppscotch Agent Update Available")
- .kind(MessageDialogKind::Info)
- .buttons(MessageDialogButtons::OkCancelCustom(
- "Update".to_string(),
- "Cancel".to_string(),
- ))
- .blocking_show();
-
- if do_update {
- let _ = update.download_and_install(|_, _| {}, || {}).await;
-
- tauri::process::restart(&app.env());
- }
- }
- #[cfg(feature = "portable")]
- {
- let download_url = "https://hoppscotch.com/download";
- let message = format!(
- "An update (version {}) is available for the Hoppscotch Agent.\n\nPlease download the latest portable version from our website.",
- update.version
- );
-
- dialog::info(&message);
-
- if dialog::confirm(
- "Open Download Page",
- "Would you like to open the download page in your browser?",
- MessageType::Info,
- ) {
- if let None = util::open_link(download_url) {
- dialog::error(&format!(
- "Failed to open download page. Please visit {}",
- download_url
- ));
- }
- }
- }
- }
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/util.rs b/packages/hoppscotch-agent/src-tauri/src/util.rs
deleted file mode 100644
index 56b3fb02..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/util.rs
+++ /dev/null
@@ -1,94 +0,0 @@
-use std::process::{Command, Stdio};
-
-use aes_gcm::{aead::Aead, AeadCore, Aes256Gcm, KeyInit};
-use axum::{
- body::Body,
- response::{IntoResponse, Response},
-};
-use rand::rngs::OsRng;
-use serde::Serialize;
-use sha2::{Digest, Sha256};
-
-use crate::global::NONCE;
-
-pub fn generate_auth_key_hash(auth_key: &str) -> String {
- let hash = Sha256::digest(auth_key.as_bytes());
- base16::encode_lower(&hash[..3])
-}
-
-pub fn open_link(link: &str) -> Option<()> {
- let null = Stdio::null();
-
- #[cfg(target_os = "windows")]
- {
- Command::new("rundll32")
- .args(["url.dll,FileProtocolHandler", link])
- .stdout(null)
- .spawn()
- .ok()
- .map(|_| ())
- }
-
- #[cfg(target_os = "macos")]
- {
- Command::new("open")
- .arg(link)
- .stdout(null)
- .spawn()
- .ok()
- .map(|_| ())
- }
-
- #[cfg(target_os = "linux")]
- {
- Command::new("xdg-open")
- .arg(link)
- .stdout(null)
- .spawn()
- .ok()
- .map(|_| ())
- }
-
- #[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
- {
- None
- }
-}
-
-#[derive(Debug)]
-pub struct EncryptedJson {
- pub key_b16: String,
- pub data: T,
-}
-
-impl IntoResponse for EncryptedJson
-where
- T: Serialize,
-{
- fn into_response(self) -> Response {
- let serialized_response = serde_json::to_vec(&self.data)
- .expect("Failed serializing response to vec for encryption");
-
- let key: [u8; 32] = base16::decode(&self.key_b16).unwrap()[0..32]
- .try_into()
- .unwrap();
-
- let cipher = Aes256Gcm::new(&key.into());
-
- let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
-
- let nonce_b16 = base16::encode_lower(&nonce);
-
- let encrypted_response = cipher
- .encrypt(&nonce, serialized_response.as_slice())
- .expect("Failed encrypting response");
-
- let mut response = Response::new(Body::from(encrypted_response));
- let response_headers = response.headers_mut();
-
- response_headers.insert("Content-Type", "application/octet-stream".parse().unwrap());
- response_headers.insert(NONCE, nonce_b16.parse().unwrap());
-
- response
- }
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/webview/error.rs b/packages/hoppscotch-agent/src-tauri/src/webview/error.rs
deleted file mode 100644
index 7bfeff52..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/webview/error.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-use std::io;
-
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-pub enum WebViewError {
- #[error("Failed to open URL: {0}")]
- UrlOpen(#[from] io::Error),
- #[error("Failed to download WebView2 installer: {0}")]
- Download(String),
- #[error("WebView2 installation failed: {0}")]
- Installation(String),
- #[error("Failed during request: {0}")]
- Request(#[from] tauri_plugin_http::reqwest::Error),
-}
diff --git a/packages/hoppscotch-agent/src-tauri/src/webview/mod.rs b/packages/hoppscotch-agent/src-tauri/src/webview/mod.rs
deleted file mode 100644
index b303b056..00000000
--- a/packages/hoppscotch-agent/src-tauri/src/webview/mod.rs
+++ /dev/null
@@ -1,212 +0,0 @@
-/// The WebView2 Runtime is a critical dependency for Tauri applications on Windows.
-/// We need to check for its presence, see [Source: GitHub Issue #59 - Portable windows build](https://github.com/tauri-apps/tauri-action/issues/59#issuecomment-827142638)
-///
-/// > "Tauri requires an installer if you define app resources, external binaries or running on environments that do not have Webview2 runtime installed. So I don't think it's a good idea to have a "portable" option since a Tauri binary itself isn't 100% portable."
-///
-/// The approach for checking WebView2 installation is based on Microsoft's official documentation, which states:
-///
-/// > ###### Detect if a WebView2 Runtime is already installed
-/// >
-/// > To verify that a WebView2 Runtime is installed, use one of the following approaches:
-/// >
-/// > * Approach 1: Inspect the `pv (REG_SZ)` regkey for the WebView2 Runtime at both of the following registry locations. The `HKEY_LOCAL_MACHINE` regkey is used for _per-machine_ install. The `HKEY_CURRENT_USER` regkey is used for _per-user_ install.
-/// >
-/// > For WebView2 applications, at least one of these regkeys must be present and defined with a version greater than 0.0.0.0. If neither regkey exists, or if only one of these regkeys exists but its value is `null`, an empty string, or 0.0.0.0, this means that the WebView2 Runtime isn't installed on the client. Inspect these regkeys to detect whether the WebView2 Runtime is installed, and to get the version of the WebView2 Runtime. Find `pv (REG_SZ)` at the following two locations.
-/// >
-/// > The two registry locations to inspect on 64-bit Windows:
-/// >
-/// > ```
-/// > HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}
-/// >
-/// > HKEY_CURRENT_USER\Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}
-/// > ```
-/// >
-/// > The two registry locations to inspect on 32-bit Windows:
-/// >
-/// > ```
-/// > HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}
-/// >
-/// > HKEY_CURRENT_USER\Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}
-/// > ```
-/// >
-/// > * Approach 2: Run [GetAvailableCoreWebView2BrowserVersionString](/microsoft-edge/webview2/reference/win32/webview2-idl#getavailablecorewebview2browserversionstring) and evaluate whether the `versionInfo` is `nullptr`. `nullptr` indicates that the WebView2 Runtime isn't installed. This API returns version information for the WebView2 Runtime or for any installed preview channels of Microsoft Edge (Beta, Dev, or Canary).
-///
-/// See: https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution?tabs=dotnetcsharp#detect-if-a-webview2-runtime-is-already-installed
-///
-/// Our implementation uses Approach 1, checking both the 32-bit (WOW6432Node) and 64-bit registry locations
-/// to make sure we have critical dependency compatibility with different system architectures.
-pub mod error;
-
-use std::{io, ops::Not};
-
-use native_dialog::MessageType;
-
-use crate::{dialog, util};
-use error::WebViewError;
-
-#[cfg(windows)]
-use {
- std::io::Cursor,
- std::process::Command,
- tauri_plugin_http::reqwest,
- tempfile::TempDir,
- winreg::{
- enums::{HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE},
- RegKey,
- },
-};
-
-const TAURI_WEBVIEW_REF: &str = "https://v2.tauri.app/references/webview-versions/";
-const WINDOWS_WEBVIEW_REF: &str =
- "https://developer.microsoft.com/microsoft-edge/webview2/#download-section";
-
-fn is_available() -> bool {
- #[cfg(windows)]
- {
- const KEY_WOW64: &str = r"SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}";
- const KEY: &str =
- r"SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}";
-
- let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
- let hkcu = RegKey::predef(HKEY_CURRENT_USER);
-
- [
- hklm.open_subkey(KEY_WOW64),
- hkcu.open_subkey(KEY_WOW64),
- hklm.open_subkey(KEY),
- hkcu.open_subkey(KEY),
- ]
- .into_iter()
- .any(|result| result.is_ok())
- }
-
- #[cfg(not(windows))]
- {
- true
- }
-}
-
-fn open_install_website() -> Result<(), WebViewError> {
- let url = if cfg!(windows) {
- WINDOWS_WEBVIEW_REF
- } else {
- TAURI_WEBVIEW_REF
- };
-
- util::open_link(url).map(|_| ()).ok_or_else(|| {
- WebViewError::UrlOpen(io::Error::new(
- io::ErrorKind::Other,
- "Failed to open browser to WebView download section",
- ))
- })
-}
-
-#[cfg(windows)]
-async fn install() -> Result<(), WebViewError> {
- const WEBVIEW2_BOOTSTRAPPER_URL: &str = "https://go.microsoft.com/fwlink/p/?LinkId=2124703";
- const DEFAULT_FILENAME: &str = "MicrosoftEdgeWebview2Setup.exe";
-
- let client = reqwest::Client::builder()
- .user_agent("Hoppscotch Agent")
- .gzip(true)
- .build()?;
-
- let response = client.get(WEBVIEW2_BOOTSTRAPPER_URL).send().await?;
-
- if !response.status().is_success() {
- return Err(WebViewError::Download(format!(
- "Failed to download WebView2 bootstrapper. Status: {}",
- response.status()
- )));
- }
-
- let filename =
- get_filename_from_response(&response).unwrap_or_else(|| DEFAULT_FILENAME.to_owned());
-
- let tmp_dir = TempDir::with_prefix("WebView-setup-")?;
- let installer_path = tmp_dir.path().join(filename);
-
- let content = response.bytes().await?;
- {
- let mut file = std::fs::File::create(&installer_path)?;
- io::copy(&mut Cursor::new(content), &mut file)?;
- }
-
- let status = Command::new(&installer_path).args(["/install"]).status()?;
-
- if !status.success() {
- return Err(WebViewError::Installation(format!(
- "Installer exited with code `{}`.",
- status.code().unwrap_or(-1)
- )));
- }
-
- Ok(())
-}
-
-#[cfg(windows)]
-fn get_filename_from_response(response: &reqwest::Response) -> Option {
- response
- .headers()
- .get("content-disposition")
- .and_then(|value| value.to_str().ok())
- .and_then(|value| value.split("filename=").last())
- .map(|name| name.trim().replace('\"', ""))
- .or_else(|| {
- response
- .url()
- .path_segments()
- .and_then(|segments| segments.last())
- .map(|name| name.to_string())
- })
- .filter(|name| !name.is_empty())
-}
-
-#[cfg(not(windows))]
-async fn install() -> Result<(), WebViewError> {
- Err(WebViewError::Installation(
- "Unable to auto-install WebView. Please refer to https://v2.tauri.app/references/webview-versions/".to_string(),
- ))
-}
-
-pub fn init_webview() {
- if is_available() {
- return;
- }
-
- if dialog::confirm(
- "WebView Error",
- "WebView is required for this application to work.\n\n\
- Do you want to install it?",
- MessageType::Error,
- )
- .not()
- {
- tracing::warn!("Declined to setup WebView.");
-
- std::process::exit(1);
- }
-
- if let Err(e) = tauri::async_runtime::block_on(install()) {
- dialog::error(&format!(
- "Failed to install WebView: {}\n\n\
- Please install it manually from webpage that should open when you click 'Ok'.\n\n\
- If that doesn't work, please visit Microsoft Edge Webview2 download section.",
- e
- ));
-
- if let Err(e) = open_install_website() {
- tracing::warn!("Failed to launch WebView website:\n{}", e);
- }
-
- std::process::exit(1);
- }
-
- if is_available().not() {
- dialog::panic(
- "Unable to setup WebView:\n\n\
- Please install it manually and relaunch the application.\n\
- https://developer.microsoft.com/microsoft-edge/webview2/#download-section",
- );
- }
-}
diff --git a/packages/hoppscotch-agent/src-tauri/tauri.conf.json b/packages/hoppscotch-agent/src-tauri/tauri.conf.json
deleted file mode 100644
index d23437e4..00000000
--- a/packages/hoppscotch-agent/src-tauri/tauri.conf.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "$schema": "https://schema.tauri.app/config/2.0.0-rc",
- "productName": "Hoppscotch Agent",
- "version": "0.1.17",
- "identifier": "io.hoppscotch.agent",
- "build": {
- "beforeDevCommand": "pnpm dev",
- "devUrl": "http://127.0.0.1:1420",
- "beforeBuildCommand": "pnpm build",
- "frontendDist": "../dist"
- },
- "app": {
- "windows": [
- {
- "title": "Hoppscotch Agent",
- "width": 600,
- "height": 400,
- "center": true,
- "resizable": false,
- "maximizable": false,
- "minimizable": false,
- "focus": true,
- "alwaysOnTop": true,
- "create": false
- }
- ],
- "security": {
- "csp": null
- }
- },
- "bundle": {
- "active": true,
- "targets": "all",
- "icon": [
- "icons/32x32.png",
- "icons/128x128.png",
- "icons/128x128@2x.png",
- "icons/icon.icns",
- "icons/icon.ico"
- ],
- "createUpdaterArtifacts": true
- },
- "plugins": {
- "updater": {
- "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDRBQzgxQjc3MzJCMjZENEMKUldSTWJiSXlkeHZJU3EvQW1abFVlREVhRDNlM0ZhOVJYaHN4M0FpbXZhcUFzSVdVbG84RWhPa1AK",
- "endpoints": ["https://releases.hoppscotch.com/hoppscotch-agent.json"]
- }
- }
-}
diff --git a/packages/hoppscotch-agent/src-tauri/tauri.portable.conf.json b/packages/hoppscotch-agent/src-tauri/tauri.portable.conf.json
deleted file mode 100644
index 657477e9..00000000
--- a/packages/hoppscotch-agent/src-tauri/tauri.portable.conf.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "$schema": "https://schema.tauri.app/config/2.0.0-rc",
- "productName": "Hoppscotch Agent Portable",
- "version": "0.1.17",
- "identifier": "io.hoppscotch.agent",
- "build": {
- "beforeDevCommand": "pnpm dev",
- "devUrl": "http://localhost:1420",
- "beforeBuildCommand": "pnpm build",
- "frontendDist": "../dist"
- },
- "app": {
- "windows": [
- {
- "title": "Hoppscotch Agent Portable",
- "width": 600,
- "height": 400,
- "center": true,
- "resizable": false,
- "maximizable": false,
- "minimizable": false,
- "focus": true,
- "alwaysOnTop": true,
- "create": false
- }
- ],
- "security": {
- "csp": null
- }
- },
- "bundle": {
- "active": false,
- "targets": "all",
- "icon": [
- "icons/32x32.png",
- "icons/128x128.png",
- "icons/128x128@2x.png",
- "icons/icon.icns",
- "icons/icon.ico"
- ],
- "createUpdaterArtifacts": false
- },
- "plugins": {
- "updater": {
- "active": false
- }
- }
-}
diff --git a/packages/hoppscotch-agent/src/App.vue b/packages/hoppscotch-agent/src/App.vue
deleted file mode 100644
index ee370573..00000000
--- a/packages/hoppscotch-agent/src/App.vue
+++ /dev/null
@@ -1,228 +0,0 @@
-
-
-
{{ pipe(state(), getTitle) }}
-
-
-
-
- An app is trying to register against the Hoppscotch Agent. If this was
- intentional, copy the given code into the app to complete the
- registration process. Please cancel the registration if you did not
- initiate this request. The window will hide automatically once
- registration succeeds. If you minimize this window during
- registration, you can access it again from the tray by selecting
- "Maximize Window".
-
-
- {{
- pipe(
- state().otp,
- O.getOrElse(() => "")
- )
- }}
-
-
-
-
-
-
-
- {{
- formatDate(String(item.registered_at))
- }}
-
-
-
-
-
-
-
-
-
diff --git a/packages/hoppscotch-agent/src/index.css b/packages/hoppscotch-agent/src/index.css
deleted file mode 100644
index b5c61c95..00000000
--- a/packages/hoppscotch-agent/src/index.css
+++ /dev/null
@@ -1,3 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
diff --git a/packages/hoppscotch-agent/src/main.ts b/packages/hoppscotch-agent/src/main.ts
deleted file mode 100644
index a1a836ca..00000000
--- a/packages/hoppscotch-agent/src/main.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { createApp } from "vue"
-import App from "./App.vue"
-import "./index.css"
-
-import { plugin as HoppUI } from "@hoppscotch/ui"
-
-import "@hoppscotch/ui/themes.css"
-
-import "@hoppscotch/ui/style.css"
-
-createApp(App).use(HoppUI).mount("#app")
diff --git a/packages/hoppscotch-agent/src/pages/otp.vue b/packages/hoppscotch-agent/src/pages/otp.vue
deleted file mode 100644
index dfee5bb2..00000000
--- a/packages/hoppscotch-agent/src/pages/otp.vue
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
Agent Registration Request
-
-
- An app is trying to register against the Hoppscotch Agent. If this was
- intentional, copy the given code into the app to complete the
- registration process. Please hide the window if you did not initiate
- this request. Do not hide this window until the verification code is
- entered. The window will hide automatically once done.
-
-
- {{ otpCode }}
-
-
-
-
Waiting for registration requests...
-
- You can hide this window and access it again from the tray icon.
-
-
-
-
-
-
-
diff --git a/packages/hoppscotch-agent/src/pages/registrations.vue b/packages/hoppscotch-agent/src/pages/registrations.vue
deleted file mode 100644
index 37eea795..00000000
--- a/packages/hoppscotch-agent/src/pages/registrations.vue
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
Agent Registrations
-
-
- {{
- formatDate(item.registered_at)
- }}
-
-
-
-
-
-
-
-
-
diff --git a/packages/hoppscotch-agent/src/vite-env.d.ts b/packages/hoppscotch-agent/src/vite-env.d.ts
deleted file mode 100644
index fc812394..00000000
--- a/packages/hoppscotch-agent/src/vite-env.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-///
-
-declare module "*.vue" {
- import type { DefineComponent } from "vue";
- const component: DefineComponent<{}, {}, any>;
- export default component;
-}
diff --git a/packages/hoppscotch-agent/tailwind.config.js b/packages/hoppscotch-agent/tailwind.config.js
deleted file mode 100644
index 8d2a79d6..00000000
--- a/packages/hoppscotch-agent/tailwind.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import preset from '@hoppscotch/ui/ui-preset'
-
-export default {
- content: ['src/**/*.{vue,html}'],
- presets: [preset]
-}
diff --git a/packages/hoppscotch-agent/tsconfig.json b/packages/hoppscotch-agent/tsconfig.json
deleted file mode 100644
index f82888f3..00000000
--- a/packages/hoppscotch-agent/tsconfig.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2020",
- "useDefineForClassFields": true,
- "module": "ESNext",
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
- "skipLibCheck": true,
-
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "preserve",
-
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
- },
- "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
- "references": [{ "path": "./tsconfig.node.json" }]
-}
diff --git a/packages/hoppscotch-agent/tsconfig.node.json b/packages/hoppscotch-agent/tsconfig.node.json
deleted file mode 100644
index 42872c59..00000000
--- a/packages/hoppscotch-agent/tsconfig.node.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "compilerOptions": {
- "composite": true,
- "skipLibCheck": true,
- "module": "ESNext",
- "moduleResolution": "bundler",
- "allowSyntheticDefaultImports": true
- },
- "include": ["vite.config.ts"]
-}
diff --git a/packages/hoppscotch-agent/vite.config.ts b/packages/hoppscotch-agent/vite.config.ts
deleted file mode 100644
index 002646ef..00000000
--- a/packages/hoppscotch-agent/vite.config.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { defineConfig } from "vite";
-import vue from "@vitejs/plugin-vue";
-import tailwindcss from 'tailwindcss';
-import autoprefixer from 'autoprefixer';
-import path from 'path';
-import Icons from "unplugin-icons/vite";
-import IconsResolver from 'unplugin-icons/resolver';
-import Components from 'unplugin-vue-components/vite';
-
-const host = process.env.TAURI_DEV_HOST;
-
-// https://vitejs.dev/config/
-export default defineConfig(async () => ({
- plugins: [
- vue(),
- Icons({ compiler: 'vue3' }),
- Components({
- resolvers: [
- IconsResolver({
- prefix: '' // optional, default is 'i'
- })
- ]
- })
- ],
- css: {
- postcss: {
- plugins: [
- tailwindcss,
- autoprefixer,
- ],
- },
- },
- resolve: {
- alias: {
- '@': path.resolve(__dirname, './src')
- }
- },
- // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
- //
- // 1. prevent vite from obscuring rust errors
- clearScreen: false,
- // 2. tauri expects a fixed port, fail if that port is not available
- server: {
- port: 1420,
- strictPort: true,
- host: '127.0.0.1',
- hmr: host
- ? {
- protocol: "ws",
- host,
- port: 1421,
- }
- : undefined,
- watch: {
- // 3. tell vite to ignore watching `src-tauri`
- ignored: ["**/src-tauri/**"],
- },
- },
-}));
diff --git a/packages/hoppscotch-cli/.gitignore b/packages/hoppscotch-cli/.gitignore
deleted file mode 100644
index a0bc82af..00000000
--- a/packages/hoppscotch-cli/.gitignore
+++ /dev/null
@@ -1,146 +0,0 @@
-
-# Created by https://www.toptal.com/developers/gitignore/api/node
-# Edit at https://www.toptal.com/developers/gitignore?templates=node
-
-### Node ###
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-.pnpm-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# Snowpack dependency directory (https://snowpack.dev/)
-web_modules/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variables file
-.env
-.env.test
-.env.production
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-out
-
-# Nuxt.js build / generate output
-.nuxt
-dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v2
-.yarn/cache
-.yarn/unplugged
-.yarn/build-state.yml
-.yarn/install-state.gz
-.pnp.*
-
-# End of https://www.toptal.com/developers/gitignore/api/node
-
-# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode
-# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode
-
-### VisualStudioCode ###
-.vscode/*
-!.vscode/settings.json
-!.vscode/tasks.json
-!.vscode/launch.json
-!.vscode/extensions.json
-*.code-workspace
-
-# Local History for Visual Studio Code
-.history/
-
-### VisualStudioCode Patch ###
-# Ignore all local history of files
-.history
-.ionide
-
-# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode
diff --git a/packages/hoppscotch-cli/.prettierrc b/packages/hoppscotch-cli/.prettierrc
deleted file mode 100644
index 5c6bc947..00000000
--- a/packages/hoppscotch-cli/.prettierrc
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "semi": true,
- "trailingComma": "es5",
- "singleQuote": false,
- "printWidth": 80,
- "useTabs": false,
- "tabWidth": 2
-}
diff --git a/packages/hoppscotch-cli/CONTRIBUTING.md b/packages/hoppscotch-cli/CONTRIBUTING.md
deleted file mode 100644
index 15d6bc80..00000000
--- a/packages/hoppscotch-cli/CONTRIBUTING.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# Contributing
-
-When contributing to this repository, please first discuss the change you wish to make via issue,
-email, or any other method with the owners of this repository before making a change.
-
-Please note we have a code of conduct, please follow it in all your interactions with the project.
-
-## Pull Request Process
-
-1. Ensure any install or build dependencies are removed before the end of the layer when doing a
- build.
-2. Update the README.md with details of changes to the interface, this includes new environment
- variables, exposed ports, useful file locations and container parameters.
-3. Increase the version numbers in any examples files and the README.md to the new version that this
- Pull Request would represent. The versioning scheme we use is [SemVer](https://semver.org).
-4. You may merge the Pull Request once you have the sign-off of two other developers, or if you
- do not have permission to do that, you may request the second reviewer merge it for you.
-
-## Set Up The Development Environment
-
-1. After cloning the repository, execute the following commands:
-
- ```bash
- pnpm install
- pnpm run build
- ```
-
-2. In order to test locally, you can use two types of package linking:
-
- 1. The 'pnpm exec' way (preferred since it does not hamper your original installation of the CLI):
-
- ```bash
- pnpm link @hoppscotch/cli
-
- // Then to use or test the CLI:
- pnpm exec hopp
-
- // After testing, to remove the package linking:
- pnpm rm @hoppscotch/cli
- ```
-
- 2. The 'global' way (warning: this might override the globally installed CLI, if exists):
-
- ```bash
- sudo pnpm link --global
-
- // Then to use or test the CLI:
- hopp
-
- // After testing, to remove the package linking:
- sudo pnpm rm --global @hoppscotch/cli
- ```
-
-3. To use the Typescript watch scripts:
- ```bash
- pnpm run dev
- ```
diff --git a/packages/hoppscotch-cli/README.md b/packages/hoppscotch-cli/README.md
deleted file mode 100644
index 8a36a420..00000000
--- a/packages/hoppscotch-cli/README.md
+++ /dev/null
@@ -1,211 +0,0 @@
-# Hoppscotch CLI ALPHA
-
-A CLI to run Hoppscotch Test Scripts in CI environments.
-
-### **Commands:**
-
-- `hopp test [options] [file]`: testing hoppscotch collection.json file
-
-### **Usage:**
-
-```bash
-hopp [options or commands] arguments
-```
-
-### **Options:**
-
-- `-v`, `--ver`: see the current version of the CLI
-- `-h`, `--help`: display help for command
-
-## **Command Descriptions:**
-
-1. #### **`hopp -v` / `hopp --ver`**
-
- - Prints out the current version of the Hoppscotch CLI
-
-2. #### **`hopp -h` / `hopp --help`**
-
- - Displays the help text
-
-3. #### **`hopp test [options] `**
-
- - Interactive CLI to accept Hoppscotch collection JSON path
- - Parses the collection JSON and executes each requests
- - Executes pre-request script.
- - Outputs the response of each request.
- - Executes and outputs test-script response.
-
- #### Options:
-
- ##### `-e, --env `
-
- - Accepts path to env.json with contents in below format:
-
- ```json
- {
- "ENV1": "value1",
- "ENV2": "value2"
- }
- ```
-
- - You can now access those variables using `pw.env.get('')`
-
- Taking the above example, `pw.env.get("ENV1")` will return `"value1"`
-
- #### `-d, --delay `
-
- - Used to defer the execution of requests in a collection.
-
- #### `--token `
-
- - Expects a personal access token to be passed for establishing connection with your Hoppscotch account.
-
- #### `--server `
-
- - URL of your self-hosted instance, if your collections are on a self-hosted instance.
-
- #### `--reporter-junit [path]`
-
- - Expects a file path to store the JUnit Report.
-
- ##### `--iteration-count `
-
- - Accepts the number of iterations to run the collection
-
- ##### `--iteration-data `
-
- - Accepts the path to a CSV file with contents in the below format:
-
- ```text
- key1,key2,key3
- value1,value2,value3
- value4,value5,value6
- ```
-
- For every iteration the values will be replaced with the respective keys in the environment. For iteration 1 the value1,value2,value3 will be replaced and for iteration 2 value4,value5,value6 will be replaced and so on.
-
- #### `--legacy-sandbox`
-
- - Opt out from the experimental scripting sandbox.
-
-## Versioning
-
-The Hoppscotch CLI follows **pre-1.0 semantic versioning** conventions while in alpha (version `< 1.0.0`):
-
-- **Feature releases** (e.g., `0.20.0` → `0.21.0`): New features, enhancements, or improvements
-- **Patch releases** (e.g., `0.20.0` → `0.20.1`): Bug fixes, security patches, and minor improvements
-- **Breaking changes** (e.g., `0.21.0` → `0.30.0`): Major version-like bumps for backwards-incompatible changes
-
-> Once the CLI reaches stability and a mature feature set, we will transition to standard semantic versioning starting with `1.0.0`.
-
-## Install
-
-- Before you install Hoppscotch CLI you need to make sure you have the dependencies it requires to run.
-
- - **Windows & macOS**: You will need `node-gyp` installed. Find instructions here: https://github.com/nodejs/node-gyp
- - **Debian/Ubuntu derivatives**:
- ```sh
- sudo apt-get install python g++ build-essential
- ```
- - **Alpine Linux**:
- ```sh
- sudo apk add python3 make g++
- ```
- - **Amazon Linux (AMI)**
- ```sh
- sudo yum install gcc72 gcc72-c++
- ```
- - **Arch Linux**
- ```sh
- sudo pacman -S make gcc python
- ```
- - **RHEL/Fedora derivatives**:
- ```sh
- sudo dnf install python3 make gcc gcc-c++ zlib-devel brotli-devel openssl-devel libuv-devel
- ```
-
-- Once the dependencies are installed, install [@hoppscotch/cli](https://www.npmjs.com/package/@hoppscotch/cli) from npm by running:
- ```
- npm i -g @hoppscotch/cli
- ```
-
-## **Developing:**
-
-1. Clone the repository, make sure you've installed latest [pnpm](https://pnpm.io).
-2. `pnpm install`
-3. Build required workspace dependencies (if needed):
- ```bash
- # These auto-build via postinstall hooks during 'pnpm install'
- # Rebuild manually only when you make changes to these packages:
- pnpm --filter @hoppscotch/data run build
- pnpm --filter @hoppscotch/js-sandbox run build
- ```
-4. `cd packages/hoppscotch-cli`
-5. `pnpm run build`
-6. `sudo pnpm link --global`
-7. Test the installation by executing `hopp`
-
-## **Contributing:**
-
-When contributing to this repository, please first discuss the change you wish to make via issue,
-email, or any other method with the owners of this repository before making a change.
-
-Please note we have a code of conduct, please follow it in all your interactions with the project.
-
-## Pull Request Process
-
-1. Ensure any install or build dependencies are removed before the end of the layer when doing a
- build.
-2. Update the README.md with details of changes to the interface, this includes new environment
- variables, exposed ports, useful file locations and container parameters.
-3. Increase the version numbers in any examples files and the README.md to the new version that this
- Pull Request would represent. The versioning scheme we use is [SemVer](https://semver.org).
-4. You may merge the Pull Request once you have the sign-off of two other developers, or if you
- do not have permission to do that, you may request the second reviewer merge it for you.
-
-## Set Up The Development Environment
-
-1. After cloning the repository, execute the following commands:
-
- ```bash
- pnpm install
- # Build required workspace dependencies (if needed)
- # These auto-build via postinstall hooks during 'pnpm install'
- # Rebuild manually only when you make changes to these packages:
- pnpm --filter @hoppscotch/data run build
- pnpm --filter @hoppscotch/js-sandbox run build
- # Then build the CLI
- cd packages/hoppscotch-cli && pnpm run build
- ```
-
-2. In order to test locally, you can use two types of package linking:
-
- 1. The 'pnpm exec' way (preferred since it does not hamper your original installation of the CLI):
-
- ```bash
- pnpm link @hoppscotch/cli
-
- // Then to use or test the CLI:
- pnpm exec hopp
-
- // After testing, to remove the package linking:
- pnpm rm @hoppscotch/cli
- ```
-
- 2. The 'global' way (warning: this might override the globally installed CLI, if exists):
-
- ```bash
- sudo pnpm link --global
-
- // Then to use or test the CLI:
- hopp
-
- // After testing, to remove the package linking:
- sudo pnpm rm --global @hoppscotch/cli
- ```
-
-3. To use the Typescript watch scripts:
-
- ```bash
- pnpm run dev
- ```
diff --git a/packages/hoppscotch-cli/bin/hopp.js b/packages/hoppscotch-cli/bin/hopp.js
deleted file mode 100755
index 238480e3..00000000
--- a/packages/hoppscotch-cli/bin/hopp.js
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/env node
-// * The entry point of the CLI
-// @ts-check
-
-import chalk from "chalk";
-import { spawnSync } from "child_process";
-import fs from "fs";
-import { cloneDeep } from "lodash-es";
-import semver from "semver";
-import { fileURLToPath } from "url";
-
-const highlightVersion = (version) => chalk.black.bgYellow(`v${version}`);
-
-const packageJsonPath = fileURLToPath(
- new URL("../package.json", import.meta.url)
-);
-const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
-
-const requiredNodeVersionRange = packageJson.engines?.node || ">=22";
-
-// Extract the major version from the start of the range
-const requiredNodeVersion = semver.major(
- semver.minVersion(requiredNodeVersionRange) ?? "22"
-);
-
-const currentNodeVersion = process.versions.node;
-
-// Last supported version of the CLI for Node.js v20
-const lastSupportedVersion = "0.26.0";
-
-if (!semver.satisfies(currentNodeVersion, requiredNodeVersionRange)) {
- console.error(
- `${chalk.greenBright("Hoppscotch CLI")} requires Node.js ${highlightVersion(requiredNodeVersion)} or higher and you're on Node.js ${highlightVersion(currentNodeVersion)}.`
- );
-
- console.error(
- `\nIf you prefer staying on Node.js ${highlightVersion("20")}, you can install the last supported version of the CLI:\n` +
- `${chalk.green(`npm install -g @hoppscotch/cli@${lastSupportedVersion}`)} alongside ${highlightVersion("2025.10.1")} of the Hoppscotch app.\n`
- );
- process.exit(1);
-}
-
-// Dynamically importing the module after the Node.js version check prevents errors due to unrecognized APIs in older Node.js versions
-const { cli } = await import("../dist/index.js");
-
-// As per isolated-vm documentation, we need to supply `--no-node-snapshot` for node >= 20
-// src: https://github.com/laverdet/isolated-vm?tab=readme-ov-file#requirements
-if (!process.execArgv.includes("--no-node-snapshot")) {
- const argCopy = cloneDeep(process.argv);
-
- // Replace first argument with --no-node-snapshot
- // We can get argv[0] from process.argv0
- argCopy[0] = "--no-node-snapshot";
-
- const result = spawnSync(process.argv0, argCopy, { stdio: "inherit" });
-
- // Exit with the same status code as the spawned process
- process.exit(result.status ?? 0);
-} else {
- cli(process.argv);
-}
diff --git a/packages/hoppscotch-cli/package.json b/packages/hoppscotch-cli/package.json
deleted file mode 100644
index c16380b0..00000000
--- a/packages/hoppscotch-cli/package.json
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "name": "@hoppscotch/cli",
- "version": "0.31.1",
- "description": "A CLI to run Hoppscotch test scripts in CI environments.",
- "homepage": "https://hoppscotch.io",
- "type": "module",
- "main": "dist/index.js",
- "bin": {
- "hopp": "bin/hopp.js"
- },
- "publishConfig": {
- "access": "public"
- },
- "engines": {
- "node": ">=22"
- },
- "scripts": {
- "build": "pnpm exec tsup",
- "dev": "pnpm exec tsup --watch",
- "debugger": "node debugger.js 9999",
- "prepublish": "pnpm exec tsup",
- "prettier-format": "prettier --config .prettierrc 'src/**/*.ts' --write",
- "test": "pnpm run build && vitest run",
- "do-typecheck": "pnpm exec tsc --noEmit",
- "do-test": "pnpm run test"
- },
- "keywords": [
- "cli",
- "hoppscotch",
- "hopp-cli"
- ],
- "author": "Hoppscotch (support@hoppscotch.io)",
- "repository": {
- "type": "git",
- "url": "https://github.com/hoppscotch/hoppscotch.git"
- },
- "bugs": {
- "url": "https://github.com/hoppscotch/hoppscotch/issues",
- "email": "support@hoppscotch.io"
- },
- "license": "MIT",
- "private": false,
- "dependencies": {
- "aws4fetch": "1.0.20",
- "axios": "1.15.2",
- "axios-cookiejar-support": "6.0.5",
- "chalk": "5.6.2",
- "commander": "14.0.3",
- "isolated-vm": "6.1.2",
- "js-md5": "0.8.3",
- "jsonc-parser": "3.3.1",
- "lodash-es": "4.18.1",
- "papaparse": "5.5.3",
- "qs": "6.15.1",
- "semver": "7.7.4",
- "tough-cookie": "6.0.1",
- "verzod": "0.4.0",
- "xmlbuilder2": "4.0.3",
- "zod": "3.25.32"
- },
- "devDependencies": {
- "@hoppscotch/data": "workspace:^",
- "@hoppscotch/js-sandbox": "workspace:^",
- "@relmify/jest-fp-ts": "2.1.1",
- "@types/lodash-es": "4.17.12",
- "@types/papaparse": "5.5.2",
- "@types/qs": "6.15.0",
- "fp-ts": "2.16.11",
- "prettier": "3.8.3",
- "tsup": "8.5.1",
- "typescript": "5.9.3",
- "vitest": "4.1.5"
- }
-}
diff --git a/packages/hoppscotch-cli/setupFiles.ts b/packages/hoppscotch-cli/setupFiles.ts
deleted file mode 100644
index 0a1bcdc0..00000000
--- a/packages/hoppscotch-cli/setupFiles.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-// Vitest doesn't work without globals
-// Ref: https://github.com/relmify/jest-fp-ts/issues/11
-
-import decodeMatchers from "@relmify/jest-fp-ts/dist/decodeMatchers";
-import eitherMatchers from "@relmify/jest-fp-ts/dist/eitherMatchers";
-import optionMatchers from "@relmify/jest-fp-ts/dist/optionMatchers";
-import theseMatchers from "@relmify/jest-fp-ts/dist/theseMatchers";
-import eitherOrTheseMatchers from "@relmify/jest-fp-ts/dist/eitherOrTheseMatchers";
-import { expect } from "vitest";
-
-expect.extend(decodeMatchers.matchers);
-expect.extend(eitherMatchers.matchers);
-expect.extend(optionMatchers.matchers);
-expect.extend(theseMatchers.matchers);
-expect.extend(eitherOrTheseMatchers.matchers);
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/commands/__snapshots__/test.spec.ts.snap b/packages/hoppscotch-cli/src/__tests__/e2e/commands/__snapshots__/test.spec.ts.snap
deleted file mode 100644
index 9c3e21c6..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/commands/__snapshots__/test.spec.ts.snap
+++ /dev/null
@@ -1,529 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`hopp test [options] > Test\`hopp test --env --reporter-junit [path] > Generates a JUnit report at the default path 1`] = `
-"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >"
-} (ENV_EXPAND_LOOP)]]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- "
-`;
-
-exports[`hopp test [options] > Test\`hopp test --env --reporter-junit [path] > Generates a JUnit report at the specified path 1`] = `
-"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >"
-} (ENV_EXPAND_LOOP)]]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- "
-`;
-
-exports[`hopp test [options] > Test\`hopp test --env --reporter-junit [path] > Generates a JUnit report for a collection referring to environment variables 1`] = `
-"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- "
-`;
-
-exports[`hopp test [options] > Test\`hopp test --env --reporter-junit [path] > Generates a JUnit report for a collection with authorization/headers set at the collection level 1`] = `
-"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- "
-`;
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/commands/test.spec.ts b/packages/hoppscotch-cli/src/__tests__/e2e/commands/test.spec.ts
deleted file mode 100644
index 42f7df62..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/commands/test.spec.ts
+++ /dev/null
@@ -1,1493 +0,0 @@
-import { ExecException } from "child_process";
-import fs from "fs";
-import path from "path";
-import { afterAll, beforeAll, describe, expect, test } from "vitest";
-
-import { HoppErrorCode } from "../../../types/errors";
-import {
- getErrorCode,
- getTestJsonFilePath,
- runCLI,
- runCLIWithNetworkRetry,
-} from "../../utils";
-
-describe("hopp test [options] ", { timeout: 100000 }, () => {
- const VALID_TEST_ARGS = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`;
-
- describe("Test `hopp test ` command:", () => {
- describe("Argument parsing", () => {
- test("Errors with the code `INVALID_ARGUMENT` for not supplying enough arguments", async () => {
- const args = "test";
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
-
- test("Errors with the code `INVALID_ARGUMENT` for an invalid command", async () => {
- const args = "invalid-arg";
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
- });
-
- describe("Supplied collection export file validations", () => {
- test("Errors with the code `FILE_NOT_FOUND` if the supplied collection export file doesn't exist", async () => {
- const args = "test notfound.json";
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("FILE_NOT_FOUND");
- });
-
- test("Errors with the code UNKNOWN_ERROR if the supplied collection export file content isn't valid JSON", async () => {
- const args = `test ${getTestJsonFilePath("malformed-coll.json", "collection")}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("UNKNOWN_ERROR");
- });
-
- test("Errors with the code `MALFORMED_COLLECTION` if the supplied collection export file content is malformed", async () => {
- const args = `test ${getTestJsonFilePath("malformed-coll-2.json", "collection")}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("MALFORMED_COLLECTION");
- });
-
- test("Errors with the code `INVALID_FILE_TYPE` if the supplied collection export file doesn't end with the `.json` extension", async () => {
- const args = `test ${getTestJsonFilePath("notjson-coll.txt", "collection")}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_FILE_TYPE");
- });
-
- test("Fails if the collection file includes scripts with incorrect API usage and failed assertions", async () => {
- const args = `test ${getTestJsonFilePath("fails-coll.json", "collection")}`;
- const { error } = await runCLI(args);
-
- expect(error).not.toBeNull();
- expect(error).toMatchObject({
- code: 1,
- });
- });
- });
-
- describe("Versioned entities", () => {
- describe("Collections & Requests", () => {
- const testFixtures = [
- { fileName: "coll-v1-req-v0.json", collVersion: 1, reqVersion: 0 },
- { fileName: "coll-v1-req-v1.json", collVersion: 1, reqVersion: 1 },
- { fileName: "coll-v2-req-v2.json", collVersion: 2, reqVersion: 2 },
- { fileName: "coll-v2-req-v3.json", collVersion: 2, reqVersion: 3 },
- ];
-
- testFixtures.forEach(({ collVersion, fileName, reqVersion }) => {
- test(`Successfully processes a supplied collection export file where the collection is based on the "v${collVersion}" schema and the request following the "v${reqVersion}" schema`, async () => {
- const args = `test ${getTestJsonFilePath(fileName, "collection")}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
- });
-
- describe("Mixed versions", () => {
- test("Successfully processes children based on valid version ranges", async () => {
- const args = `test ${getTestJsonFilePath("valid-mixed-versions-coll.json", "collection")}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- test("Errors with the code `MALFORMED_COLLECTION` if the children fall out of valid version ranges", async () => {
- const args = `test ${getTestJsonFilePath("invalid-mixed-versions-coll.json", "collection")}`;
-
- const { stderr } = await runCLI(args);
- const out = getErrorCode(stderr);
-
- expect(out).toBe("MALFORMED_COLLECTION");
- });
- });
- });
-
- describe("Environments", () => {
- const testFixtures = [
- { fileName: "env-v0.json", version: 0 },
- { fileName: "env-v1.json", version: 1 },
- { fileName: "env-v2.json", version: 2 },
- ];
-
- testFixtures.forEach(({ fileName, version }) => {
- test(`Successfully processes the supplied collection and environment export files where the environment is based on the "v${version}" schema`, async () => {
- const ENV_PATH = getTestJsonFilePath(fileName, "environment");
- const args = `test ${getTestJsonFilePath("sample-coll.json", "collection")} --env ${ENV_PATH}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
- });
- });
- });
-
- test("Successfully processes a supplied collection export file of the expected format", async () => {
- const args = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- test("Successfully inherits/overrides authorization and headers specified at the root collection at deeply nested collections", async () => {
- const args = `test ${getTestJsonFilePath(
- "collection-level-auth-headers-coll.json",
- "collection"
- )}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- test("Successfully inherits/overrides authorization and headers at each level with multiple child collections", async () => {
- const args = `test ${getTestJsonFilePath(
- "multiple-child-collections-auth-headers-coll.json",
- "collection"
- )}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- test("Successfully inherits collection variables into folders without their own variables", async () => {
- const args = `test ${getTestJsonFilePath(
- "collection-with-variables.json",
- "collection"
- )}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- test("Persists environment variables set in the pre-request script for consumption in the test script", async () => {
- const args = `test ${getTestJsonFilePath(
- "pre-req-script-env-var-persistence-coll.json",
- "collection"
- )}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- test("The `Content-Type` header takes priority over the value set at the request body", async () => {
- const args = `test ${getTestJsonFilePath(
- "content-type-header-scenarios.json",
- "collection"
- )}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- test("Strips comments from JSONC request bodies", async () => {
- const args = `test ${getTestJsonFilePath(
- "jsonc-body-coll.json",
- "collection"
- )}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- describe("OAuth 2 Authorization type with Authorization Code Grant Type", () => {
- test("Successfully translates the authorization information to headers/query params and sends it along with the request", async () => {
- const args = `test ${getTestJsonFilePath(
- "oauth2-auth-code-coll.json",
- "collection"
- )}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
- });
-
- describe("multipart/form-data content type", () => {
- test("Successfully derives the relevant headers based and sends the form data in the request body", async () => {
- const args = `test ${getTestJsonFilePath(
- "oauth2-auth-code-coll.json",
- "collection"
- )}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
- });
-
- test("Successfully display console logs and recognizes platform APIs in the experimental scripting sandbox", async () => {
- const args = `test ${getTestJsonFilePath(
- "test-scripting-sandbox-modes-coll.json",
- "collection"
- )}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
-
- expect(result.error).toBeNull();
-
- const expectedStaticParts = [
- "https://example.com/path?foo=bar&baz=qux",
- "'0': 72",
- "'12': 33",
- "Decoded: Hello, world!",
- "Hello after 1s",
- ];
-
- expectedStaticParts.forEach((part) => {
- expect(result.stdout).toContain(part);
- });
-
- const every500msCount = (result.stdout.match(/Every 500ms/g) || [])
- .length;
- expect(every500msCount).toBeGreaterThanOrEqual(3);
- });
-
- test("Fails to display console logs and recognize platform APIs in the legacy scripting sandbox", async () => {
- const args = `test ${getTestJsonFilePath(
- "test-scripting-sandbox-modes-coll.json",
- "collection"
- )} --legacy-sandbox`;
- const { error, stdout } = await runCLI(args);
-
- expect(error).toBeTruthy();
- expect(stdout).not.toContain("https://example.com/path?foo=bar&baz=qux");
- expect(stdout).not.toContain("Encoded");
- });
-
- test("Ensures tests run in sequence order based on request path", async () => {
- // Expected order of collection runs
- const expectedOrder = [
- "root-collection-request",
- "folder-1/folder-1-request",
- "folder-1/folder-11/folder-11-request",
- "folder-1/folder-12/folder-12-request",
- "folder-1/folder-13/folder-13-request",
- "folder-2/folder-2-request",
- "folder-2/folder-21/folder-21-request",
- "folder-2/folder-22/folder-22-request",
- "folder-2/folder-23/folder-23-request",
- "folder-3/folder-3-request",
- "folder-3/folder-31/folder-31-request",
- "folder-3/folder-32/folder-32-request",
- "folder-3/folder-33/folder-33-request",
- ];
-
- const normalizePath = (path: string) => path.replace(/\\/g, "/");
-
- const extractRunningOrder = (stdout: string): string[] =>
- [...stdout.matchAll(/Running:.*?\/(.*?)\r?\n/g)].map(
- ([, path]) => normalizePath(path.replace(/\x1b\[\d+m/g, "")) // Remove ANSI codes and normalize paths
- );
-
- const args = `test ${getTestJsonFilePath(
- "multiple-child-collections-auth-headers-coll.json",
- "collection"
- )}`;
-
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
-
- expect(extractRunningOrder(result.stdout)).toStrictEqual(expectedOrder);
-
- expect(result.error).toBeNull();
- });
-
- /**
- * Tests pm.sendRequest() functionality with external HTTP endpoints.
- *
- * Network Resilience Strategy:
- * - Retries once (2 total attempts) on transient network errors
- * - Detects and logs specific errors (ECONNRESET, ETIMEDOUT, etc.)
- * - Validates JUnit XML completeness (60+ test suites) before accepting success
- * - Auto-skips on network failures to prevent blocking PRs
- */
- test("Supports the new scripting API method additions under the `hopp` and `pm` namespaces and validates JUnit report structure", async () => {
- // First, run without JUnit report to ensure basic functionality works
- const basicArgs = `test ${getTestJsonFilePath(
- "scripting-revamp-coll.json",
- "collection"
- )}`;
- const basicResult = await runCLIWithNetworkRetry(basicArgs);
- if (basicResult === null) return;
- expect(basicResult.error).toBeNull();
-
- // Then, run with JUnit report and validate structure
- const junitPath = path.join(
- __dirname,
- "scripting-revamp-snapshot-junit.xml"
- );
-
- if (fs.existsSync(junitPath)) {
- fs.unlinkSync(junitPath);
- }
-
- const junitArgs = `test ${getTestJsonFilePath(
- "scripting-revamp-coll.json",
- "collection"
- )} --reporter-junit ${junitPath}`;
-
- // Enhanced retry for JUnit run - also validate output completeness
- const runWithValidation = async () => {
- const minExpectedTestSuites = 60; // Should have 67+ test suites
- const maxAttempts = 2; // Only retry once (2 total attempts)
-
- const extractNetworkError = (output: string): string => {
- const econnresetMatch = output.match(/ECONNRESET/i);
- const eaiAgainMatch = output.match(/EAI_AGAIN/i);
- const enotfoundMatch = output.match(/ENOTFOUND/i);
- const etimedoutMatch = output.match(/ETIMEDOUT/i);
- const econnrefusedMatch = output.match(/ECONNREFUSED/i);
-
- if (econnresetMatch) return "ECONNRESET (connection reset by peer)";
- if (eaiAgainMatch) return "EAI_AGAIN (DNS lookup timeout)";
- if (enotfoundMatch) return "ENOTFOUND (DNS lookup failed)";
- if (etimedoutMatch) return "ETIMEDOUT (connection timeout)";
- if (econnrefusedMatch) return "ECONNREFUSED (connection refused)";
- return "Unknown network error";
- };
-
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
- if (fs.existsSync(junitPath)) {
- fs.unlinkSync(junitPath);
- }
-
- const result = await runCLI(junitArgs);
-
- // Check for transient errors in output (network or httpbin 5xx)
- const output = `${result.stdout}\n${result.stderr}`;
- const hasNetworkError =
- /ECONNRESET|EAI_AGAIN|ENOTFOUND|ETIMEDOUT|ECONNREFUSED|REQUEST_ERROR/i.test(
- output
- );
- const hasHttpbin5xx =
- /httpbin\.org is down \(5xx\)|httpbin\.org is down \(503\)/i.test(
- output
- );
-
- // If successful and JUnit file exists, validate completeness
- if (!result.error && fs.existsSync(junitPath)) {
- const xml = fs.readFileSync(junitPath, "utf-8");
- const testsuiteCount = (xml.match(/= minExpectedTestSuites && !hasHttpbin5xx) {
- return result;
- }
-
- // Incomplete output or httpbin issues - retry once if transient
- if (
- (hasNetworkError || hasHttpbin5xx) &&
- attempt < maxAttempts - 1
- ) {
- const errorDetail = hasHttpbin5xx
- ? "httpbin.org 5xx response"
- : `incomplete output (${testsuiteCount}/${minExpectedTestSuites} test suites) with ${extractNetworkError(output)}`;
- console.log(
- `⚠️ Transient error detected: ${errorDetail}. Retrying once...`
- );
- await new Promise((r) => setTimeout(r, 2000));
- continue;
- }
- }
-
- // Non-transient error - fail fast
- if (result.error && !hasNetworkError && !hasHttpbin5xx) {
- return result;
- }
-
- // Transient error - retry once
- const isLastAttempt = attempt === maxAttempts - 1;
- if (!isLastAttempt) {
- const errorDetail = hasHttpbin5xx
- ? "httpbin.org 5xx response"
- : extractNetworkError(output);
- console.log(
- `⚠️ Transient error detected: ${errorDetail}. Retrying once...`
- );
- await new Promise((r) => setTimeout(r, 2000));
- continue;
- }
-
- // Last attempt exhausted due to transient issues - skip test to avoid blocking PR
- const errorDetail = hasHttpbin5xx
- ? "httpbin.org service degradation (5xx)"
- : extractNetworkError(output);
- console.warn(
- `⚠️ Skipping test: Retry exhausted due to ${errorDetail}. External services may be unavailable.`
- );
- return null; // Signal to skip test
- }
-
- // Should never reach here - all paths above should return
- throw new Error("Unexpected: retry loop completed without returning");
- };
-
- const junitResult = await runWithValidation();
- if (junitResult === null) return;
- expect(junitResult.error).toBeNull();
-
- const junitXml = fs.readFileSync(junitPath, "utf-8");
-
- // Validate structural invariants using regex parsing.
- // Validate no testcases have "root" as name (would indicate assertions at root level).
- const testcaseRootPattern = /]*name="root"/;
- expect(junitXml).not.toMatch(testcaseRootPattern);
-
- // Validate test structure: testcases should have meaningful names from test blocks
- const testcasePattern = / m[1]
- );
-
- // Ensure we have testcases
- expect(testcaseNames.length).toBeGreaterThan(0);
-
- // Ensure no empty testcase names
- for (const name of testcaseNames) {
- expect(name.length).toBeGreaterThan(0);
- expect(name).not.toBe("root");
- }
-
- // Validate presence of key test groups instead of snapshot comparison
- // This is more reliable for CI as network responses can vary
-
- // 1. Correct number of test suites
- const testsuitePattern = / {
- const args = `test ${getTestJsonFilePath(
- "collection-level-scripts-coll.json",
- "collection"
- )}`;
-
- const defaultResult = await runCLIWithNetworkRetry(args);
- if (defaultResult === null) return;
- expect(defaultResult.error).toBeNull();
-
- const legacyResult = await runCLIWithNetworkRetry(`${args} --legacy-sandbox`);
- if (legacyResult === null) return;
- expect(legacyResult.error).toBeNull();
- });
- });
-
- describe("Test `hopp test --env ` command:", () => {
- describe("Supplied environment export file validations", () => {
- describe("Argument parsing", () => {
- test("Errors with the code `INVALID_ARGUMENT` if no file is supplied", async () => {
- const args = `${VALID_TEST_ARGS} --env`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
- });
-
- test("Errors with the code `INVALID_FILE_TYPE` if the supplied environment export file doesn't end with the `.json` extension", async () => {
- const args = `${VALID_TEST_ARGS} --env ${getTestJsonFilePath(
- "notjson-coll.txt",
- "collection"
- )}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_FILE_TYPE");
- });
-
- test("Errors with the code `FILE_NOT_FOUND` if the supplied environment export file doesn't exist", async () => {
- const args = `${VALID_TEST_ARGS} --env notfound.json`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("FILE_NOT_FOUND");
- });
-
- test("Errors with the code `MALFORMED_ENV_FILE` on supplying a malformed environment export file", async () => {
- const ENV_PATH = getTestJsonFilePath(
- "malformed-envs.json",
- "environment"
- );
- const args = `${VALID_TEST_ARGS} --env ${ENV_PATH}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("MALFORMED_ENV_FILE");
- });
-
- test("Errors with the code `BULK_ENV_FILE` on supplying an environment export file based on the bulk environment export format", async () => {
- const ENV_PATH = getTestJsonFilePath("bulk-envs.json", "environment");
- const args = `${VALID_TEST_ARGS} --env ${ENV_PATH}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("BULK_ENV_FILE");
- });
- });
-
- test("Successfully resolves values from the supplied environment export file", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "env-flag-tests-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath("env-flag-envs.json", "environment");
- const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
-
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- test("Successfully resolves environment variables referenced in the request body", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "req-body-env-vars-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "req-body-env-vars-envs.json",
- "environment"
- );
- const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
-
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- test("Works with short `-e` flag", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "env-flag-tests-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath("env-flag-envs.json", "environment");
- const args = `test ${COLL_PATH} -e ${ENV_PATH}`;
-
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- describe("Secret environment variables", () => {
- // Reads secret environment values from system environment
- test("Successfully picks the values for secret environment variables from `process.env` and persists the variables set from the pre-request script", async () => {
- const env = {
- ...process.env,
- secretBearerToken: "test-token",
- secretBasicAuthUsername: "test-user",
- secretBasicAuthPassword: "test-pass",
- secretQueryParamValue: "secret-query-param-value",
- secretBodyValue: "secret-body-value",
- secretHeaderValue: "secret-header-value",
- };
-
- const COLL_PATH = getTestJsonFilePath(
- "secret-envs-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath("secret-envs.json", "environment");
- const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
-
- const result = await runCLIWithNetworkRetry(args, { env });
- if (result === null) return;
-
- expect(result.stdout).toContain(
- "https://httpbin.org/basic-auth/*********/*********"
- );
- expect(result.error).toBeNull();
- });
-
- test("Successfully picks the values for secret environment variables set directly in the environment export file and persists the environment variables set from the pre-request script", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "secret-envs-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "secret-supplied-values-envs.json",
- "environment"
- );
- const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
-
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
-
- expect(result.stdout).toContain(
- "https://httpbin.org/basic-auth/*********/*********"
- );
- expect(result.error).toBeNull();
- });
-
- test("Setting values for secret environment variables from the pre-request script overrides values set at the supplied environment export file", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "secret-envs-persistence-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "secret-supplied-values-envs.json",
- "environment"
- );
- const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
-
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
-
- expect(result.stdout).toContain(
- "https://httpbin.org/basic-auth/*********/*********"
- );
- expect(result.error).toBeNull();
- });
-
- test("Persists secret environment variable values set from the pre-request script for consumption in the request and post-request script context", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "secret-envs-persistence-scripting-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "secret-envs-persistence-scripting-envs.json",
- "environment"
- );
-
- const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
-
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
- });
-
- describe("Request variables", () => {
- test("Picks active request variables and ignores inactive entries alongside the usage of environment variables", async () => {
- const env = {
- ...process.env,
- secretBasicAuthPasswordEnvVar: "password",
- };
-
- const COLL_PATH = getTestJsonFilePath(
- "request-vars-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "request-vars-envs.json",
- "environment"
- );
-
- const args = `test ${COLL_PATH} --env ${ENV_PATH}`;
-
- const result = await runCLIWithNetworkRetry(args, { env });
- if (result === null) return;
- expect(result.stdout).toContain(
- "https://echo.hoppscotch.io/********/********"
- );
- expect(result.error).toBeNull();
- });
- });
-
- describe("AWS Signature Authorization type", () => {
- test("Successfully translates the authorization information to headers/query params and sends it along with the request", async () => {
- const env = {
- ...process.env,
- secretKey: "test-secret-key",
- serviceToken: "test-token",
- };
-
- const COLL_PATH = getTestJsonFilePath(
- "aws-signature-auth-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "aws-signature-auth-envs.json",
- "environment"
- );
-
- const args = `test ${COLL_PATH} -e ${ENV_PATH}`;
- const result = await runCLIWithNetworkRetry(args, { env });
- if (result === null) return;
-
- expect(result.error).toBeNull();
- });
- });
-
- describe("Digest Authorization type", () => {
- /**
- * NOTE: This test is being skipped because the test endpoint is no longer resolving
- * TODO: Find a reliable public endpoint that supports Digest Auth and re-enable this test
- */
- test.skip("Successfully translates the authorization information to headers/query params and sends it along with the request", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "digest-auth-success-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "digest-auth-envs.json",
- "environment"
- );
-
- const args = `test ${COLL_PATH} -e ${ENV_PATH}`;
- const { error } = await runCLI(args);
- expect(error).toBeNull();
- });
- });
-
- test("Supports disabling request retries", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "digest-auth-failure-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "digest-auth-envs.json",
- "environment"
- );
-
- const args = `test ${COLL_PATH} -e ${ENV_PATH}`;
- const { error } = await runCLI(args);
-
- expect(error).toBeTruthy();
- });
-
- describe("HAWK Authentication", () => {
- test("Correctly generates and attaches authorization headers to the request ", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "hawk-auth-success-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "hawk-auth-envs.json",
- "environment"
- );
-
- const args = `test ${COLL_PATH} -e ${ENV_PATH}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
-
- expect(result.error).toBeNull();
- });
- });
- });
-
- describe("Test `hopp test --delay ` command:", () => {
- describe("Argument parsing", () => {
- test("Errors with the code `INVALID_ARGUMENT` on not supplying a delay value", async () => {
- const args = `${VALID_TEST_ARGS} --delay`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
-
- test("Errors with the code `INVALID_ARGUMENT` on supplying an invalid delay value", async () => {
- const args = `${VALID_TEST_ARGS} --delay 'NaN'`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
- });
-
- test("Successfully performs delayed request execution for a valid delay value", async () => {
- const args = `${VALID_TEST_ARGS} --delay 1`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
-
- test("Works with the short `-d` flag", async () => {
- const args = `${VALID_TEST_ARGS} -d 1`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
- expect(result.error).toBeNull();
- });
- });
-
- // Future TODO: Enable once a proper e2e test environment is set up locally
- describe.skip("Test `hopp test --env --token --server ` command:", () => {
- const {
- REQ_BODY_ENV_VARS_COLL_ID,
- COLLECTION_LEVEL_HEADERS_AUTH_COLL_ID,
- REQ_BODY_ENV_VARS_ENVS_ID,
- PERSONAL_ACCESS_TOKEN,
- } = process.env;
-
- if (
- !REQ_BODY_ENV_VARS_COLL_ID ||
- !COLLECTION_LEVEL_HEADERS_AUTH_COLL_ID ||
- !REQ_BODY_ENV_VARS_ENVS_ID ||
- !PERSONAL_ACCESS_TOKEN
- ) {
- return;
- }
-
- const SERVER_URL = "https://stage-shc.hoppscotch.io/backend";
-
- describe("Argument parsing", () => {
- test("Errors with the code `INVALID_ARGUMENT` on not supplying a value for the `--token` flag", async () => {
- const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --token`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
-
- test("Errors with the code `INVALID_ARGUMENT` on not supplying a value for the `--server` flag", async () => {
- const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --server`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
- });
-
- describe("Workspace access validations", () => {
- const INVALID_COLLECTION_ID = "invalid-coll-id";
- const INVALID_ENVIRONMENT_ID = "invalid-env-id";
- const INVALID_ACCESS_TOKEN = "invalid-token";
-
- test("Errors with the code `TOKEN_INVALID` if the supplied access token is invalid", async () => {
- const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --token ${INVALID_ACCESS_TOKEN} --server ${SERVER_URL}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("TOKEN_INVALID");
- });
-
- test("Errors with the code `INVALID_ID` if the supplied collection ID is invalid", async () => {
- const args = `test ${INVALID_COLLECTION_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ID");
- });
-
- test("Errors with the code `INVALID_ID` if the supplied environment ID is invalid", async () => {
- const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${INVALID_ENVIRONMENT_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ID");
- });
-
- test("Errors with the code `INVALID_SERVER_URL` if not supplying a valid SH instance server URL", async () => {
- // FE URL of the staging SHC instance
- const INVALID_SERVER_URL = "https://stage-shc.hoppscotch.io";
- const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${INVALID_SERVER_URL}`;
-
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_SERVER_URL");
- });
-
- test("Errors with the code `SERVER_CONNECTION_REFUSED` if supplying an SH instance server URL that doesn't follow URL semantics", async () => {
- const INVALID_URL = "invalid-url";
- const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${INVALID_URL}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("SERVER_CONNECTION_REFUSED");
- });
- });
-
- test("Successfully retrieves a collection with the ID", async () => {
- const args = `test ${COLLECTION_LEVEL_HEADERS_AUTH_COLL_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`;
-
- const { error } = await runCLI(args);
- expect(error).toBeNull();
- });
-
- test("Successfully retrieves collections and environments from a workspace using their respective IDs", async () => {
- const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`;
-
- const { error } = await runCLI(args);
- expect(error).toBeNull();
- });
-
- test("Supports specifying collection file path along with environment ID", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "req-body-env-vars-coll.json",
- "collection"
- );
- const args = `test ${COLL_PATH} --env ${REQ_BODY_ENV_VARS_ENVS_ID} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`;
-
- const { error } = await runCLI(args);
- expect(error).toBeNull();
- });
-
- test("Supports specifying environment file path along with collection ID", async () => {
- const ENV_PATH = getTestJsonFilePath(
- "req-body-env-vars-envs.json",
- "environment"
- );
- const args = `test ${REQ_BODY_ENV_VARS_COLL_ID} --env ${ENV_PATH} --token ${PERSONAL_ACCESS_TOKEN} --server ${SERVER_URL}`;
-
- const { error } = await runCLI(args);
- expect(error).toBeNull();
- });
-
- test("Supports specifying both collection and environment file paths", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "req-body-env-vars-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "req-body-env-vars-envs.json",
- "environment"
- );
- const args = `test ${COLL_PATH} --env ${ENV_PATH} --token ${PERSONAL_ACCESS_TOKEN}`;
-
- const { error } = await runCLI(args);
- expect(error).toBeNull();
- });
- });
-
- describe("Test`hopp test --env --reporter-junit [path]", () => {
- const genPath = path.resolve("hopp-cli-test");
-
- // Helper function to replace dynamic values before generating test snapshots
- // Currently scoped to JUnit report generation
- const replaceDynamicValuesInStr = (input: string): string =>
- input
- .replace(/(time|timestamp)="[^"]+"/g, (_, attr) => `${attr}="${attr}"`)
- // Strip QuickJS GC assertion errors - these are non-deterministic
- // and appear after script errors when scope disposal fails
- // Pattern matches multi-line format ending with ]]
- .replace(
- /\n\s*Then, failed to dispose scope: Aborted\(Assertion failed[^\]]*\]\]/g,
- ""
- );
-
- beforeAll(() => {
- fs.mkdirSync(genPath);
- });
-
- afterAll(() => {
- fs.rmdirSync(genPath, { recursive: true });
- });
-
- test("Report export fails with the code `REPORT_EXPORT_FAILED` while encountering an error during path creation", async () => {
- const exportPath = "hopp-junit-report.xml";
-
- const COLL_PATH = getTestJsonFilePath("passes-coll.json", "collection");
-
- const invalidPath =
- process.platform === "win32"
- ? "Z:/non-existent-path/report.xml"
- : "/non-existent/report.xml";
-
- const args = `test ${COLL_PATH} --reporter-junit ${invalidPath}`;
-
- const { stdout, stderr } = await runCLI(args, {
- cwd: path.resolve("hopp-cli-test"),
- });
-
- const out = getErrorCode(stderr);
- expect(out).toBe("REPORT_EXPORT_FAILED");
-
- expect(stdout).not.toContain(
- `Successfully exported the JUnit report to: ${exportPath}`
- );
- });
-
- test("Generates a JUnit report at the default path", async () => {
- const exportPath = "hopp-junit-report.xml";
-
- const COLL_PATH = getTestJsonFilePath(
- "test-junit-report-export-coll.json",
- "collection"
- );
-
- const args = `test ${COLL_PATH} --reporter-junit`;
-
- // Use retry logic to handle transient network errors (ECONNRESET, etc.)
- // that can corrupt JUnit XML structure and cause snapshot mismatches
- const maxAttempts = 2; // Only retry once (2 total attempts)
- let lastResult: Awaited> | null = null;
- let lastFileContents = "";
-
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
- lastResult = await runCLI(args, {
- cwd: path.resolve("hopp-cli-test"),
- });
-
- // Read JUnit XML file
- const fileContents = fs
- .readFileSync(path.resolve(genPath, exportPath))
- .toString();
-
- lastFileContents = fileContents;
-
- const hasNetworkErrorInXML =
- /ECONNRESET|EAI_AGAIN|ENOTFOUND|ETIMEDOUT|ECONNREFUSED/i.test(
- fileContents
- ) ||
- (/REQUEST_ERROR/i.test(fileContents) &&
- !/Invalid URL/i.test(fileContents));
-
- if (!hasNetworkErrorInXML) {
- break;
- }
-
- // Network error detected - retry once if not last attempt
- if (attempt < maxAttempts - 1) {
- console.log(
- `⚠️ Network error detected in JUnit XML (ECONNRESET/DNS). Retrying once to get clean snapshot...`
- );
- // Delete corrupted XML file before retry
- try {
- fs.unlinkSync(path.resolve(genPath, exportPath));
- } catch {}
- await new Promise((r) => setTimeout(r, 2000));
- continue;
- }
-
- // Last attempt exhausted - skip test to avoid false positive
- console.warn(
- `⚠️ Skipping snapshot test: Network errors persisted in JUnit XML after retry. External services may be degraded.`
- );
- return; // Skip test - don't fail on infrastructure issues
- }
-
- expect(lastResult?.stdout).not.toContain(
- `Overwriting the pre-existing path: ${exportPath}`
- );
-
- expect(lastResult?.stdout).toContain(
- `Successfully exported the JUnit report to: ${exportPath}`
- );
-
- expect(replaceDynamicValuesInStr(lastFileContents)).toMatchSnapshot();
- });
-
- test("Generates a JUnit report at the specified path", async () => {
- const exportPath = "outer-dir/inner-dir/report.xml";
-
- const COLL_PATH = getTestJsonFilePath(
- "test-junit-report-export-coll.json",
- "collection"
- );
-
- const args = `test ${COLL_PATH} --reporter-junit ${exportPath}`;
-
- // Use retry logic to handle transient network errors (ECONNRESET, etc.)
- // that can corrupt JUnit XML structure and cause snapshot mismatches
- const maxAttempts = 2; // Only retry once (2 total attempts)
- let lastResult: Awaited> | null = null;
- let lastFileContents = "";
-
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
- lastResult = await runCLI(args, {
- cwd: path.resolve("hopp-cli-test"),
- });
-
- // Read JUnit XML file
- const fileContents = fs
- .readFileSync(path.resolve(genPath, exportPath))
- .toString();
-
- lastFileContents = fileContents;
-
- const hasNetworkErrorInXML =
- /ECONNRESET|EAI_AGAIN|ENOTFOUND|ETIMEDOUT|ECONNREFUSED/i.test(
- fileContents
- ) ||
- (/REQUEST_ERROR/i.test(fileContents) &&
- !/Invalid URL/i.test(fileContents));
-
- if (!hasNetworkErrorInXML) {
- break;
- }
-
- // Network error detected - retry once if not last attempt
- if (attempt < maxAttempts - 1) {
- console.log(
- `⚠️ Network error detected in JUnit XML (ECONNRESET/DNS). Retrying once to get clean snapshot...`
- );
- // Delete corrupted XML file before retry
- try {
- fs.unlinkSync(path.resolve(genPath, exportPath));
- } catch {}
- await new Promise((r) => setTimeout(r, 2000));
- continue;
- }
-
- // Last attempt exhausted - skip test to avoid false positive
- console.warn(
- `⚠️ Skipping snapshot test: Network errors persisted in JUnit XML after retry. External services may be degraded.`
- );
- return; // Skip test - don't fail on infrastructure issues
- }
-
- expect(lastResult?.stdout).not.toContain(
- `Overwriting the pre-existing path: ${exportPath}`
- );
-
- expect(lastResult?.stdout).toContain(
- `Successfully exported the JUnit report to: ${exportPath}`
- );
-
- expect(replaceDynamicValuesInStr(lastFileContents)).toMatchSnapshot();
- });
-
- test("Generates a JUnit report for a collection with authorization/headers set at the collection level", async () => {
- const exportPath = "hopp-junit-report.xml";
-
- const COLL_PATH = getTestJsonFilePath(
- "collection-level-auth-headers-coll.json",
- "collection"
- );
-
- const args = `test ${COLL_PATH} --reporter-junit`;
-
- // Use retry logic to handle transient network errors (ECONNRESET, etc.)
- // that can corrupt JUnit XML structure and cause snapshot mismatches
- const maxAttempts = 2; // Only retry once (2 total attempts)
- let lastResult: Awaited> | null = null;
- let lastFileContents = "";
-
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
- lastResult = await runCLI(args, {
- cwd: path.resolve("hopp-cli-test"),
- });
-
- // Read JUnit XML file
- const fileContents = fs
- .readFileSync(path.resolve(genPath, exportPath))
- .toString();
-
- lastFileContents = fileContents;
-
- const hasNetworkErrorInXML =
- /ECONNRESET|EAI_AGAIN|ENOTFOUND|ETIMEDOUT|ECONNREFUSED/i.test(
- fileContents
- ) ||
- (/REQUEST_ERROR/i.test(fileContents) &&
- !/Invalid URL/i.test(fileContents));
-
- if (!hasNetworkErrorInXML) {
- break;
- }
-
- // Network error detected - retry once if not last attempt
- if (attempt < maxAttempts - 1) {
- console.log(
- `⚠️ Network error detected in JUnit XML (ECONNRESET/DNS). Retrying once to get clean snapshot...`
- );
- // Delete corrupted XML file before retry
- try {
- fs.unlinkSync(path.resolve(genPath, exportPath));
- } catch {}
- await new Promise((r) => setTimeout(r, 2000));
- continue;
- }
-
- // Last attempt exhausted - skip test to avoid false positive
- console.warn(
- `⚠️ Skipping snapshot test: Network errors persisted in JUnit XML after retry. External services may be degraded.`
- );
- return; // Skip test - don't fail on infrastructure issues
- }
-
- expect(lastResult?.stdout).toContain(
- `Overwriting the pre-existing path: ${exportPath}`
- );
-
- expect(lastResult?.stdout).toContain(
- `Successfully exported the JUnit report to: ${exportPath}`
- );
-
- expect(replaceDynamicValuesInStr(lastFileContents)).toMatchSnapshot();
- });
-
- test("Generates a JUnit report for a collection referring to environment variables", async () => {
- const exportPath = "hopp-junit-report.xml";
-
- const COLL_PATH = getTestJsonFilePath(
- "req-body-env-vars-coll.json",
- "collection"
- );
- const ENV_PATH = getTestJsonFilePath(
- "req-body-env-vars-envs.json",
- "environment"
- );
-
- const args = `test ${COLL_PATH} --env ${ENV_PATH} --reporter-junit`;
-
- // Use retry logic to handle transient network errors (ECONNRESET, etc.)
- // that can corrupt JUnit XML structure and cause snapshot mismatches
- const maxAttempts = 2; // Only retry once (2 total attempts)
- let lastResult: Awaited> | null = null;
- let lastFileContents = "";
-
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
- lastResult = await runCLI(args, {
- cwd: path.resolve("hopp-cli-test"),
- });
-
- // Read JUnit XML file
- const fileContents = fs
- .readFileSync(path.resolve(genPath, exportPath))
- .toString();
-
- lastFileContents = fileContents;
-
- const hasNetworkErrorInXML =
- /ECONNRESET|EAI_AGAIN|ENOTFOUND|ETIMEDOUT|ECONNREFUSED/i.test(
- fileContents
- ) ||
- (/REQUEST_ERROR/i.test(fileContents) &&
- !/Invalid URL/i.test(fileContents));
-
- if (!hasNetworkErrorInXML) {
- break;
- }
-
- // Network error detected - retry once if not last attempt
- if (attempt < maxAttempts - 1) {
- console.log(
- `⚠️ Network error detected in JUnit XML (ECONNRESET/DNS). Retrying once to get clean snapshot...`
- );
- // Delete corrupted XML file before retry
- try {
- fs.unlinkSync(path.resolve(genPath, exportPath));
- } catch {}
- await new Promise((r) => setTimeout(r, 2000));
- continue;
- }
-
- // Last attempt exhausted - skip test to avoid false positive
- console.warn(
- `⚠️ Skipping snapshot test: Network errors persisted in JUnit XML after retry. External services may be degraded.`
- );
- return; // Skip test - don't fail on infrastructure issues
- }
-
- expect(lastResult?.stdout).toContain(
- `Overwriting the pre-existing path: ${exportPath}`
- );
-
- expect(lastResult?.stdout).toContain(
- `Successfully exported the JUnit report to: ${exportPath}`
- );
-
- expect(replaceDynamicValuesInStr(lastFileContents)).toMatchSnapshot();
- });
- });
-
- describe("Test `hopp test --iteration-count ` command:", () => {
- const VALID_TEST_ARGS = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`;
-
- test("Errors with the code `INVALID_ARGUMENT` on not supplying an iteration count", async () => {
- const args = `${VALID_TEST_ARGS} --iteration-count`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
-
- test("Errors with the code `INVALID_ARGUMENT` on supplying an invalid iteration count", async () => {
- const args = `${VALID_TEST_ARGS} --iteration-count NaN`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
-
- test("Errors with the code `INVALID_ARGUMENT` on supplying an iteration count below `1`", async () => {
- const args = `${VALID_TEST_ARGS} --iteration-count -5`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
-
- test("Successfully executes all requests in the collection iteratively based on the specified iteration count", async () => {
- const iterationCount = 3;
- const args = `${VALID_TEST_ARGS} --iteration-count ${iterationCount}`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
-
- Array.from({ length: 3 }).forEach((_, idx) =>
- expect(result.stdout).include(`Iteration: ${idx + 1}/${iterationCount}`)
- );
- expect(result.error).toBeNull();
- });
-
- test("Doesn't log iteration count if the value supplied is `1`", async () => {
- const args = `${VALID_TEST_ARGS} --iteration-count 1`;
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
-
- expect(result.stdout).not.include(`Iteration: 1/1`);
-
- expect(result.error).toBeNull();
- });
- });
-
- describe("Test `hopp test --iteration-data ` command:", () => {
- describe("Supplied data export file validations", () => {
- const VALID_TEST_ARGS = `test ${getTestJsonFilePath("passes-coll.json", "collection")}`;
-
- test("Errors with the code `INVALID_ARGUMENT` if no file is supplied", async () => {
- const args = `${VALID_TEST_ARGS} --iteration-data`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_ARGUMENT");
- });
-
- test("Errors with the code `INVALID_DATA_FILE_TYPE` if the supplied data file doesn't end with the `.csv` extension", async () => {
- const args = `${VALID_TEST_ARGS} --iteration-data ${getTestJsonFilePath(
- "notjson-coll.txt",
- "collection"
- )}`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("INVALID_DATA_FILE_TYPE");
- });
-
- test("Errors with the code `FILE_NOT_FOUND` if the supplied data export file doesn't exist", async () => {
- const args = `${VALID_TEST_ARGS} --iteration-data notfound.csv`;
- const { stderr } = await runCLI(args);
-
- const out = getErrorCode(stderr);
- expect(out).toBe("FILE_NOT_FOUND");
- });
- });
-
- test("Prioritizes values from the supplied data export file over environment variables with relevant fallbacks for missing entries", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "iteration-data-tests-coll.json",
- "collection"
- );
- const ITERATION_DATA_PATH = getTestJsonFilePath(
- "iteration-data-export.csv",
- "environment"
- );
- const ENV_PATH = getTestJsonFilePath(
- "iteration-data-envs.json",
- "environment"
- );
- const args = `test ${COLL_PATH} --iteration-data ${ITERATION_DATA_PATH} -e ${ENV_PATH}`;
-
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
-
- const iterationCount = 3;
-
- Array.from({ length: iterationCount }).forEach((_, idx) =>
- expect(result.stdout).include(`Iteration: ${idx + 1}/${iterationCount}`)
- );
-
- expect(result.error).toBeNull();
- });
-
- test("Iteration count takes priority if supplied instead of inferring from the iteration data size", async () => {
- const COLL_PATH = getTestJsonFilePath(
- "iteration-data-tests-coll.json",
- "collection"
- );
- const ITERATION_DATA_PATH = getTestJsonFilePath(
- "iteration-data-export.csv",
- "environment"
- );
- const ENV_PATH = getTestJsonFilePath(
- "iteration-data-envs.json",
- "environment"
- );
-
- const iterationCount = 5;
- const args = `test ${COLL_PATH} --iteration-data ${ITERATION_DATA_PATH} -e ${ENV_PATH} --iteration-count ${iterationCount}`;
-
- const result = await runCLIWithNetworkRetry(args);
- if (result === null) return;
-
- Array.from({ length: iterationCount }).forEach((_, idx) =>
- expect(result.stdout).include(`Iteration: ${idx + 1}/${iterationCount}`)
- );
-
- expect(result.error).toBeNull();
- });
- });
-});
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/aws-signature-auth-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/aws-signature-auth-coll.json
deleted file mode 100644
index eae88b75..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/aws-signature-auth-coll.json
+++ /dev/null
@@ -1,101 +0,0 @@
-{
- "v": 3,
- "name": "AWS Signature Auth - collection",
- "folders": [],
- "requests": [
- {
- "v": "7",
- "id": "cm0dm70cw000687bnxi830zz7",
- "auth": {
- "addTo": "HEADERS",
- "region": "<>",
- "authType": "aws-signature",
- "accessKey": "<>",
- "secretKey": "<>",
- "authActive": true,
- "serviceName": "<>",
- "serviceToken": "",
- "grantTypeInfo": {
- "token": "",
- "isPKCE": false,
- "clientID": "",
- "grantType": "AUTHORIZATION_CODE",
- "authEndpoint": "",
- "clientSecret": "",
- "tokenEndpoint": "",
- "codeVerifierMethod": "S256"
- }
- },
- "body": {
- "body": null,
- "contentType": null
- },
- "name": "aws-signature-auth-headers",
- "method": "GET",
- "params": [],
- "headers": [],
- "endpoint": "<>",
- "testScript": "pw.test(\"Successfully sends relevant AWS signature information via headers\", ()=> {\n const { headers } = pw.response.body\n\n // Dynamic values, hence comparing the type.\n pw.expect(headers[\"authorization\"]).toBeType(\"string\");\n pw.expect(headers[\"x-amz-date\"]).toBeType(\"string\");\n \n pw.expect(headers[\"x-amz-content-sha256\"]).toBe(\"UNSIGNED-PAYLOAD\")\n \n // No session token supplied\n pw.expect(headers[\"x-amz-security-token\"]).toBe(undefined)\n \n});",
- "preRequestScript": "",
- "requestVariables": [
- {
- "key": "secretVarKey",
- "value": "<>",
- "active": true
- }
- ]
- },
- {
- "v": "7",
- "id": "cm0dm70cw000687bnxi830zz7",
- "auth": {
- "addTo": "QUERY_PARAMS",
- "region": "<>",
- "authType": "aws-signature",
- "accessKey": "<>",
- "secretKey": "<>",
- "authActive": true,
- "serviceName": "<>",
- "serviceToken": "<>",
- "grantTypeInfo": {
- "token": "",
- "isPKCE": false,
- "clientID": "",
- "grantType": "AUTHORIZATION_CODE",
- "authEndpoint": "",
- "clientSecret": "",
- "tokenEndpoint": "",
- "codeVerifierMethod": "S256"
- }
- },
- "body": {
- "body": null,
- "contentType": null
- },
- "name": "aws-signature-auth-query-params",
- "method": "GET",
- "params": [],
- "headers": [],
- "endpoint": "<>",
- "testScript": "pw.test(\"Successfully sends relevant AWS signature information via query params\", ()=> {\n const { args } = pw.response.body\n pw.expect(args[\"X-Amz-Algorithm\"]).toBe(\"AWS4-HMAC-SHA256\");\n pw.expect(args[\"X-Amz-Algorithm\"]).toBe(\"AWS4-HMAC-SHA256\");\n pw.expect(args[\"X-Amz-Credential\"]).toInclude(\"test-access-key\");\n pw.expect(args[\"X-Amz-Credential\"]).toInclude(\"eu-west-1/s3\");\n\n // Dynamic values, hence comparing the type.\n pw.expect(args[\"X-Amz-Date\"]).toBeType(\"string\");\n pw.expect(args[\"X-Amz-Signature\"]).toBeType(\"string\");\n\n pw.expect(args[\"X-Amz-Expires\"]).toBe(\"86400\")\n pw.expect(args[\"X-Amz-SignedHeaders\"]).toBe(\"host\")\n pw.expect(args[\"X-Amz-Security-Token\"]).toBe(\"test-token\")\n \n});",
- "preRequestScript": "",
- "requestVariables": [
- {
- "key": "awsRegion",
- "value": "eu-west-1",
- "active": true
- },
- {
- "key": "secretKey",
- "value": "test-secret-key-overriden",
- "active": true
- }
- ]
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v1-req-v0.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v1-req-v0.json
deleted file mode 100644
index bf63d2ae..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v1-req-v0.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "v": 1,
- "name": "coll-v1",
- "folders": [
- {
- "v": 1,
- "name": "coll-v1-child",
- "folders": [],
- "requests": [
- {
- "url": "https://echo.hoppscotch.io",
- "path": "/get",
- "headers": [
- { "key": "Inactive-Header", "value": "Inactive Header", "active": false },
- { "key": "Authorization", "value": "Bearer token123", "active": true }
- ],
- "params": [
- { "key": "key", "value": "value", "active": true },
- { "key": "inactive-key", "value": "inactive-param", "active": false }
- ],
- "name": "req-v0-II",
- "method": "GET",
- "preRequestScript": "",
- "testScript": "pw.test(\"Asserts request params\", () => {\n pw.expect(pw.response.body.args.key).toBe(\"value\")\n pw.expect(pw.response.body.args[\"inactive-key\"]).toBe(undefined)\n})\n\npw.test(\"Asserts request headers\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer token123\")\n pw.expect(pw.response.body.headers[\"inactive-header\"]).toBe(undefined)\n})",
- "contentType": "application/json",
- "body": "",
- "auth": "Bearer Token",
- "bearerToken": "token123"
- }
- ]
- }
- ],
- "requests": [
- {
- "url": "https://echo.hoppscotch.io",
- "path": "/get",
- "headers": [
- { "key": "Inactive-Header", "value": "Inactive Header", "active": false },
- { "key": "Authorization", "value": "Bearer token123", "active": true }
- ],
- "params": [
- { "key": "key", "value": "value", "active": true },
- { "key": "inactive-key", "value": "inactive-param", "active": false }
- ],
- "name": "req-v0",
- "method": "GET",
- "preRequestScript": "",
- "testScript": "pw.test(\"Asserts request params\", () => {\n pw.expect(pw.response.body.args.key).toBe(\"value\")\n pw.expect(pw.response.body.args[\"inactive-key\"]).toBe(undefined)\n})\n\npw.test(\"Asserts request headers\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer token123\")\n pw.expect(pw.response.body.headers[\"inactive-header\"]).toBe(undefined)\n})",
- "contentType": "application/json",
- "body": "",
- "auth": "Bearer Token",
- "bearerToken": "token123"
- }
- ]
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v1-req-v1.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v1-req-v1.json
deleted file mode 100644
index 9bfc979e..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v1-req-v1.json
+++ /dev/null
@@ -1,97 +0,0 @@
-{
- "v": 1,
- "name": "coll-v1",
- "folders": [
- {
- "v": 1,
- "name": "coll-v1-child",
- "folders": [],
- "requests": [
- {
- "v": "1",
- "endpoint": "https://echo.hoppscotch.io",
- "headers": [
- {
- "key": "Inactive-Header",
- "value": "Inactive Header",
- "active": false
- },
- {
- "key": "Authorization",
- "value": "Bearer token123",
- "active": true
- }
- ],
- "params": [
- {
- "key": "key",
- "value": "value",
- "active": true
- },
- {
- "key": "inactive-key",
- "value": "inactive-param",
- "active": false
- }
- ],
- "name": "req-v1-II",
- "method": "GET",
- "preRequestScript": "",
- "testScript": "pw.test(\"Asserts request params\", () => {\n pw.expect(pw.response.body.args.key).toBe(\"value\")\n pw.expect(pw.response.body.args[\"inactive-key\"]).toBe(undefined)\n})\n\npw.test(\"Asserts request headers\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer token123\")\n pw.expect(pw.response.body.headers[\"inactive-header\"]).toBe(undefined)\n})",
- "body": {
- "contentType": null,
- "body": null
- },
- "auth": {
- "authType": "bearer",
- "authActive": true,
- "token": "token123"
- }
- }
- ]
- }
- ],
- "requests": [
- {
- "v": "1",
- "endpoint": "https://echo.hoppscotch.io",
- "headers": [
- {
- "key": "Inactive-Header",
- "value": "Inactive Header",
- "active": false
- },
- {
- "key": "Authorization",
- "value": "Bearer token123",
- "active": true
- }
- ],
- "params": [
- {
- "key": "key",
- "value": "value",
- "active": true
- },
- {
- "key": "inactive-key",
- "value": "inactive-param",
- "active": false
- }
- ],
- "name": "req-v1",
- "method": "GET",
- "preRequestScript": "",
- "testScript": "pw.test(\"Asserts request params\", () => {\n pw.expect(pw.response.body.args.key).toBe(\"value\")\n pw.expect(pw.response.body.args[\"inactive-key\"]).toBe(undefined)\n})\n\npw.test(\"Asserts request headers\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer token123\")\n pw.expect(pw.response.body.headers[\"inactive-header\"]).toBe(undefined)\n})",
- "body": {
- "contentType": null,
- "body": null
- },
- "auth": {
- "authType": "bearer",
- "authActive": true,
- "token": "token123"
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v2-req-v2.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v2-req-v2.json
deleted file mode 100644
index 0bcbd132..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v2-req-v2.json
+++ /dev/null
@@ -1,109 +0,0 @@
-{
- "v": 2,
- "name": "coll-v2",
- "folders": [
- {
- "v": 2,
- "name": "coll-v2-child",
- "folders": [],
- "requests": [
- {
- "v": "2",
- "endpoint": "https://echo.hoppscotch.io",
- "headers": [
- {
- "key": "Inactive-Header",
- "value": "Inactive Header",
- "active": false
- },
- {
- "key": "Authorization",
- "value": "Bearer token123",
- "active": true
- }
- ],
- "params": [
- {
- "key": "key",
- "value": "value",
- "active": true
- },
- {
- "key": "inactive-key",
- "value": "inactive-param",
- "active": false
- }
- ],
- "name": "req-v2-II",
- "method": "GET",
- "preRequestScript": "",
- "testScript": "pw.test(\"Asserts request params\", () => {\n pw.expect(pw.response.body.args.key).toBe(\"value\")\n pw.expect(pw.response.body.args[\"inactive-key\"]).toBe(undefined)\n})\n\npw.test(\"Asserts request headers\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer token123\")\n pw.expect(pw.response.body.headers[\"inactive-header\"]).toBe(undefined)\n})",
- "body": {
- "contentType": null,
- "body": null
- },
- "auth": {
- "authType": "bearer",
- "authActive": true,
- "token": "token123"
- },
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
- }
- ],
- "requests": [
- {
- "v": "2",
- "endpoint": "https://echo.hoppscotch.io",
- "headers": [
- {
- "key": "Inactive-Header",
- "value": "Inactive Header",
- "active": false
- },
- {
- "key": "Authorization",
- "value": "Bearer token123",
- "active": true
- }
- ],
- "params": [
- {
- "key": "key",
- "value": "value",
- "active": true
- },
- {
- "key": "inactive-key",
- "value": "inactive-param",
- "active": false
- }
- ],
- "name": "req-v2",
- "method": "GET",
- "preRequestScript": "",
- "testScript": "pw.test(\"Asserts request params\", () => {\n pw.expect(pw.response.body.args.key).toBe(\"value\")\n pw.expect(pw.response.body.args[\"inactive-key\"]).toBe(undefined)\n})\n\npw.test(\"Asserts request headers\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer token123\")\n pw.expect(pw.response.body.headers[\"inactive-header\"]).toBe(undefined)\n})",
- "body": {
- "contentType": null,
- "body": null
- },
- "auth": {
- "authType": "bearer",
- "authActive": true,
- "token": "token123"
- },
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
-}
\ No newline at end of file
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v2-req-v3.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v2-req-v3.json
deleted file mode 100644
index 916e809d..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/coll-v2-req-v3.json
+++ /dev/null
@@ -1,109 +0,0 @@
-{
- "v": 2,
- "name": "coll-v2",
- "folders": [
- {
- "v": 2,
- "name": "coll-v2-child",
- "folders": [],
- "requests": [
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io",
- "headers": [
- {
- "key": "Inactive-Header",
- "value": "Inactive Header",
- "active": false
- },
- {
- "key": "Authorization",
- "value": "Bearer token123",
- "active": true
- }
- ],
- "params": [
- {
- "key": "key",
- "value": "value",
- "active": true
- },
- {
- "key": "inactive-key",
- "value": "inactive-param",
- "active": false
- }
- ],
- "name": "req-v3-II",
- "method": "GET",
- "preRequestScript": "",
- "testScript": "pw.test(\"Asserts request params\", () => {\n pw.expect(pw.response.body.args.key).toBe(\"value\")\n pw.expect(pw.response.body.args[\"inactive-key\"]).toBe(undefined)\n})\n\npw.test(\"Asserts request headers\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer token123\")\n pw.expect(pw.response.body.headers[\"inactive-header\"]).toBe(undefined)\n})",
- "body": {
- "contentType": null,
- "body": null
- },
- "auth": {
- "authType": "bearer",
- "authActive": true,
- "token": "token123"
- },
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
- }
- ],
- "requests": [
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io",
- "headers": [
- {
- "key": "Inactive-Header",
- "value": "Inactive Header",
- "active": false
- },
- {
- "key": "Authorization",
- "value": "Bearer token123",
- "active": true
- }
- ],
- "params": [
- {
- "key": "key",
- "value": "value",
- "active": true
- },
- {
- "key": "inactive-key",
- "value": "inactive-param",
- "active": false
- }
- ],
- "name": "req-v3",
- "method": "GET",
- "preRequestScript": "",
- "testScript": "pw.test(\"Asserts request params\", () => {\n pw.expect(pw.response.body.args.key).toBe(\"value\")\n pw.expect(pw.response.body.args[\"inactive-key\"]).toBe(undefined)\n})\n\npw.test(\"Asserts request headers\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer token123\")\n pw.expect(pw.response.body.headers[\"inactive-header\"]).toBe(undefined)\n})",
- "body": {
- "contentType": null,
- "body": null
- },
- "auth": {
- "authType": "bearer",
- "authActive": true,
- "token": "token123"
- },
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
-}
\ No newline at end of file
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-level-auth-headers-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-level-auth-headers-coll.json
deleted file mode 100644
index bdca78c6..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-level-auth-headers-coll.json
+++ /dev/null
@@ -1,227 +0,0 @@
-[
- {
- "v": 2,
- "name": "CollectionA",
- "folders": [
- {
- "v": 2,
- "name": "FolderA",
- "folders": [
- {
- "v": 2,
- "name": "FolderB",
- "folders": [
- {
- "v": 2,
- "name": "FolderC",
- "folders": [],
- "requests": [
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io",
- "name": "RequestD",
- "params": [],
- "headers": [
- {
- "active": true,
- "key": "X-Test-Header",
- "value": "Overriden at RequestD"
- }
- ],
- "method": "GET",
- "auth": {
- "authType": "basic",
- "authActive": true,
- "username": "username",
- "password": "password"
- },
- "preRequestScript": "",
- "testScript": "pw.test(\"Overrides auth and headers set at the parent folder\", ()=> {\n pw.expect(pw.response.body.headers[\"x-test-header\"]).toBe(\"Overriden at RequestD\");\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Basic dXNlcm5hbWU6cGFzc3dvcmQ=\");\n});",
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
- }
- ],
- "requests": [
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io",
- "name": "RequestC",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "preRequestScript": "",
- "testScript": "pw.test(\"Correctly inherits auth and headers from the parent folder\", ()=> {\n pw.expect(pw.response.body.headers[\"x-test-header\"]).toBe(\"Overriden at FolderB\");\n pw.expect(pw.response.body.headers[\"key\"]).toBe(\"test-key\");\n});",
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "api-key",
- "authActive": true,
- "addTo": "HEADERS",
- "key": "key",
- "value": "test-key"
- },
- "headers": [
- {
- "active": true,
- "key": "X-Test-Header",
- "value": "Overriden at FolderB"
- }
- ]
- }
- ],
- "requests": [
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io",
- "name": "RequestB",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "preRequestScript": "",
- "testScript": "pw.test(\"Correctly inherits auth and headers from the parent folder\", ()=> {\n pw.expect(pw.response.body.headers[\"x-test-header\"]).toBe(\"Set at root collection\");\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer BearerToken\");\n});",
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "id": "clpttpdq00003qp16kut6doqv"
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
- }
- ],
- "requests": [
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io",
- "name": "RequestA",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "preRequestScript": "",
- "testScript": "pw.test(\"Correctly inherits auth and headers from the root collection\", ()=> {\n pw.expect(pw.response.body.headers[\"x-test-header\"]).toBe(\"Set at root collection\");\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer BearerToken\");\n});",
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "id": "clpttpdq00003qp16kut6doqv"
- }
- ],
- "headers": [
- {
- "active": true,
- "key": "X-Test-Header",
- "value": "Set at root collection"
- }
- ],
- "auth": {
- "authType": "bearer",
- "authActive": true,
- "token": "BearerToken"
- }
- },
- {
- "v": 2,
- "name": "CollectionB",
- "folders": [
- {
- "v": 2,
- "name": "FolderA",
- "folders": [],
- "requests": [
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io",
- "name": "RequestB",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "preRequestScript": "",
- "testScript": "pw.test(\"Correctly inherits auth and headers from the parent folder\", ()=> {\n pw.expect(pw.response.body.headers[\"x-test-header\"]).toBe(\"Set at root collection\");\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer BearerToken\");\n});",
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "id": "clpttpdq00003qp16kut6doqv"
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
- }
- ],
- "requests": [
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io",
- "name": "RequestA",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "preRequestScript": "",
- "testScript": "pw.test(\"Correctly inherits auth and headers from the root collection\", ()=> {\n pw.expect(pw.response.body.headers[\"x-test-header\"]).toBe(\"Set at root collection\");\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Bearer BearerToken\");\n});",
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "id": "clpttpdq00003qp16kut6doqv"
- }
- ],
- "headers": [
- {
- "active": true,
- "key": "X-Test-Header",
- "value": "Set at root collection"
- }
- ],
- "auth": {
- "authType": "bearer",
- "authActive": true,
- "token": "BearerToken"
- }
- }
-]
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-level-scripts-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-level-scripts-coll.json
deleted file mode 100644
index 38bae839..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-level-scripts-coll.json
+++ /dev/null
@@ -1,114 +0,0 @@
-{
- "v": 12,
- "name": "collection-level-scripts-coll",
- "variables": [],
- "description": null,
- "folders": [
- {
- "v": 12,
- "name": "target-folder",
- "variables": [],
- "description": null,
- "folders": [],
- "requests": [
- {
- "v": "17",
- "id": "cl-script-req-1",
- "name": "target-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [],
- "preRequestScript": "pw.env.set(\"REQ_RAN\", \"yes\");\npw.env.set(\"PRE_ORDER\", pw.env.get(\"PRE_ORDER\") + \"->target-req\");",
- "testScript": "pw.env.set(\"TEST_ORDER\", \"target-req\");\npw.env.set(\"ORDER_AT_REQ\", pw.env.get(\"TEST_ORDER\"));\npw.test(\"pre-script cascade ran in root->target-folder->target-req order\", () => {\n pw.expect(pw.env.get(\"PRE_ORDER\")).toBe(\"root->target-folder->target-req\");\n});\npw.test(\"all cascade pre-scripts committed env vars\", () => {\n pw.expect(pw.env.get(\"ROOT_RAN\")).toBe(\"yes\");\n pw.expect(pw.env.get(\"TARGET_FOLDER_RAN\")).toBe(\"yes\");\n pw.expect(pw.env.get(\"REQ_RAN\")).toBe(\"yes\");\n});\npw.test(\"request-level test observed request position in test-cascade\", () => {\n pw.expect(pw.env.get(\"ORDER_AT_REQ\")).toBe(\"target-req\");\n});",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {},
- "description": null
- },
- {
- "v": "17",
- "id": "cl-script-req-2",
- "name": "sibling-request-in-target-folder",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [],
- "preRequestScript": "pw.env.set(\"PRE_ORDER\", pw.env.get(\"PRE_ORDER\") + \"->sibling-req-in-target\");",
- "testScript": "pw.env.set(\"TEST_ORDER\", \"sibling-req-in-target\");\npw.test(\"sibling request cascade is root->target-folder->this-request\", () => {\n pw.expect(pw.env.get(\"PRE_ORDER\")).toBe(\"root->target-folder->sibling-req-in-target\");\n});",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {},
- "description": null
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [],
- "preRequestScript": "pw.env.set(\"TARGET_FOLDER_RAN\", \"yes\");\npw.env.set(\"TARGET_FOLDER_RUN_COUNT\", String((parseInt(pw.env.get(\"TARGET_FOLDER_RUN_COUNT\") || \"0\", 10)) + 1));\npw.env.set(\"PRE_ORDER\", pw.env.get(\"PRE_ORDER\") + \"->target-folder\");",
- "testScript": "pw.env.set(\"TEST_ORDER\", pw.env.get(\"TEST_ORDER\") + \"->target-folder\");\npw.env.set(\"ORDER_AT_TARGET_FOLDER\", pw.env.get(\"TEST_ORDER\"));"
- },
- {
- "v": 12,
- "name": "sibling-folder",
- "variables": [],
- "description": null,
- "folders": [],
- "requests": [
- {
- "v": "17",
- "id": "cl-script-req-3",
- "name": "sibling-request-in-sibling-folder",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [],
- "preRequestScript": "pw.env.set(\"PRE_ORDER\", pw.env.get(\"PRE_ORDER\") + \"->sibling-req-in-sibling\");",
- "testScript": "pw.env.set(\"TEST_ORDER\", \"sibling-req-in-sibling\");\npw.test(\"sibling-folder cascade is root->sibling-folder->this-request (no target-folder leak)\", () => {\n pw.expect(pw.env.get(\"PRE_ORDER\")).toBe(\"root->sibling-folder->sibling-req-in-sibling\");\n});\npw.test(\"target-folder pre-script ran exactly twice (one per request in target-folder)\", () => {\n pw.expect(pw.env.get(\"TARGET_FOLDER_RUN_COUNT\")).toBe(\"2\");\n});",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {},
- "description": null
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [],
- "preRequestScript": "pw.env.set(\"SIBLING_FOLDER_RAN\", \"yes\");\npw.env.set(\"PRE_ORDER\", pw.env.get(\"PRE_ORDER\") + \"->sibling-folder\");",
- "testScript": "pw.env.set(\"TEST_ORDER\", pw.env.get(\"TEST_ORDER\") + \"->sibling-folder\");"
- }
- ],
- "requests": [],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [],
- "preRequestScript": "pw.env.set(\"ROOT_RAN\", \"yes\");\npw.env.set(\"PRE_ORDER\", \"root\");",
- "testScript": "pw.env.set(\"TEST_ORDER\", pw.env.get(\"TEST_ORDER\") + \"->root\");\npw.test(\"test-script cascade ran in request->folder->root order for every request\", () => {\n pw.expect([\"target-req->target-folder->root\", \"sibling-req-in-target->target-folder->root\", \"sibling-req-in-sibling->sibling-folder->root\"].includes(pw.env.get(\"TEST_ORDER\"))).toBe(true);\n});"
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-with-variables.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-with-variables.json
deleted file mode 100644
index d5383da5..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/collection-with-variables.json
+++ /dev/null
@@ -1,326 +0,0 @@
-{
- "id": "cmeicx49r00xylb1jxektmknk",
- "_ref_id": "coll_meicx3z7_a1cb5e72-cd1b-414b-adc2-7d601ca0936d",
- "v": 10,
- "name": "coll-with-variables",
- "folders": [
- {
- "id": "cmeicy6fu00xzlb1jqmmqbjdm",
- "_ref_id": "coll_meie14lh_818ea8a2-9839-4a1c-8cce-cc7565b5f594",
- "v": 10,
- "name": "folder-1",
- "folders": [],
- "requests": [
- {
- "v": "15",
- "id": "cmeicyhnn00y1lb1j8d80g7ys",
- "name": "request-1",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [
- {
- "key": "collection-var-1",
- "value": "<>",
- "active": true,
- "description": ""
- },
- {
- "key": "collection-var-2",
- "value": "<>",
- "active": true,
- "description": ""
- },
- {
- "key": "folder-var-1",
- "value": "<>",
- "active": true,
- "description": ""
- },
- {
- "key": "folder-var-2",
- "value": "<>",
- "active": true,
- "description": ""
- }
- ],
- "headers": [],
- "preRequestScript": "",
- "testScript": "pw.test('Correctly inherits collection variables from the parent collection and folder', () => {\n pw.expect([\n \"collection-var-1-initial-value\",\n \"collection-var-1-current-value\"\n ]).toInclude(pw.response.body.args[\"collection-var-1\"]);\n\n pw.expect([\n \"collection-var-2-initial-value\",\n \"collection-var-2-current-value\"\n ]).toInclude(pw.response.body.args[\"collection-var-2\"]);\n\n pw.expect([\n \"folder-variable-1-initial-value\",\n \"folder-variable-1-current-value\"\n ]).toInclude(pw.response.body.args[\"folder-var-1\"]);\n\n pw.expect([\n \"folder-variable-2-initial-value\",\n \"folder-variable-2-current-value\"\n ]).toInclude(pw.response.body.args[\"folder-var-2\"]);\n});",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [],
- "variables": [
- {
- "key": "folder-variable-1",
- "secret": false,
- "currentValue": "",
- "initialValue": "folder-variable-1-initial-value"
- },
- {
- "key": "folder-variable-2",
- "secret": false,
- "currentValue": "",
- "initialValue": "folder-variable-2-initial-value"
- }
- ]
- },
- {
- "id": "empty_folder_test",
- "_ref_id": "coll_empty_folder",
- "v": 10,
- "name": "folder-without-variables",
- "folders": [
- {
- "id": "nested_folder_test",
- "_ref_id": "coll_nested_folder",
- "v": 10,
- "name": "nested-folder",
- "folders": [],
- "requests": [
- {
- "v": "15",
- "id": "nested_request",
- "name": "deeply-nested-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [
- {
- "key": "nested-var-1",
- "value": "<>",
- "active": true,
- "description": ""
- },
- {
- "key": "nested-var-2",
- "value": "<>",
- "active": true,
- "description": ""
- }
- ],
- "headers": [],
- "preRequestScript": "",
- "testScript": "pw.test('Nested folder should inherit variables from root collection through parent', () => {\n pw.expect([\n \"collection-var-1-initial-value\",\n \"collection-var-1-current-value\"\n ]).toInclude(pw.response.body.args[\"nested-var-1\"]);\n\n pw.expect([\n \"collection-var-2-initial-value\",\n \"collection-var-2-current-value\"\n ]).toInclude(pw.response.body.args[\"nested-var-2\"]);\n});",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [],
- "variables": []
- }
- ],
- "requests": [
- {
- "v": "15",
- "id": "request_in_empty_folder",
- "name": "request-inheriting-collection-vars",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [
- {
- "key": "inherited-var-1",
- "value": "<>",
- "active": true,
- "description": ""
- },
- {
- "key": "inherited-var-2",
- "value": "<>",
- "active": true,
- "description": ""
- }
- ],
- "headers": [],
- "preRequestScript": "",
- "testScript": "pw.test('Folder without variables should inherit from parent collection', () => {\n pw.expect([\n \"collection-var-1-initial-value\",\n \"collection-var-1-current-value\"\n ]).toInclude(pw.response.body.args[\"inherited-var-1\"]);\n\n pw.expect([\n \"collection-var-2-initial-value\",\n \"collection-var-2-current-value\"\n ]).toInclude(pw.response.body.args[\"inherited-var-2\"]);\n});",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [],
- "variables": []
- },
- {
- "id": "precedence_test_folder",
- "_ref_id": "coll_precedence_folder",
- "v": 10,
- "name": "folder-with-override",
- "folders": [],
- "requests": [
- {
- "v": "15",
- "id": "request_with_override",
- "name": "request-with-folder-override",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [
- {
- "key": "overridden-var",
- "value": "<>",
- "active": true,
- "description": ""
- },
- {
- "key": "non-overridden-var",
- "value": "<>",
- "active": true,
- "description": ""
- }
- ],
- "headers": [],
- "preRequestScript": "",
- "testScript": "pw.test('Folder variable should take precedence over collection variable with same key', () => {\n // collection-variable-1 is overridden by folder, should be 'folder-override-value'\n pw.expect(pw.response.body.args[\"overridden-var\"]).toBe(\"folder-override-value\");\n\n // collection-variable-2 is NOT overridden, should be from collection\n pw.expect([\n \"collection-var-2-initial-value\",\n \"collection-var-2-current-value\"\n ]).toInclude(pw.response.body.args[\"non-overridden-var\"]);\n});",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [],
- "variables": [
- {
- "key": "collection-variable-1",
- "secret": false,
- "currentValue": "",
- "initialValue": "folder-override-value"
- }
- ]
- }
- ],
- "requests": [
- {
- "v": "15",
- "id": "root_level_request",
- "name": "root-level-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [
- {
- "key": "root-var-1",
- "value": "<>",
- "active": true,
- "description": ""
- },
- {
- "key": "root-var-2",
- "value": "<>",
- "active": true,
- "description": ""
- }
- ],
- "headers": [],
- "preRequestScript": "",
- "testScript": "pw.test('Root-level request should access collection variables directly', () => {\n pw.expect([\n \"collection-var-1-initial-value\",\n \"collection-var-1-current-value\"\n ]).toInclude(pw.response.body.args[\"root-var-1\"]);\n\n pw.expect([\n \"collection-var-2-initial-value\",\n \"collection-var-2-current-value\"\n ]).toInclude(pw.response.body.args[\"root-var-2\"]);\n});",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- },
- {
- "v": "15",
- "id": "root_level_request_with_precedence",
- "name": "root-request-variable-precedence",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [
- {
- "key": "precedence-test",
- "value": "<>",
- "active": true,
- "description": ""
- }
- ],
- "headers": [],
- "preRequestScript": "",
- "testScript": "pw.test('Request variable takes precedence over collection variable with same key', () => {\n // collection-variable-1 exists at collection level with value \"collection-var-1-initial-value\"\n // but request variable overrides it with \"request-wins\"\n pw.expect(pw.response.body.args[\"precedence-test\"]).toBe(\"request-wins\");\n});",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [
- {
- "key": "collection-variable-1",
- "value": "request-wins",
- "active": true
- }
- ],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "headers": [],
- "variables": [
- {
- "key": "collection-variable-1",
- "secret": false,
- "currentValue": "",
- "initialValue": "collection-var-1-initial-value"
- },
- {
- "key": "collection-variable-2",
- "secret": false,
- "currentValue": "",
- "initialValue": "collection-var-2-initial-value"
- }
- ]
-}
\ No newline at end of file
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/content-type-header-scenarios.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/content-type-header-scenarios.json
deleted file mode 100644
index 9aea2c0f..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/content-type-header-scenarios.json
+++ /dev/null
@@ -1,171 +0,0 @@
-{
- "v": 2,
- "name": "content-type-header-scenarios",
- "folders": [],
- "requests": [
- {
- "v": "6",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "body": "\n\n \n 12345 \n John Doe \n john.doe@example.com \n \n \n 98765 \n Sample Product \n 2 \n \n \n",
- "contentType": "text/xml"
- },
- "name": "content-type-header-assignment",
- "method": "POST",
- "params": [],
- "headers": [],
- "endpoint": "https://echo.hoppscotch.io",
- "testScript": "pw.test(\"The `Content-Type` header is assigned the content type value set at the request body level\", ()=> {\n pw.expect(pw.response.body.headers[\"content-type\"]).toBe(\"text/xml\");\n});",
- "preRequestScript": "",
- "requestVariables": []
- },
- {
- "v": "6",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "body": "\n\n \n 12345 \n John Doe \n john.doe@example.com \n \n \n 98765 \n Sample Product \n 2 \n \n \n",
- "contentType": "application/json"
- },
- "name": "content-type-header-override",
- "method": "POST",
- "params": [],
- "headers": [
- {
- "key": "Content-Type",
- "value": "application/xml",
- "active": true
- }
- ],
- "endpoint": "https://echo.hoppscotch.io",
- "testScript": "pw.test(\"The `Content-Type` header overrides the content type value set at the request body level\", ()=> {\n pw.expect(pw.response.body.headers[\"content-type\"]).toBe(\"application/xml\");\n});",
- "preRequestScript": "",
- "requestVariables": []
- },
- {
- "v": "6",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "body": "\n\n \n 12345 \n John Doe \n john.doe@example.com \n \n \n 98765 \n Sample Product \n 2 \n \n \n",
- "contentType": "application/json"
- },
- "name": "multiple-content-type-headers",
- "method": "POST",
- "params": [],
- "headers": [
- {
- "key": "Content-Type",
- "value": "text/xml",
- "active": true
- },
- {
- "key": "Content-Type",
- "value": "application/json",
- "active": true
- },
- {
- "key": "Content-Type",
- "value": "application/xml",
- "active": true
- }
- ],
- "endpoint": "https://echo.hoppscotch.io",
- "testScript": "pw.test(\"The last occurrence will be considered among multiple `Content-Type` headers\", ()=> {\n pw.expect(pw.response.body.headers[\"content-type\"]).toBe(\"application/xml\");\n});",
- "preRequestScript": "",
- "requestVariables": []
- },
- {
- "v": "6",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "body": "\n\n \n 12345 \n John Doe \n john.doe@example.com \n \n \n 98765 \n Sample Product \n 2 \n \n \n",
- "contentType": null
- },
- "name": "multiple-content-type-headers-different-casing",
- "method": "POST",
- "params": [],
- "headers": [
- {
- "key": "Content-Type",
- "value": "text/xml",
- "active": true
- },
- {
- "key": "content-Type",
- "value": "application/json",
- "active": true
- },
- {
- "key": "Content-type",
- "value": "text/plain",
- "active": true
- },
- {
- "key": "CONTENT-TYPE",
- "value": "application/xml",
- "active": true
- }
- ],
- "endpoint": "https://echo.hoppscotch.io",
- "testScript": "pw.test(\"The last occurrence will be considered among multiple `Content-Type` headers following different casing\", ()=> {\n pw.expect(pw.response.body.headers[\"content-type\"]).toBe(\"application/xml\");\n});",
- "preRequestScript": "",
- "requestVariables": []
- },
- {
- "v": "6",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "body": "\n\n \n 12345 \n John Doe \n john.doe@example.com \n \n \n 98765 \n Sample Product \n 2 \n \n \n",
- "contentType": null
- },
- "name": "multiple-content-type-headers-different-casing-without-value-set-at-body",
- "method": "POST",
- "params": [],
- "headers": [
- {
- "key": "Content-Type",
- "value": "text/xml",
- "active": true
- },
- {
- "key": "content-Type",
- "value": "application/json",
- "active": true
- },
- {
- "key": "Content-type",
- "value": "text/plain",
- "active": true
- },
- {
- "key": "CONTENT-TYPE",
- "value": "application/xml",
- "active": true
- }
- ],
- "endpoint": "https://echo.hoppscotch.io",
- "testScript": "pw.test(\"The content type is inferred from the `Content-Type` header if not set at the request body\", ()=> {\n pw.expect(pw.response.body.headers[\"content-type\"]).toBe(\"application/xml\");\n});",
- "preRequestScript": "",
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
-}
\ No newline at end of file
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/digest-auth-failure-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/digest-auth-failure-coll.json
deleted file mode 100644
index d8ab5ef2..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/digest-auth-failure-coll.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "v": 3,
- "name": "Digest Auth (failure state) - collection",
- "folders": [],
- "requests": [
- {
- "v": "8",
- "id": "cm0dm70cw000687bnxi830zz7",
- "auth": {
- "authType": "digest",
- "authActive": true,
- "username": "<>",
- "password": "<>",
- "realm": "",
- "nonce": "",
- "algorithm": "MD5",
- "qop": "auth",
- "nc": "",
- "cnonce": "",
- "opaque": "",
- "disableRetry": true
- },
- "body": {
- "body": null,
- "contentType": null
- },
- "name": "digest-auth-headers",
- "method": "GET",
- "params": [],
- "headers": [],
- "endpoint": "<>",
- "testScript": "pw.test(\"Status code is not 200\", ()=> { pw.expect(pw.response.status).not.toBe(200);}); \n pw.test(\"Receives the www-authenticate header\", ()=> { pw.expect(pw.response.headers['www-authenticate']).not.toBeType('string');});",
- "preRequestScript": "",
- "responses": {},
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/digest-auth-success-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/digest-auth-success-coll.json
deleted file mode 100644
index 16f0b6fc..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/digest-auth-success-coll.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "v": 3,
- "name": "Digest Auth (success state) - collection",
- "folders": [],
- "requests": [
- {
- "v": "8",
- "id": "cm0dm70cw000687bnxi830zz7",
- "auth": {
- "authType": "digest",
- "authActive": true,
- "username": "<>",
- "password": "<>",
- "realm": "",
- "nonce": "",
- "algorithm": "MD5",
- "qop": "auth",
- "nc": "",
- "cnonce": "",
- "opaque": "",
- "disableRetry": false
- },
- "body": {
- "body": null,
- "contentType": null
- },
- "name": "digest-auth-headers",
- "method": "GET",
- "params": [],
- "headers": [],
- "endpoint": "<>",
- "testScript": "pw.test(\"Status code is 200\", ()=> { pw.expect(pw.response.status).toBe(200);}); \n pw.test(\"Receives the www-authenticate header\", ()=> { pw.expect(pw.response.headers['www-authenticate']).toBeType('string');});",
- "preRequestScript": "",
- "responses": {},
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/env-flag-tests-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/env-flag-tests-coll.json
deleted file mode 100644
index ded538ab..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/env-flag-tests-coll.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "v": 1,
- "name": "env-flag-tests",
- "folders": [],
- "requests": [
- {
- "v": "3",
- "endpoint": "<>",
- "name": "test1",
- "params": [],
- "headers": [],
- "method": "POST",
- "auth": { "authType": "none", "authActive": true },
- "preRequestScript": "",
- "testScript": "const HOST = pw.env.get(\"HOST\");\nconst UNSET_ENV = pw.env.get(\"UNSET_ENV\");\nconst EXPECTED_URL = \"https://echo.hoppscotch.io\";\nconst URL = pw.env.get(\"URL\");\nconst BODY_VALUE = pw.env.get(\"BODY_VALUE\");\n\n// Check JSON response property\npw.test(\"Check headers properties.\", ()=> {\n pw.expect(pw.response.body.headers.host).toBe(HOST);\n});\n\npw.test(\"Check data properties.\", () => {\n\tconst DATA = pw.response.body.data;\n \n pw.expect(DATA).toBeType(\"string\");\n pw.expect(JSON.parse(DATA).body_key).toBe(BODY_VALUE);\n});\n\npw.test(\"Check request URL.\", () => {\n pw.expect(URL).toBe(EXPECTED_URL);\n})\n\npw.test(\"Check unset ENV.\", () => {\n pw.expect(UNSET_ENV).toBeType(\"undefined\");\n})",
- "body": {
- "contentType": "application/json",
- "body": "{\n \"<>\":\"<>\"\n}"
- },
- "requestVariables": []
- }
- ]
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/fails-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/fails-coll.json
deleted file mode 100644
index b8172049..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/fails-coll.json
+++ /dev/null
@@ -1,47 +0,0 @@
-[
- {
- "v": 1,
- "name": "tests",
- "folders": [],
- "requests": [
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io/<>",
- "name": "",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "preRequestScript": "pw.env.set(\"HEADERS_TYPE1\", \"devblin_local1\");",
- "testScript": "// Check status code is 200\npwd.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\n// Check JSON response property\npw.test(\"Check JSON response property\", ()=> {\n pw.expect(pw.response.body.method).toBe(\"GET\");\n pw.expect(pw.response.body.headers).toBeType(\"string\");\n});",
- "body": {
- "contentType": "application/json",
- "body": "{\n\"test\": \"<>\"\n}"
- },
- "requestVariables": []
- },
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.dio/<>",
- "name": "success",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "preRequestScript": "pw.env.setd(\"HEADERS_TYPE2\", \"devblin_local2\");",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(300);\n});\n\n// Check JSON response property\npw.test(\"Check JSON response property\", ()=> {\n pw.expect(pw.response.body.method).toBe(\"GET\");\n pw.expect(pw.response.body.headers).toBeType(\"object\");\n});",
- "body": {
- "contentType": "application/json",
- "body": "{\n\"test\": \"<>\"\n}"
- },
- "requestVariables": []
- }
- ]
- }
-]
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/hawk-auth-success-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/hawk-auth-success-coll.json
deleted file mode 100644
index fbf755fb..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/hawk-auth-success-coll.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "v": 3,
- "name": "HAWK Auth (success state) - collection",
- "folders": [],
- "requests": [
- {
- "v": "12",
- "id": "cm0dm70cw000687bnxi830zz2",
- "auth": {
- "authType": "hawk",
- "authActive": true,
- "authId": "<>",
- "authKey": "<>",
- "algorithm": "<>",
- "includePayloadHash": false,
- "user": "<>",
- "nonce": "<>",
- "ext": "<>",
- "app": "<>",
- "dlg": "<>",
- "timestamp": "<>"
- },
- "body": {
- "body": null,
- "contentType": null
- },
- "name": "hawk-auth-headers",
- "method": "GET",
- "params": [],
- "headers": [],
- "endpoint": "<>",
- "testScript": "pw.test(\"Status code is 200\", ()=> { pw.expect(pw.response.status).toBe(200);});",
- "preRequestScript": "",
- "responses": {},
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/invalid-mixed-versions-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/invalid-mixed-versions-coll.json
deleted file mode 100644
index 6b53a4f0..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/invalid-mixed-versions-coll.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "v": 5,
- "id": "cmbgcmyly10yhdjet63hiorps",
- "name": "Invalid mixed versions collection",
- "folders": [
- {
- "v": 8,
- "id": "cmbgnb4h100v613phgrz6vku9",
- "name": "fold1",
- "folders": [],
- "requests": [
- {
- "v": "13",
- "name": "req",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [],
- "preRequestScript": "",
- "testScript": "",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [],
- "_ref_id": "coll_mbgnb8zy_eab190e2-6770-428c-8645-f49e88a3fe90"
- }
- ],
- "requests": [],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [],
- "_ref_id": "coll_mbgnb8zy_7c3f6eca-bd94-44a5-90e3-3f7c2126d63e"
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/iteration-data-tests-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/iteration-data-tests-coll.json
deleted file mode 100644
index d70aa845..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/iteration-data-tests-coll.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "v": 1,
- "name": "iteration-data-tests-coll",
- "folders": [],
- "requests": [
- {
- "v": "3",
- "endpoint": "<>",
- "name": "test1",
- "params": [],
- "headers": [],
- "method": "POST",
- "auth": { "authType": "none", "authActive": true },
- "preRequestScript": "",
- "testScript": "// Iteration data is prioritised over environment variables \n const { data, headers } = pw.response.body;\n pw.expect(headers['host']).toBe('echo.hoppscotch.io')\n // Falls back to environment variables for missing entries in data export\n pw.expect(data).toInclude('overriden-body-key-at-environment')\n pw.expect(data).toInclude('body_value')",
- "body": {
- "contentType": "application/json",
- "body": "{\n \"<>\":\"<>\"\n}"
- },
- "requestVariables": []
- }
- ]
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/jsonc-body-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/jsonc-body-coll.json
deleted file mode 100644
index 247e3672..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/jsonc-body-coll.json
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "v": 11,
- "name": "JSONC Body Test Collection",
- "folders": [],
- "requests": [
- {
- "v": "17",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "body": "{\n \"key1\": \"value1\", // inline comment\n \"key2\": \"value2\" // another comment\n}",
- "contentType": "application/json"
- },
- "name": "Echo with inline comments",
- "method": "POST",
- "params": [],
- "headers": [],
- "endpoint": "https://echo.hoppscotch.io",
- "testScript": "hopp.test('Should successfully parse JSONC with comments', () => {\n hopp.expect(hopp.response.statusCode).toBe(200);\n const data = JSON.parse(hopp.response.body.asJSON().data);\n hopp.expect(data.key1).toBe('value1');\n hopp.expect(data.key2).toBe('value2');\n});",
- "preRequestScript": "",
- "requestVariables": [],
- "responses": {}
- },
- {
- "v": "17",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "body": "{\n /* Multi-line comment\n should also work */\n \"message\": \"test\",\n \"nested\": {\n \"field\": \"value\" // another comment\n }\n}",
- "contentType": "application/json"
- },
- "name": "Echo with multiline comments",
- "method": "POST",
- "params": [],
- "headers": [],
- "endpoint": "https://echo.hoppscotch.io",
- "testScript": "hopp.test('Should successfully parse JSONC with multiline comments', () => {\n hopp.expect(hopp.response.statusCode).toBe(200);\n const data = JSON.parse(hopp.response.body.asJSON().data);\n hopp.expect(data.message).toBe('test');\n hopp.expect(data.nested.field).toBe('value');\n});",
- "preRequestScript": "",
- "requestVariables": [],
- "responses": {}
- },
- {
- "v": "17",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "body": "{\n \"key\": \"value\",\n \"count\": 42,\n}",
- "contentType": "application/json"
- },
- "name": "Echo with trailing commas",
- "method": "POST",
- "params": [],
- "headers": [],
- "endpoint": "https://echo.hoppscotch.io",
- "testScript": "hopp.test('Should successfully parse JSONC with trailing commas', () => {\n hopp.expect(hopp.response.statusCode).toBe(200);\n const data = JSON.parse(hopp.response.body.asJSON().data);\n hopp.expect(data.key).toBe('value');\n hopp.expect(data.count).toBe(42);\n});",
- "preRequestScript": "",
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [],
- "variables": [],
- "description": ""
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/jwt-auth-headers-success-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/jwt-auth-headers-success-coll.json
deleted file mode 100644
index 38d15711..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/jwt-auth-headers-success-coll.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "v": 3,
- "name": "JWT Auth (headers) - collection",
- "folders": [],
- "requests": [
- {
- "v": "13",
- "id": "cm0dm70cw000687bnxi830zz3",
- "auth": {
- "authType": "jwt",
- "authActive": true,
- "addTo": "HEADERS",
- "algorithm": "<>",
- "secret": "<>",
- "privateKey": "<>",
- "payload": "<>",
- "jwtHeaders": "<>",
- "headerPrefix": "<>",
- "isSecretBase64Encoded": false
- },
- "body": {
- "body": null,
- "contentType": null
- },
- "name": "jwt-auth-headers",
- "method": "GET",
- "params": [],
- "headers": [],
- "endpoint": "<>",
- "testScript": "pw.test(\"Status code is 200\", ()=> { pw.expect(pw.response.status).toBe(200);});",
- "preRequestScript": "",
- "responses": {},
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/jwt-auth-params-success-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/jwt-auth-params-success-coll.json
deleted file mode 100644
index 25a9a3c1..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/jwt-auth-params-success-coll.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "v": 3,
- "name": "JWT Auth (params) - collection",
- "folders": [],
- "requests": [
- {
- "v": "13",
- "id": "cm0dm70cw000687bnxi830zz4",
- "auth": {
- "authType": "jwt",
- "authActive": true,
- "addTo": "QUERY_PARAMS",
- "algorithm": "<>",
- "secret": "<>",
- "privateKey": "<>",
- "payload": "<>",
- "jwtHeaders": "<>",
- "paramName": "<>",
- "isSecretBase64Encoded": false
- },
- "body": {
- "body": null,
- "contentType": null
- },
- "name": "jwt-auth-params",
- "method": "GET",
- "params": [],
- "headers": [],
- "endpoint": "<>",
- "testScript": "pw.test(\"Status code is 200\", ()=> { pw.expect(pw.response.status).toBe(200);});",
- "preRequestScript": "",
- "responses": {},
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/malformed-coll-2.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/malformed-coll-2.json
deleted file mode 100644
index 8df994d7..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/malformed-coll-2.json
+++ /dev/null
@@ -1,7 +0,0 @@
-[
- {
- "v": 1,
- "name": "tests",
- "folders": []
- }
-]
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/malformed-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/malformed-coll.json
deleted file mode 100644
index a4c46721..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/malformed-coll.json
+++ /dev/null
@@ -1,46 +0,0 @@
-[
- {
- "v": 1,
- "folders": [],
- "requests":
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io/<>",
- "name": "fail",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "preRequestScript": "pw.env.set(\"HEADERS_TYPE1\", \"devblin_local1\");",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\n// Check JSON response property\npw.test(\"Check JSON response property\", ()=> {\n pw.expect(pw.response.body.method).toBe(\"GET\");\n pw.expect(pw.response.body.headers).toBeType(\"string\");\n});",
- "body": {
- "contentType": "application/json",
- "body": "{\n\"test\": \"<>\"\n}"
- },
- "requestVariables": [],
- },
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io/<>",
- "name": "success",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "preRequestScript": "pw.env.set(\"HEADERS_TYPE2\", \"devblin_local2\");",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(300);\n});\n\n// Check JSON response property\npw.test(\"Check JSON response property\", ()=> {\n pw.expect(pw.response.body.method).toBe(\"GET\");\n pw.expect(pw.response.body.headers).toBeType(\"object\");\n});",
- "body": {
- "contentType": "application/json",
- "body": "{\n\"test\": \"<>\"\n}"
- },
- "requestVariables": []
- }
- ]
- }
-]
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/multipart-form-data-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/multipart-form-data-coll.json
deleted file mode 100644
index 37d419dc..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/multipart-form-data-coll.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "v": 3,
- "name": "Multipart form data content type - Collection",
- "folders": [],
- "requests": [
- {
- "v": "7",
- "endpoint": "https://echo.hoppscotch.io",
- "name": "multipart-form-data-sample-req",
- "params": [],
- "headers": [],
- "method": "POST",
- "auth": {
- "authType": "none",
- "authActive": true,
- "addTo": "HEADERS",
- "grantTypeInfo": {
- "authEndpoint": "test-authorization-endpoint",
- "tokenEndpoint": "test-token-endpont",
- "clientID": "test-client-id",
- "clientSecret": "test-client-secret",
- "isPKCE": true,
- "codeVerifierMethod": "S256",
- "grantType": "AUTHORIZATION_CODE",
- "token": "test-token"
- }
- },
- "preRequestScript": "",
- "testScript": "pw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully derives the relevant headers based on the content type\", () => {\n pw.expect(pw.response.body.headers['content-type']).toInclude(\"multipart/form-data\");\n});\n\npw.test(\"Successfully sends the form data in the request body\", () => {\n // Dynamic value\n pw.expect(pw.response.body.data).toBeType(\"string\");\n});",
- "body": {
- "contentType": "multipart/form-data",
- "body": [
- {
- "key": "key1",
- "value": "value1",
- "active": true,
- "isFile": false
- },
- {
- "key": "key2",
- "value": [{}],
- "active": true,
- "isFile": true
- }
- ]
- },
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/multiple-child-collections-auth-headers-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/multiple-child-collections-auth-headers-coll.json
deleted file mode 100644
index f56863a4..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/multiple-child-collections-auth-headers-coll.json
+++ /dev/null
@@ -1,700 +0,0 @@
-{
- "v": 6,
- "id": "cm9wmuzj46s3imbs891pdamv4",
- "name": "Multiple child collections with authorization, headers and variables set at each level",
- "folders": [
- {
- "v": 6,
- "id": "cm9wmuzjp6s3lmbs878f67qr9",
- "name": "folder-1",
- "folders": [
- {
- "v": 6,
- "id": "cm9wmuzln6s3umbs8j8lasa3u",
- "name": "folder-11",
- "folders": [],
- "requests": [
- {
- "v": "11",
- "name": "folder-11-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-1\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n})",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [
- {
- "key": "key",
- "value": "Set at folder-11",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_c1131ca7-4f49-4c25-b524-c00b0c94a9d5"
- },
- {
- "v": 6,
- "id": "cm9wmuzm66s3xmbs8lzb76mkm",
- "name": "folder-12",
- "folders": [],
- "requests": [
- {
- "v": "11",
- "name": "folder-12-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-12-request",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Overriden at folder-12-request",
- "active": true,
- "description": ""
- }
- ],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-12-request\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"key\"]).toBe(\"Overriden at folder-12-request\")\n})",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-12",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Set at folder-12",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_2bcc342f-8817-4450-8d1e-4786cfad0d83"
- },
- {
- "v": 6,
- "id": "cm9wmuzmp6s40mbs8lspc4162",
- "name": "folder-13",
- "folders": [],
- "requests": [
- {
- "v": "11",
- "name": "folder-13-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [
- {
- "key": "Custom-Header-Request-Level",
- "value": "New custom header added at the folder-13-request level",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Overriden at folder-13-request",
- "active": true,
- "description": ""
- }
- ],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level with new header addition\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-13\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"key\"]).toBe(\"Overriden at folder-13-request\")\n pw.expect(pw.response.body.headers[\"custom-header-request-level\"]).toBe(\"New custom header added at the folder-13-request level\")\n})",
- "auth": {
- "authType": "basic",
- "username": "testuser",
- "password": "testpass",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "bearer",
- "token": "test-token",
- "authActive": true
- },
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-13",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Set at folder-13",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_cbab702b-28e6-4ec9-9b13-84f7b154fc1e"
- }
- ],
- "requests": [
- {
- "v": "11",
- "name": "folder-1-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-1\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n})",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-1",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_d82c9136-95cd-4b72-b49d-f6980c153a9b"
- },
- {
- "v": 6,
- "id": "cm9wmuzk96s3ombs80h6zpd5d",
- "name": "folder-2",
- "folders": [
- {
- "v": 6,
- "id": "cm9wmuzn96s43mbs8ty5ruesu",
- "name": "folder-21",
- "folders": [],
- "requests": [
- {
- "v": "11",
- "name": "folder-21-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-2\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n})",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [
- {
- "key": "key",
- "value": "Set at folder-21",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_a1ae4845-9eab-4963-9ba3-51f8887b8fdd"
- },
- {
- "v": 6,
- "id": "cm9wmuznr6s46mbs8j6598bvx",
- "name": "folder-22",
- "folders": [],
- "requests": [
- {
- "v": "11",
- "name": "folder-22-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-22-request",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Overriden at folder-22-request",
- "active": true,
- "description": ""
- }
- ],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-22-request\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"key\"]).toBe(\"Overriden at folder-22-request\")\n})",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-22",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Set at folder-22",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_2215866f-b5d2-4a18-853a-c40ac9238729"
- },
- {
- "v": 6,
- "id": "cm9wmuzo96s49mbs8ripqlpct",
- "name": "folder-23",
- "folders": [],
- "requests": [
- {
- "v": "11",
- "name": "folder-23-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [
- {
- "key": "Custom-Header-Request-Level",
- "value": "New custom header added at the folder-23-request level",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Overriden at folder-23-request",
- "active": true,
- "description": ""
- }
- ],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level with new header addition\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-23\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"key\"]).toBe(\"Overriden at folder-23-request\")\n pw.expect(pw.response.body.headers[\"custom-header-request-level\"]).toBe(\"New custom header added at the folder-23-request level\")\n})",
- "auth": {
- "authType": "basic",
- "username": "testuser",
- "password": "testpass",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "bearer",
- "token": "test-token",
- "authActive": true
- },
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-23",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Set at folder-23",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_11b0fc1e-0ecc-45d2-a7e6-5e3600f2972f"
- }
- ],
- "requests": [
- {
- "v": "11",
- "name": "folder-2-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-2-request",
- "active": true,
- "description": ""
- }
- ],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-2-request\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n})",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-2",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_02b9a042-e935-4d0e-a30e-720b13ebf77b"
- },
- {
- "v": 6,
- "id": "cm9wmuzl26s3rmbs8mdewgock",
- "name": "folder-3",
- "folders": [
- {
- "v": 6,
- "id": "cm9wmuzor6s4cmbs833gdoh57",
- "name": "folder-31",
- "folders": [],
- "requests": [
- {
- "v": "11",
- "name": "folder-31-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-3\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n})",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": [
- {
- "key": "key",
- "value": "Set at folder-31",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_875254bc-5d26-4235-acfa-e8e93638f828"
- },
- {
- "v": 6,
- "id": "cm9wmuzp96s4fmbs8aj730ukh",
- "name": "folder-32",
- "folders": [],
- "requests": [
- {
- "v": "11",
- "name": "folder-32-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-32-request",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Overriden at folder-32-request",
- "active": true,
- "description": ""
- }
- ],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(undefined)\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-32-request\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"key\"]).toBe(\"Overriden at folder-32-request\")\n})",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-32",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Set at folder-32",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_da0095e7-8a92-4187-ac56-d62ac9ea0ba8"
- },
- {
- "v": 6,
- "id": "cm9wmuzpr6s4imbs8a2ludk99",
- "name": "folder-33",
- "folders": [],
- "requests": [
- {
- "v": "11",
- "name": "folder-33-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [
- {
- "key": "Custom-Header-Request-Level",
- "value": "New custom header added at the folder-33-request level",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Overriden at folder-33-request",
- "active": true,
- "description": ""
- }
- ],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level with new header addition\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-33\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"key\"]).toBe(\"Overriden at folder-33-request\")\n pw.expect(pw.response.body.headers[\"custom-header-request-level\"]).toBe(\"New custom header added at the folder-33-request level\")\n})",
- "auth": {
- "authType": "basic",
- "username": "testuser",
- "password": "testpass",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "bearer",
- "token": "test-token",
- "authActive": true
- },
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-33",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Set at folder-33",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_992c8305-c7dc-4ec3-a940-3f1fd1ea5d36"
- }
- ],
- "requests": [
- {
- "v": "11",
- "name": "folder-3-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [
- {
- "key": "Custom-Header-Request-Level",
- "value": "New custom header added at the folder-3-request level",
- "active": true,
- "description": ""
- },
- {
- "key": "key",
- "value": "Set at folder-3-request",
- "active": true,
- "description": ""
- }
- ],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits/overrides authorization/header set at the parent collection level with new header addition\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value overriden at folder-3\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n pw.expect(pw.response.body.headers[\"key\"]).toBe(\"Set at folder-3-request\")\n pw.expect(pw.response.body.headers[\"custom-header-request-level\"]).toBe(\"New custom header added at the folder-3-request level\")\n})",
- "auth": {
- "authType": "basic",
- "username": "testuser",
- "password": "testpass",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "basic",
- "username": "testuser",
- "password": "testpass",
- "authActive": true
- },
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value overriden at folder-3",
- "active": true,
- "description": ""
- }
- ],
- "_ref_id": "coll_m9wn4jl9_c3efcd2a-36d9-48d0-824e-ef5a8bdddab9"
- }
- ],
- "requests": [
- {
- "v": "11",
- "name": "root-collection-request",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [],
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully inherits authorization/header set at the parent collection level\", () => {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBe(\"Basic dGVzdHVzZXI6dGVzdHBhc3M=\")\n \n pw.expect(pw.response.body.headers[\"custom-header\"]).toBe(\"Custom header value set at the root collection\")\n pw.expect(pw.response.body.headers[\"inherited-header\"]).toBe(\"Inherited header at all levels\")\n})",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {}
- }
- ],
- "auth": {
- "authType": "basic",
- "username": "testuser",
- "password": "testpass",
- "authActive": true
- },
- "headers": [
- {
- "key": "Custom-Header",
- "value": "Custom header value set at the root collection",
- "active": true,
- "description": ""
- },
- {
- "key": "Inherited-Header",
- "value": "Inherited header at all levels",
- "active": true,
- "description": ""
- }
- ],
- "variables": [
- {
- "key": "collection-variable",
- "currentValue": "collection-variable-value",
- "initialValue": "collection-variable-value",
- "secret": false
- }
- ],
- "_ref_id": "coll_m9wn4jl9_aa8a3bc2-a96f-4cac-86f3-2df4bb355cc8"
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/notjson-coll.txt b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/notjson-coll.txt
deleted file mode 100644
index bd979971..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/notjson-coll.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-[
- {
- "v": 1,
- "folders": [],
- "requests":
- {
- "v": "2",
- "endpoint": "https://echo.hoppscotch.io/<>",
- "name": "fail",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "none",
- "authActive": true,
- "addTo": "Headers",
- "key": "",
- "value": ""
- },
- "preRequestScript": "pw.env.set(\"HEADERS_TYPE1\", \"devblin_local1\");",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\n// Check JSON response property\npw.test(\"Check JSON response property\", ()=> {\n pw.expect(pw.response.body.method).toBe(\"GET\");\n pw.expect(pw.response.body.headers).toBeType(\"string\");\n});",
- "body": {
- "contentType": "application/json",
- "body": "{\n\"test\": \"<>\"\n}"
- },
- "requestVariables": []
- }
- ]
- }
-]
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/oauth2-auth-code-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/oauth2-auth-code-coll.json
deleted file mode 100644
index 12c91fbd..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/oauth2-auth-code-coll.json
+++ /dev/null
@@ -1,72 +0,0 @@
-{
- "v": 3,
- "name": "OAuth2 Authorization Code Grant Type - Collection",
- "folders": [],
- "requests": [
- {
- "v": "7",
- "endpoint": "https://echo.hoppscotch.io",
- "name": "oauth2-auth-code-sample-req-pass-by-headers",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "oauth-2",
- "authActive": true,
- "addTo": "HEADERS",
- "grantTypeInfo": {
- "authEndpoint": "test-authorization-endpoint",
- "tokenEndpoint": "test-token-endpont",
- "clientID": "test-client-id",
- "clientSecret": "test-client-secret",
- "isPKCE": true,
- "codeVerifierMethod": "S256",
- "grantType": "AUTHORIZATION_CODE",
- "token": "test-token"
- }
- },
- "preRequestScript": "",
- "testScript": "pw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully derives Authorization header from the supplied fields\", ()=> {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBeType(\"string\");\n});",
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": []
- },
- {
- "v": "7",
- "endpoint": "https://echo.hoppscotch.io",
- "name": "oauth2-auth-code-sample-req-pass-by-query-params",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "oauth-2",
- "authActive": true,
- "addTo": "HEADERS",
- "grantTypeInfo": {
- "authEndpoint": "test-authorization-endpoint",
- "tokenEndpoint": "test-token-endpont",
- "clientID": "test-client-id",
- "clientSecret": "test-client-secret",
- "isPKCE": true,
- "codeVerifierMethod": "S256",
- "grantType": "AUTHORIZATION_CODE",
- "token": "test-token"
- }
- },
- "preRequestScript": "",
- "testScript": "pw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully derives Authorization header from the supplied fields\", ()=> {\n pw.expect(pw.response.body.headers[\"authorization\"]).toBeType(\"string\");\n});",
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/passes-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/passes-coll.json
deleted file mode 100644
index e958164a..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/passes-coll.json
+++ /dev/null
@@ -1,47 +0,0 @@
-[
- {
- "v": 1,
- "name": "tests",
- "folders": [],
- "requests": [
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io/<>",
- "name": "",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "preRequestScript": "pw.env.set(\"HEADERS_TYPE1\", \"devblin_local1\");",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\n// Check JSON response property\npw.test(\"Check JSON response property\", ()=> {\n pw.expect(pw.response.body.method).toBe(\"GET\");\n pw.expect(pw.response.body.headers).toBeType(\"object\");\n});",
- "body": {
- "contentType": "application/json",
- "body": "{\n\"test\": \"<>\"\n}"
- },
- "requestVariables": []
- },
- {
- "v": "3",
- "endpoint": "https://echo.hoppscotch.io/<>",
- "name": "success",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "preRequestScript": "pw.env.set(\"HEADERS_TYPE2\", \"devblin_local2\");",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\n// Check JSON response property\npw.test(\"Check JSON response property\", ()=> {\n pw.expect(pw.response.body.method).toBe(\"GET\");\n pw.expect(pw.response.body.headers).toBeType(\"object\");\n});",
- "body": {
- "contentType": "application/json",
- "body": "{\n\"test\": \"<>\"\n}"
- },
- "requestVariables": []
- }
- ]
- }
-]
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/pre-req-script-env-var-persistence-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/pre-req-script-env-var-persistence-coll.json
deleted file mode 100644
index 0d625b81..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/pre-req-script-env-var-persistence-coll.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "v": 2,
- "name": "pre-req-script-env-var-persistence-coll",
- "folders": [],
- "requests": [
- {
- "v": "3",
- "auth": { "authType": "none", "authActive": true },
- "body": { "body": null, "contentType": null },
- "name": "sample-req",
- "method": "GET",
- "params": [],
- "headers": [],
- "endpoint": "https://echo.hoppscotch.io",
- "testScript": "pw.expect(pw.env.get(\"variable\")).toBe(\"value\")",
- "preRequestScript": "pw.env.set(\"variable\", \"value\");",
- "requestVariables": []
- }
- ],
- "auth": { "authType": "inherit", "authActive": true },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/req-body-env-vars-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/req-body-env-vars-coll.json
deleted file mode 100644
index 0ddf3ef3..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/req-body-env-vars-coll.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "v": 2,
- "name": "Test environment variables in request body",
- "folders": [],
- "requests": [
- {
- "v": "3",
- "name": "test-request",
- "endpoint": "https://echo.hoppscotch.io",
- "method": "POST",
- "headers": [],
- "params": [],
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "body": {
- "contentType": "application/json",
- "body": "{\n \"firstName\": \"<>\",\n \"lastName\": \"<>\",\n \"greetText\": \"<>, <>\",\n \"fullName\": \"<>\",\n \"id\": \"<>\"\n}"
- },
- "preRequestScript": "",
- "testScript": "pw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\npw.test(\"Successfully resolves environments recursively\", ()=> {\n pw.expect(pw.env.getResolve(\"recursiveVarX\")).toBe(\"Hello\")\n pw.expect(pw.env.getResolve(\"recursiveVarY\")).toBe(\"Hello\")\n pw.expect(pw.env.getResolve(\"salutation\")).toBe(\"Hello\")\n});\n\npw.test(\"Successfully resolves environments referenced in the request body\", () => {\n const expectedId = \"7\"\n const expectedFirstName = \"John\"\n const expectedLastName = \"Doe\"\n const expectedFullName = `${expectedFirstName} ${expectedLastName}`\n const expectedGreetText = `Hello, ${expectedFullName}`\n\n pw.expect(pw.env.getResolve(\"recursiveVarX\")).toBe(\"Hello\")\n pw.expect(pw.env.getResolve(\"recursiveVarY\")).toBe(\"Hello\")\n pw.expect(pw.env.getResolve(\"salutation\")).toBe(\"Hello\")\n\n const { id, firstName, lastName, fullName, greetText } = JSON.parse(pw.response.body.data)\n\n pw.expect(id).toBe(expectedId)\n pw.expect(expectedFirstName).toBe(firstName)\n pw.expect(expectedLastName).toBe(lastName)\n pw.expect(fullName).toBe(expectedFullName)\n pw.expect(greetText).toBe(expectedGreetText)\n});",
- "requestVariables": []
- }
- ],
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/request-vars-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/request-vars-coll.json
deleted file mode 100644
index 7eff0a5a..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/request-vars-coll.json
+++ /dev/null
@@ -1,188 +0,0 @@
-{
- "v": 2,
- "name": "Request variables",
- "folders": [],
- "requests": [
- {
- "v": "6",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "body": "{\n \"<>\": \"<>\"\n}",
- "contentType": "application/json"
- },
- "name": "request-variables-basic-usage",
- "method": "POST",
- "params": [
- {
- "key": "<>",
- "value": "<>",
- "active": true
- },
- {
- "key": "inactive-query-param-key",
- "value": "<>",
- "active": true
- }
- ],
- "headers": [
- {
- "key": "<>",
- "value": "<>",
- "active": true
- },
- {
- "key": "inactive-header-key",
- "value": "<>",
- "active": true
- }
- ],
- "endpoint": "<>",
- "testScript": "pw.test(\"Accounts for active request variables\", ()=> {\n pw.expect(pw.response.body.args[\"query-param-key\"]).toBe(\"query-param-value\");\n\n const data = JSON.parse(pw.response.body.data)\n\n pw.expect(data[\"http-body-raw-key\"]).toBe(\"http-body-raw-value\")\n\n pw.expect(pw.response.body.headers[\"custom-header-key\"]).toBe(\"custom-header-value\");\n});\n\npw.test(\"Ignores inactive request variables\", () => {\n pw.expect(pw.response.body.args[\"inactive-query-param-key\"]).toBe(\"\")\n pw.expect(pw.response.body.args[\"inactive-header-key\"]).toBe(undefined)\n})",
- "preRequestScript": "",
- "requestVariables": [
- {
- "key": "url",
- "value": "https://echo.hoppscotch.io",
- "active": true
- },
- {
- "key": "method",
- "value": "POST",
- "active": true
- },
- {
- "key": "httpBodyRawKey",
- "value": "http-body-raw-key",
- "active": true
- },
- {
- "key": "httpBodyRawValue",
- "value": "http-body-raw-value",
- "active": true
- },
- {
- "key": "customHeaderKey",
- "value": "custom-header-key",
- "active": true
- },
- {
- "key": "customHeaderValue",
- "value": "custom-header-value",
- "active": true
- },
- {
- "key": "queryParamKey",
- "value": "query-param-key",
- "active": true
- },
- {
- "key": "queryParamValue",
- "value": "query-param-value",
- "active": true
- },
- {
- "key": "inactiveQueryParamValue",
- "value": "inactive-query-param-value",
- "active": false
- },
- {
- "key": "inactiveHeaderValue",
- "value": "inactive-header-value",
- "active": false
- }
- ]
- },
- {
- "v": "6",
- "auth": {
- "authType": "none",
- "password": "<>",
- "username": "<>",
- "authActive": true
- },
- "body": {
- "body": "{\n \"username\": \"<>\",\n \"password\": \"<>\"\n}",
- "contentType": "application/json"
- },
- "name": "request-variables-alongside-environment-variables",
- "method": "POST",
- "params": [
- {
- "key": "method",
- "value": "<>",
- "active": true
- }
- ],
- "headers": [
- {
- "key": "test-header-key",
- "value": "<>",
- "active": true
- }
- ],
- "endpoint": "<>/<>",
- "testScript": "pw.test(\"The first occurrence is picked for multiple request variable occurrences with the same key.\", () => {\n pw.expect(pw.response.body.args.method).toBe(\"post\");\n});\n\npw.test(\"Request variables support recursive resolution and pick values from secret environment variables\", () => {\n const { username, password } = JSON.parse(pw.response.body.data)\n\n pw.expect(username).toBe(\"username\")\n pw.expect(password).toBe(\"password\")\n\n})\n\npw.test(\"Resolves request variables that are clubbed together\", () => {\n pw.expect(pw.response.body.path).toBe(\"/username/password\")\n})\n\npw.test(\"Request variables are prioritised over environment variables\", () => {\n pw.expect(pw.response.body.headers.host).toBe(\"echo.hoppscotch.io\")\n})\n\npw.test(\"Environment variable is picked if the request variable under the same name is empty\", () => {\n pw.expect(pw.response.body.headers[\"test-header-key\"]).toBe(\"test-header-value\")\n})",
- "preRequestScript": "",
- "requestVariables": [
- {
- "key": "url",
- "value": "https://echo.hoppscotch.io",
- "active": true
- },
- {
- "key": "username",
- "value": "<>",
- "active": true
- },
- {
- "key": "recursiveBasicAuthUsernameReqVar",
- "value": "<>",
- "active": true
- },
- {
- "key": "password",
- "value": "<>",
- "active": true
- },
- {
- "key": "recursiveBasicAuthPasswordReqVar",
- "value": "<>",
- "active": true
- },
- {
- "key": "method",
- "value": "post",
- "active": true
- },
- {
- "key": "method",
- "value": "get",
- "active": true
- },
- {
- "key": "method",
- "value": "put",
- "active": true
- },
- {
- "key": "path",
- "value": "<>/<>",
- "active": true
- },
- {
- "key": "testHeaderValue",
- "value": "",
- "active": true
- }
- ]
- }
- ],
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "headers": []
-}
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/sample-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/sample-coll.json
deleted file mode 100644
index b0ca8cec..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/sample-coll.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "v": 1,
- "name": "tests",
- "folders": [],
- "requests": [
- {
- "v": "2",
- "endpoint": "<>",
- "name": "",
- "params": [],
- "headers": [],
- "method": "GET",
- "auth": {
- "authType": "none",
- "authActive": true
- },
- "preRequestScript": "",
- "testScript": "// Check status code is 200\npw.test(\"Status code is 200\", ()=> {\n pw.expect(pw.response.status).toBe(200);\n});\n\n// Check JSON response property\npw.test(\"Check JSON response property\", ()=> {\n pw.expect(pw.response.body.method).toBe(\"GET\");\n pw.expect(pw.response.body.headers).toBeType(\"object\");\n});",
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": []
- }
- ]
-}
\ No newline at end of file
diff --git a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/scripting-revamp-coll.json b/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/scripting-revamp-coll.json
deleted file mode 100644
index f236cd7a..00000000
--- a/packages/hoppscotch-cli/src/__tests__/e2e/fixtures/collections/scripting-revamp-coll.json
+++ /dev/null
@@ -1,1686 +0,0 @@
-{
- "v": 11,
- "name": "scripting-revamp-coll",
- "folders": [],
- "requests": [
- {
- "v": "17",
- "id": "cmfhzf0oo0092qt0if5rvd2g4",
- "name": "json-response-test",
- "method": "POST",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [
- {
- "key": "Test-Header",
- "value": "test",
- "active": true,
- "description": "test header"
- }
- ],
- "preRequestScript": "",
- "testScript": "export {};\nhopp.test(\"`hopp.response.body.asJSON()` parses response body as JSON\", () => {\n const parsedData = JSON.parse(hopp.response.body.asJSON().data)\n\n hopp.expect(parsedData.name).toBe('John Doe')\n hopp.expect(parsedData.age).toBeType(\"number\")\n})\n\npm.test(\"`pm.response.json()` parses response body as JSON\", () => {\n const parsedData = JSON.parse(pm.response.json().data)\n\n pm.expect(parsedData.name).toBe('John Doe')\n pm.expect(parsedData.age).toBeType(\"number\")\n})\n\nhopp.test(\"`hopp.response.body.asText()` parses response body as plain text\", () => {\n const textResponse = hopp.response.body.asText()\n hopp.expect(textResponse).toInclude('\\\"test-header\\\":\\\"test\\\"')\n})\n\npm.test(\"`pm.response.text()` parses response body as plain text\", () => {\n const textResponse = pm.response.text()\n pm.expect(textResponse).toInclude('\\\"test-header\\\":\\\"test\\\"')\n})\n\nhopp.test(\"hopp.response.bytes()` parses response body as raw bytes\", () => {\n const rawResponse = hopp.response.body.bytes()\n\n hopp.expect(rawResponse[0]).toBe(123)\n})\n\npm.test(\"pm.response.stream` parses response body as raw bytes\", () => {\n const rawResponse = pm.response.stream\n\n pm.expect(rawResponse[0]).toBe(123)\n})\n",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": "application/json",
- "body": "{\n \"name\": \"John Doe\",\n \"age\": 35\n}"
- },
- "requestVariables": [],
- "responses": {},
- "description": null
- },
- {
- "v": "17",
- "id": "cmfhzf0op0093qt0ictgoxymy",
- "name": "html-response-test",
- "method": "GET",
- "endpoint": "https://hoppscotch.io",
- "params": [],
- "headers": [
- {
- "key": "Test-Header",
- "value": "test",
- "active": true,
- "description": "Test header"
- }
- ],
- "preRequestScript": "",
- "testScript": "hopp.test(\"`hopp.response.asText()` parses response body as plain text\", () => {\n const textResponse = hopp.response.body.asText()\n hopp.expect(textResponse).toInclude(\"Open source API development ecosystem\")\n})\n\npm.test(\"`pm.response.text()` parses response body as plain text\", () => {\n const textResponse = pm.response.text()\n pm.expect(textResponse).toInclude(\"Open source API development ecosystem\")\n})\n\nhopp.test(\"`hopp.response.body.bytes()` parses response body as raw bytes\", () => {\n const rawResponse = hopp.response.body.bytes()\n\n hopp.expect(rawResponse[0]).toBe(60)\n})\n\npm.test(\"`pm.response.stream` parses response body as raw bytes\", () => {\n const rawResponse = pm.response.stream\n\n pm.expect(rawResponse[0]).toBe(60)\n})\n\n\n",
- "auth": {
- "authType": "inherit",
- "authActive": true
- },
- "body": {
- "contentType": null,
- "body": null
- },
- "requestVariables": [],
- "responses": {},
- "description": null
- },
- {
- "v": "17",
- "id": "cmfhzf0op0094qt0ixbo9rqnw",
- "name": "environment-variables-test",
- "method": "GET",
- "endpoint": "https://echo.hoppscotch.io",
- "params": [],
- "headers": [],
- "preRequestScript": "export {};\nhopp.env.set('test_key', 'test_value')\nhopp.env.set('recursive_key', '<>')\nhopp.env.global.set('global_key', 'global_value')\nhopp.env.active.set('active_key', 'active_value')\n\n// `pm` namespace equivalents\npm.variables.set('pm_test_key', 'pm_test_value')\npm.environment.set('pm_active_key', 'pm_active_value')\npm.globals.set('pm_global_key', 'pm_global_value')\n",
- "testScript": "\nhopp.test('`hopp.env.get()` retrieves environment variables', () => {\n const value = hopp.env.get('test_key')\n hopp.expect(value).toBe('test_value')\n})\n\npm.test('`pm.variables.get()` retrieves environment variables', () => {\n const value = pm.variables.get('test_key')\n pm.expect(value).toBe('test_value')\n})\n\nhopp.test('`hopp.env.getRaw()` retrieves raw environment variables without resolution', () => {\n const rawValue = hopp.env.getRaw('recursive_key')\n hopp.expect(rawValue).toBe('<